INSTINCT Code Coverage Report


Directory: src/
File: internal/Node/Node.hpp
Date: 2025-11-25 23:34:18
Exec Total Coverage
Lines: 34 43 79.1%
Functions: 56 82 68.3%
Branches: 15 42 35.7%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 /// @file Node.hpp
10 /// @brief Node Class
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2020-12-14
13
14 #pragma once
15
16 // <boost/asio.hpp> needs to be included before <winsock.h> (even though not used in this file)
17 // https://stackoverflow.com/questions/9750344/boostasio-winsock-and-winsock-2-compatibility-issue
18 #ifdef _WIN32
19 // Set the proper SDK version before including boost/Asio
20 #include <SDKDDKVer.h>
21 // Note boost/ASIO includes Windows.h.
22 #include <boost/asio.hpp>
23 #endif //_WIN32
24
25 #include <imgui.h>
26 #include <imgui_node_editor.h>
27 #include <imgui_stdlib.h>
28
29 #include "internal/Node/Pin.hpp"
30 #include "Navigation/Time/InsTime.hpp"
31
32 #include <string>
33 #include <vector>
34 #include <thread>
35 #include <mutex>
36 #include <condition_variable>
37 #include <atomic>
38 #include <chrono>
39 #include <map>
40
41 #include <nlohmann/json.hpp>
42 using json = nlohmann::json; ///< json namespace
43
44 namespace NAV
45 {
46 class Node;
47 class NodeData;
48 class GroupBox;
49
50 namespace NodeRegistry
51 {
52
53 void RegisterNodeTypes(); // NOLINT(readability-redundant-declaration) - false warning. This is needed for the friend declaration below
54
55 } // namespace NodeRegistry
56
57 namespace FlowExecutor
58 {
59
60 /// @brief Main task of the FlowExecutor thread
61 void execute(); // NOLINT(readability-redundant-declaration) - false warning. This is needed for the friend declaration below
62
63 /// @brief Deinitialize all Nodes
64 void deinitialize(); // NOLINT(readability-redundant-declaration) - false warning. This is needed for the friend declaration below
65
66 } // namespace FlowExecutor
67
68 namespace gui
69 {
70 class NodeEditorApplication;
71
72 namespace menus
73 {
74
75 void ShowRunMenu();
76
77 } // namespace menus
78
79 } // namespace gui
80
81 /// @brief Converts the provided node into a json object
82 /// @param[out] j Json object which gets filled with the info
83 /// @param[in] node Node to convert into json
84 void to_json(json& j, const Node& node);
85 /// @brief Converts the provided json object into a node object
86 /// @param[in] j Json object with the needed values
87 /// @param[out] node Object to fill from the json
88 void from_json(const json& j, Node& node);
89
90 /// @brief Abstract parent class for all nodes
91 class Node
92 {
93 public:
94 /// Kind information class
95 struct Kind
96 {
97 /// Possible kinds of Nodes
98 enum Value : uint8_t
99 {
100 Blueprint, ///< Node with header
101 Simple, ///< Node without header, which displays its name in the center of the content
102 GroupBox, ///< Group box which can group other nodes and drag them together
103 };
104
105 /// @brief Default Constructor
106 Kind() = default;
107
108 /// @brief Implicit Constructor from Value type
109 /// @param[in] kind Value type to construct from
110 6969 constexpr Kind(Value kind) // NOLINT(hicpp-explicit-conversions, google-explicit-constructor)
111 6969 : value(kind)
112 6969 {}
113
114 /// @brief Constructor from std::string
115 /// @param[in] string String representation of the type
116 714 explicit Kind(const std::string& string)
117 714 {
118
2/2
✓ Branch 1 taken 606 times.
✓ Branch 2 taken 108 times.
714 if (string == "Blueprint")
119 {
120 606 value = Kind::Blueprint;
121 }
122
2/2
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 8 times.
108 else if (string == "Simple")
123 {
124 100 value = Kind::Simple;
125 }
126
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 else if (string == "GroupBox")
127 {
128 8 value = Kind::GroupBox;
129 }
130 714 }
131
132 /// @brief Allow switch(Node::Value(kind)) and comparisons
133 explicit operator Value() const { return value; }
134 /// @brief Prevent usage: if(node)
135 explicit operator bool() = delete;
136 /// @brief Assignment operator from Value type
137 /// @param[in] v Value type to construct from
138 /// @return The Kind type from the value type
139 397 Kind& operator=(Value v)
140 {
141 397 value = v;
142 397 return *this;
143 }
144
145 friend constexpr bool operator==(const Node::Kind& lhs, const Node::Kind& rhs);
146 friend constexpr bool operator!=(const Node::Kind& lhs, const Node::Kind& rhs);
147
148 friend constexpr bool operator==(const Node::Kind& lhs, const Node::Kind::Value& rhs);
149 friend constexpr bool operator==(const Node::Kind::Value& lhs, const Node::Kind& rhs);
150 friend constexpr bool operator!=(const Node::Kind& lhs, const Node::Kind::Value& rhs);
151 friend constexpr bool operator!=(const Node::Kind::Value& lhs, const Node::Kind& rhs);
152
153 /// @brief std::string conversion operator
154 /// @return A std::string representation of the node kind
155 explicit operator std::string() const
156 {
157 switch (value)
158 {
159 case Kind::Blueprint:
160 return "Blueprint";
161 case Kind::Simple:
162 return "Simple";
163 case Kind::GroupBox:
164 return "GroupBox";
165 }
166 return "";
167 }
168
169 private:
170 /// @brief Value of the node kind
171 Value value;
172 };
173
174 /// @brief Possible states of the node
175 enum class State : uint8_t
176 {
177 Disabled, ///< Node is disabled and won't be initialized
178 Deinitialized, ///< Node is deinitialized (red)
179 DoInitialize, ///< Node should be initialized
180 Initializing, ///< Node is currently initializing
181 Initialized, ///< Node is initialized (green)
182 DoDeinitialize, ///< Node should be deinitialized
183 Deinitializing, ///< Node is currently deinitializing
184 DoShutdown, ///< Node should shut down
185 Shutdown, ///< Node is shutting down
186 };
187
188 /// @brief Different Modes the Node can work in
189 enum class Mode : uint8_t
190 {
191 REAL_TIME, ///< Node running in real-time mode
192 POST_PROCESSING, ///< Node running in post-processing mode
193 };
194
195 /// @brief Constructor
196 /// @param[in] name Name of the node
197 explicit Node(std::string name);
198 /// @brief Destructor
199 virtual ~Node();
200 /// @brief Copy constructor
201 Node(const Node&) = delete;
202 /// @brief Move constructor
203 Node(Node&&) = delete;
204 /// @brief Copy assignment operator
205 Node& operator=(const Node&) = delete;
206 /// @brief Move assignment operator
207 Node& operator=(Node&&) = delete;
208
209 /* -------------------------------------------------------------------------------------------------------- */
210 /* Interface */
211 /* -------------------------------------------------------------------------------------------------------- */
212
213 /// @brief String representation of the Class Type
214 [[nodiscard]] virtual std::string type() const = 0;
215
216 /// @brief ImGui config window which is shown on double click
217 /// @attention Don't forget to set hasConfig to true
218 virtual void guiConfig();
219
220 /// @brief Saves the node into a json object
221 [[nodiscard]] virtual json save() const;
222
223 /// @brief Restores the node from a json object
224 /// @param[in] j Json object with the node state
225 virtual void restore(const json& j);
226
227 /// @brief Restores link related properties of the node from a json object
228 /// @param[in] j Json object with the node state
229 virtual void restoreAtferLink(const json& j);
230
231 /// @brief Initialize the Node
232 ///
233 /// Here a node can do things like
234 /// - connecting to a sensor
235 /// - read a static data file which needs to be read completely (e.g. RINEX nav files)
236 /// - reset variables in case the NAV::Node::resetNode() is not used
237 /// @attention This function is called in the default implementation of the NAV::Node::resetNode() function.
238 /// If the initialize function should not be called more than once, make sure to override the NAV::Node::resetNode() function.
239 virtual bool initialize();
240
241 /// @brief Deinitialize the Node
242 virtual void deinitialize();
243
244 /// @brief Resets the node. It is guaranteed that the node is initialized when this is called.
245 virtual bool resetNode();
246
247 /// @brief Called when a new link is to be established
248 /// @param[in] startPin Pin where the link starts
249 /// @param[in] endPin Pin where the link ends
250 /// @return True if link is allowed, false if link is rejected
251 virtual bool onCreateLink(OutputPin& startPin, InputPin& endPin);
252
253 /// @brief Called when a link is to be deleted
254 /// @param[in] startPin Pin where the link starts
255 /// @param[in] endPin Pin where the link ends
256 virtual void onDeleteLink(OutputPin& startPin, InputPin& endPin);
257
258 /// @brief Called when a new link was established
259 /// @param[in] startPin Pin where the link starts
260 /// @param[in] endPin Pin where the link ends
261 virtual void afterCreateLink(OutputPin& startPin, InputPin& endPin);
262
263 /// @brief Called when a link was deleted
264 /// @param[in] startPin Pin where the link starts
265 /// @param[in] endPin Pin where the link ends
266 virtual void afterDeleteLink(OutputPin& startPin, InputPin& endPin);
267
268 /// @brief Function called by the flow executer after finishing to flush out remaining data
269 virtual void flush();
270
271 /* -------------------------------------------------------------------------------------------------------- */
272 /* Member functions */
273 /* -------------------------------------------------------------------------------------------------------- */
274
275 /// @brief Notifies connected nodes about the change
276 /// @param[in] pinIdx Output Port index where to set the value
277 /// @param[in] insTime Time the value was generated
278 /// @param[in] guard Lock guard of the output data
279 void notifyOutputValueChanged(size_t pinIdx, const InsTime& insTime, const std::scoped_lock<std::mutex>&& guard);
280
281 /// @brief Blocks the thread till the output values was read by all connected nodes
282 /// @param[in] pinIdx Output Pin index where to request the lock
283 [[nodiscard]] std::scoped_lock<std::mutex> requestOutputValueLock(size_t pinIdx);
284
285 /// @brief Get Input Value connected on the pin. Only const data types.
286 /// @tparam T Type of the connected object
287 /// @param[in] portIndex Input port where to retrieve the data from
288 /// @return Pointer to the object
289 template<typename T>
290 3041 [[nodiscard]] std::optional<InputPin::IncomingLink::ValueWrapper<T>> getInputValue(size_t portIndex) const
291 {
292 3041 return inputPins.at(portIndex).link.getValue<T>();
293 }
294
295 /// @brief Unblocks the connected node. Has to be called when the input value should be released and getInputValue was not called.
296 /// @param[in] portIndex Input port where the data should be released
297 void releaseInputValue(size_t portIndex);
298
299 /// @brief Checks wether there is an input pin with the same time
300 /// @param[in] insTime Time to check
301 bool hasInputPinWithSameTime(const InsTime& insTime) const;
302
303 /// @brief Calls all registered callbacks on the specified output port
304 /// @param[in] portIndex Output port where to call the callbacks
305 /// @param[in] data The data to pass to the callback targets
306 void invokeCallbacks(size_t portIndex, const std::shared_ptr<const NodeData>& data);
307
308 /// @brief Returns the pin with the given id
309 /// @param[in] pinId Id of the Pin
310 /// @return The input pin
311 [[nodiscard]] InputPin& inputPinFromId(ax::NodeEditor::PinId pinId);
312
313 /// @brief Returns the pin with the given id
314 /// @param[in] pinId Id of the Pin
315 /// @return The output pin
316 [[nodiscard]] OutputPin& outputPinFromId(ax::NodeEditor::PinId pinId);
317
318 /// @brief Returns the index of the pin
319 /// @param[in] pinId Id of the Pin
320 /// @return The index of the pin
321 [[nodiscard]] size_t inputPinIndexFromId(ax::NodeEditor::PinId pinId) const;
322
323 /// @brief Returns the index of the pin
324 /// @param[in] pinId Id of the Pin
325 /// @return The index of the pin
326 [[nodiscard]] size_t outputPinIndexFromId(ax::NodeEditor::PinId pinId) const;
327
328 /// @brief Create an Input Pin object
329 /// @param[in] name Display name of the Pin
330 /// @param[in] pinType Type of the pin
331 /// @param[in] dataIdentifier Identifier of the data which is represented by the pin
332 /// @param[in] callback Callback to register with the pin
333 /// @param[in] firable Function to check whether the callback is firable
334 /// @param[in] priority Priority when checking firable condition related to other pins (higher priority gets triggered first)
335 /// @param[in] idx Index where to put the new pin (-1 means at the end)
336 /// @return Pointer to the created pin
337 InputPin* CreateInputPin(const char* name, Pin::Type pinType, const std::vector<std::string>& dataIdentifier = {},
338 InputPin::Callback callback = static_cast<InputPin::FlowFirableCallbackFunc>(nullptr),
339 InputPin::FlowFirableCheckFunc firable = nullptr,
340 int priority = 0, int idx = -1);
341
342 /// @brief Create an Input Pin object
343 /// @tparam T Node Class where the function is member of
344 /// @param[in] name Display name of the Pin
345 /// @param[in] pinType Type of the pin
346 /// @param[in] dataIdentifier Identifier of the data which is represented by the pin
347 /// @param[in] callback Flow firable callback function to register with the pin
348 /// @param[in] firable Function to check whether the callback is firable
349 /// @param[in] priority Priority when checking firable condition related to other pins (higher priority gets triggered first)
350 /// @param[in] idx Index where to put the new pin (-1 means at the end)
351 /// @return Pointer to the created pin
352 template<std::derived_from<Node> T>
353 4835 InputPin* CreateInputPin(const char* name, Pin::Type pinType, const std::vector<std::string>& dataIdentifier = {},
354 void (T::*callback)(InputPin::NodeDataQueue&, size_t) = nullptr,
355 InputPin::FlowFirableCheckFunc firable = nullptr,
356 int priority = 0, int idx = -1)
357 {
358
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4835 times.
4835 assert(pinType == Pin::Type::Flow);
359
360
1/2
✓ Branch 2 taken 4835 times.
✗ Branch 3 not taken.
4835 return CreateInputPin(name, pinType, dataIdentifier, InputPin::Callback(static_cast<InputPin::FlowFirableCallbackFunc>(callback)), firable, priority, idx);
361 }
362
363 /// @brief Create an Input Pin object for data pins. The additional notify function gets called when the connected data was changed and the connected node calls NAV::Node::notifyOutputValueChanged
364 /// @tparam T Node Class where the function is member of
365 /// @param[in] name Display name of the Pin
366 /// @param[in] pinType Type of the pin
367 /// @param[in] dataIdentifier Identifier of the data which is represented by the pin
368 /// @param[in] notifyFunc Function to call when the data is updated
369 /// @param[in] idx Index where to put the new pin (-1 means at the end)
370 /// @return Pointer to the created pin
371 template<std::derived_from<Node> T>
372 131 InputPin* CreateInputPin(const char* name, Pin::Type pinType, const std::vector<std::string>& dataIdentifier,
373 void (T::*notifyFunc)(const InsTime&, size_t), int idx = -1)
374 {
375
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 131 times.
131 assert(pinType != Pin::Type::Flow);
376
377
1/2
✓ Branch 2 taken 131 times.
✗ Branch 3 not taken.
131 return CreateInputPin(name, pinType, dataIdentifier, InputPin::Callback(static_cast<InputPin::DataChangedNotifyFunc>(notifyFunc)), nullptr, 0, idx);
378 }
379
380 /// @brief Create an Output Pin object
381 /// @param[in] name Display name of the Pin
382 /// @param[in] pinType Type of the pin
383 /// @param[in] dataIdentifier Identifier of the data which is represented by the pin
384 /// @param[in] data Pointer to data which is represented by the pin
385 /// @param[in] idx Index where to put the new pin (-1 means at the end)
386 /// @return Pointer to the created pin
387 OutputPin* CreateOutputPin(const char* name, Pin::Type pinType, const std::vector<std::string>& dataIdentifier, OutputPin::PinData data = static_cast<void*>(nullptr), int idx = -1);
388
389 /// @brief Create an Output Pin object for Flow Pins
390 /// @tparam T Class where the function is member of
391 /// @param[in] name Display name of the Pin
392 /// @param[in] pinType Type of the pin
393 /// @param[in] dataIdentifier Identifier of the data which is represented by the pin
394 /// @param[in] peekPollDataFunc Function to poll for data on this pin
395 /// @param[in] idx Index where to put the new pin (-1 means at the end)
396 /// @return Pointer to the created pin
397 template<std::derived_from<Node> T>
398 822 OutputPin* CreateOutputPin(const char* name, Pin::Type pinType, const std::vector<std::string>& dataIdentifier,
399 std::shared_ptr<const NAV::NodeData> (T::*peekPollDataFunc)(size_t, bool) = nullptr, int idx = -1)
400 {
401
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 822 times.
822 assert(pinType == Pin::Type::Flow);
402
1/2
✓ Branch 3 taken 822 times.
✗ Branch 4 not taken.
2103 INS_ASSERT_USER_ERROR(std::none_of(outputPins.begin(), outputPins.end(),
403 [](const OutputPin& outputPin) { return std::holds_alternative<OutputPin::PollDataFunc>(outputPin.data); }),
404 "You cannot mix PollDataFunc and PeekPollDataFunc output pins. Use only PeekPollDataFunc pins if multiple pins are needed.");
405
406
1/2
✓ Branch 2 taken 822 times.
✗ Branch 3 not taken.
822 return CreateOutputPin(name, pinType, dataIdentifier, OutputPin::PinData(static_cast<OutputPin::PeekPollDataFunc>(peekPollDataFunc)), idx);
407 }
408
409 /// @brief Create an Output Pin object for Flow Pins
410 /// @tparam T Class where the function is member of
411 /// @param[in] name Display name of the Pin
412 /// @param[in] pinType Type of the pin
413 /// @param[in] dataIdentifier Identifier of the data which is represented by the pin
414 /// @param[in] pollDataFunc Function to poll for data on this pin
415 /// @param[in] idx Index where to put the new pin (-1 means at the end)
416 /// @return Pointer to the created pin
417 template<std::derived_from<Node> T>
418 1370 OutputPin* CreateOutputPin(const char* name, Pin::Type pinType, const std::vector<std::string>& dataIdentifier,
419 std::shared_ptr<const NAV::NodeData> (T::*pollDataFunc)() = nullptr, int idx = -1)
420 {
421
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1370 times.
1370 assert(pinType == Pin::Type::Flow);
422
1/6
✓ Branch 3 taken 1370 times.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1370 INS_ASSERT_USER_ERROR(std::none_of(outputPins.begin(), outputPins.end(),
423 [](const OutputPin& outputPin) { return std::holds_alternative<OutputPin::PeekPollDataFunc>(outputPin.data)
424 || std::holds_alternative<OutputPin::PollDataFunc>(outputPin.data); }),
425 "There can only be one poll pin if the poll only data function is chosen. If multiple are needed, create PeekPollDataFunc pins.");
426
427
1/2
✓ Branch 2 taken 1370 times.
✗ Branch 3 not taken.
1370 return CreateOutputPin(name, pinType, dataIdentifier, OutputPin::PinData(static_cast<OutputPin::PollDataFunc>(pollDataFunc)), idx);
428 }
429
430 /// @brief Deletes the output pin. Invalidates the pin reference given.
431 /// @param[in] pinIndex Index of the pin to delete
432 /// @return True if the pin was delete
433 bool DeleteOutputPin(size_t pinIndex);
434
435 /// @brief Deletes the input pin. Invalidates the pin reference given.
436 /// @param[in] pinIndex Index of the pin to delete
437 /// @return True if the pin was delete
438 bool DeleteInputPin(size_t pinIndex);
439
440 /// @brief Node name and id
441 [[nodiscard]] std::string nameId() const;
442
443 /// @brief Get the size of the node
444 [[nodiscard]] const ImVec2& getSize() const;
445
446 // ------------------------------------------ State handling ---------------------------------------------
447
448 /// @brief Converts the state into a printable text
449 /// @param[in] state State to convert
450 /// @return String representation of the state
451 static std::string toString(State state);
452
453 /// @brief Get the current state of the node
454 [[nodiscard]] State getState() const;
455
456 /// @brief Get the current mode of the node
457 [[nodiscard]] Mode getMode() const;
458
459 /// @brief Asks the node worker to initialize the node
460 /// @param[in] wait Wait for the worker to complete the request
461 /// @return True if not waiting and the worker accepted the request otherwise if waiting only true if the node initialized correctly
462 bool doInitialize(bool wait = false);
463
464 /// @brief Asks the node worker to reinitialize the node
465 /// @param[in] wait Wait for the worker to complete the request
466 /// @return True if not waiting and the worker accepted the request otherwise if waiting only true if the node initialized correctly
467 bool doReinitialize(bool wait = false);
468
469 /// @brief Asks the node worker to deinitialize the node
470 /// @param[in] wait Wait for the worker to complete the request
471 /// @return True if the worker accepted the request
472 bool doDeinitialize(bool wait = false);
473
474 /// @brief Asks the node worker to disable the node
475 /// @param[in] wait Wait for the worker to complete the request
476 /// @return True if the worker accepted the request
477 bool doDisable(bool wait = false);
478
479 /// @brief Enable the node
480 /// @return True if enabling was successful
481 bool doEnable();
482
483 /// Wakes the worker thread
484 void wakeWorker();
485
486 /// @brief Checks if the node is disabled
487 [[nodiscard]] bool isDisabled() const;
488
489 /// @brief Checks if the node is initialized
490 [[nodiscard]] bool isInitialized() const;
491
492 /// @brief Checks if the node is changing its state currently
493 [[nodiscard]] bool isTransient() const;
494
495 /// @brief Checks if the node is only working in real time (sensors, network interfaces, ...)
496 [[nodiscard]] bool isOnlyRealtime() const;
497
498 /* -------------------------------------------------------------------------------------------------------- */
499 /* Member variables */
500 /* -------------------------------------------------------------------------------------------------------- */
501
502 /// Unique Id of the Node
503 ax::NodeEditor::NodeId id = 0;
504 /// Kind of the Node
505 Kind kind = Kind::Blueprint;
506 /// Name of the Node
507 std::string name;
508 /// List of input pins
509 std::vector<InputPin> inputPins;
510 /// List of output pins
511 std::vector<OutputPin> outputPins;
512
513 /// Enables the callbacks
514 bool callbacksEnabled = false;
515
516 /// Map with callback events (sorted by time)
517 std::multimap<InsTime, std::pair<OutputPin*, size_t>> pollEvents;
518
519 protected:
520 /// The Default Window size for new config windows.
521 /// Only set the variable if the object/window has no persistently saved data (no entry in .ini file)
522 ImVec2 _guiConfigDefaultWindowSize{ 500.0F, 400.0F };
523
524 /// Flag if the config window should be shown
525 bool _hasConfig = false;
526
527 /// Lock the config when executing post-processing
528 bool _lockConfigDuringRun = true;
529
530 /// Whether the node can run in post-processing or only real-time
531 bool _onlyRealTime = false;
532
533 private:
534 State _state = State::Deinitialized; ///< Current state of the node
535 mutable std::mutex _stateMutex; ///< Mutex to interact with the worker state variable
536
537 /// Mode the node is currently running in
538 std::atomic<Mode> _mode = Mode::REAL_TIME;
539
540 /// Flag if the node should be reinitialize after deinitializing
541 bool _reinitialize = false;
542
543 /// Flag if the node should be disabled after deinitializing
544 bool _disable = false;
545
546 /// Flag if the config window is shown
547 bool _showConfig = false;
548
549 /// Mutex to show the config window (prevents initialization to modify values within the config window)
550 std::mutex _configWindowMutex;
551 /// Flag if the config window should be forced collapsed
552 bool _configWindowForceCollapse = false;
553 /// Flag if the config window is collapsed
554 bool _configWindowIsCollapsed = false;
555
556 /// Flag if the config window should be focused
557 bool _configWindowFocus = false;
558
559 /// Size of the node in pixels
560 ImVec2 _size{ 0, 0 };
561
562 /// Flag which prevents the worker to be autostarted if false
563 static inline bool _autostartWorker = true;
564
565 6969 std::chrono::duration<int64_t> _workerTimeout = std::chrono::minutes(1); ///< Periodic timeout of the worker to check if new data available
566 std::thread _worker; ///< Worker handling initialization and processing of data
567 std::mutex _workerMutex; ///< Mutex to interact with the worker condition variable
568 std::condition_variable _workerConditionVariable; ///< Condition variable to signal the worker thread to do something
569 bool _workerWakeup = false; ///< Variable to prevent the worker from sleeping
570
571 /// @brief Worker thread
572 /// @param[in, out] node The node where the thread belongs to
573 static void workerThread(Node* node);
574
575 /// Handler which gets triggered if the worker runs into a periodic timeout
576 virtual void workerTimeoutHandler();
577
578 /// @brief Called by the worker to initialize the node
579 /// @return True if the initialization was successful
580 bool workerInitializeNode();
581
582 /// @brief Called by the worker to deinitialize the node
583 /// @return True if the deinitialization was successful
584 bool workerDeinitializeNode();
585
586 friend class gui::NodeEditorApplication;
587 friend class NAV::GroupBox;
588
589 /// @brief Main task of the FlowExecutor thread
590 friend void NAV::FlowExecutor::execute();
591 /// @brief Deinitialize all Nodes
592 friend void NAV::FlowExecutor::deinitialize();
593 /// @brief Register all available Node types for the program
594 friend void NAV::NodeRegistry::RegisterNodeTypes();
595
596 /// @brief Converts the provided node into a json object
597 /// @param[out] j Json object which gets filled with the info
598 /// @param[in] node Node to convert into json
599 friend void NAV::to_json(json& j, const Node& node);
600 /// @brief Converts the provided json object into a node object
601 /// @param[in] j Json object with the needed values
602 /// @param[out] node Object to fill from the json
603 friend void NAV::from_json(const json& j, Node& node);
604
605 /// @brief Show the run menu dropdown
606 friend void gui::menus::ShowRunMenu();
607 };
608
609 /// @brief Equal compares Node::Kind values
610 /// @param[in] lhs Left-hand side of the operator
611 /// @param[in] rhs Right-hand side of the operator
612 /// @return Whether the comparison was successful
613 constexpr bool operator==(const Node::Kind& lhs, const Node::Kind& rhs) { return lhs.value == rhs.value; }
614 /// @brief Inequal compares Node::Kind values
615 /// @param[in] lhs Left-hand side of the operator
616 /// @param[in] rhs Right-hand side of the operator
617 /// @return Whether the comparison was successful
618 constexpr bool operator!=(const Node::Kind& lhs, const Node::Kind& rhs) { return !(lhs == rhs); }
619
620 /// @brief Equal compares Node::Kind values
621 /// @param[in] lhs Left-hand side of the operator
622 /// @param[in] rhs Right-hand side of the operator
623 /// @return Whether the comparison was successful
624 3599 constexpr bool operator==(const Node::Kind& lhs, const Node::Kind::Value& rhs) { return lhs.value == rhs; }
625 /// @brief Equal compares Node::Kind values
626 /// @param[in] lhs Left-hand side of the operator
627 /// @param[in] rhs Right-hand side of the operator
628 /// @return Whether the comparison was successful
629 constexpr bool operator==(const Node::Kind::Value& lhs, const Node::Kind& rhs) { return lhs == rhs.value; }
630 /// @brief Inequal compares Node::Kind values
631 /// @param[in] lhs Left-hand side of the operator
632 /// @param[in] rhs Right-hand side of the operator
633 /// @return Whether the comparison was successful
634 2133 constexpr bool operator!=(const Node::Kind& lhs, const Node::Kind::Value& rhs) { return !(lhs == rhs); }
635 /// @brief Inequal compares Node::Kind values
636 /// @param[in] lhs Left-hand side of the operator
637 /// @param[in] rhs Right-hand side of the operator
638 /// @return Whether the comparison was successful
639 constexpr bool operator!=(const Node::Kind::Value& lhs, const Node::Kind& rhs) { return !(lhs == rhs); }
640
641 } // namespace NAV
642