0.3.0
Loading...
Searching...
No Matches
Node.hpp
Go to the documentation of this file.
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
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"
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>
42using json = nlohmann::json;
43
44namespace NAV
45{
46class Node;
47class NodeData;
48class GroupBox;
49
50namespace NodeRegistry
51{
52
53void RegisterNodeTypes(); // NOLINT(readability-redundant-declaration) - false warning. This is needed for the friend declaration below
54
55} // namespace NodeRegistry
56
57namespace FlowExecutor
58{
59
61void execute(); // NOLINT(readability-redundant-declaration) - false warning. This is needed for the friend declaration below
62
64void deinitialize(); // NOLINT(readability-redundant-declaration) - false warning. This is needed for the friend declaration below
65
66} // namespace FlowExecutor
67
68namespace gui
69{
70class NodeEditorApplication;
71
72namespace menus
73{
74
75void ShowRunMenu();
76
77} // namespace menus
78
79} // namespace gui
80
84void to_json(json& j, const Node& node);
88void from_json(const json& j, Node& node);
89
91class Node
92{
93 public:
95 struct Kind
96 {
98 enum Value : uint8_t
99 {
103 };
104
106 Kind() = default;
107
110 constexpr Kind(Value kind) // NOLINT(hicpp-explicit-conversions, google-explicit-constructor)
111 : value(kind)
112 {}
113
116 explicit Kind(const std::string& string)
117 {
118 if (string == "Blueprint")
119 {
121 }
122 else if (string == "Simple")
123 {
125 }
126 else if (string == "GroupBox")
127 {
129 }
130 }
131
133 explicit operator Value() const { return value; }
135 explicit operator bool() = delete;
140 {
141 value = v;
142 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
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:
172 };
173
187
189 enum class Mode : uint8_t
190 {
193 };
194
197 explicit Node(std::string name);
199 virtual ~Node();
201 Node(const Node&) = delete;
203 Node(Node&&) = delete;
205 Node& operator=(const Node&) = delete;
207 Node& operator=(Node&&) = delete;
208
209 /* -------------------------------------------------------------------------------------------------------- */
210 /* Interface */
211 /* -------------------------------------------------------------------------------------------------------- */
212
214 [[nodiscard]] virtual std::string type() const = 0;
215
218 virtual void guiConfig();
219
221 [[nodiscard]] virtual json save() const;
222
225 virtual void restore(const json& j);
226
229 virtual void restoreAtferLink(const json& j);
230
232 virtual bool initialize();
233
235 virtual void deinitialize();
236
238 virtual bool resetNode();
239
244 virtual bool onCreateLink(OutputPin& startPin, InputPin& endPin);
245
249 virtual void onDeleteLink(OutputPin& startPin, InputPin& endPin);
250
254 virtual void afterCreateLink(OutputPin& startPin, InputPin& endPin);
255
259 virtual void afterDeleteLink(OutputPin& startPin, InputPin& endPin);
260
262 virtual void flush();
263
264 /* -------------------------------------------------------------------------------------------------------- */
265 /* Member functions */
266 /* -------------------------------------------------------------------------------------------------------- */
267
272 void notifyOutputValueChanged(size_t pinIdx, const InsTime& insTime, const std::scoped_lock<std::mutex>& guard);
273
276 [[nodiscard]] std::scoped_lock<std::mutex> requestOutputValueLock(size_t pinIdx);
277
282 template<typename T>
283 [[nodiscard]] std::optional<InputPin::IncomingLink::ValueWrapper<T>> getInputValue(size_t portIndex) const
284 {
285 return inputPins.at(portIndex).link.getValue<T>();
286 }
287
290 void releaseInputValue(size_t portIndex);
291
294 bool hasInputPinWithSameTime(const InsTime& insTime) const;
295
299 void invokeCallbacks(size_t portIndex, const std::shared_ptr<const NodeData>& data);
300
304 [[nodiscard]] InputPin& inputPinFromId(ax::NodeEditor::PinId pinId);
305
309 [[nodiscard]] OutputPin& outputPinFromId(ax::NodeEditor::PinId pinId);
310
314 [[nodiscard]] size_t inputPinIndexFromId(ax::NodeEditor::PinId pinId) const;
315
319 [[nodiscard]] size_t outputPinIndexFromId(ax::NodeEditor::PinId pinId) const;
320
322 [[nodiscard]] std::string nameId() const;
323
325 [[nodiscard]] const ImVec2& getSize() const;
326
327 // ------------------------------------------ State handling ---------------------------------------------
328
332 static std::string toString(State state);
333
335 [[nodiscard]] State getState() const;
336
338 [[nodiscard]] Mode getMode() const;
339
343 bool doInitialize(bool wait = false);
344
348 bool doReinitialize(bool wait = false);
349
353 bool doDeinitialize(bool wait = false);
354
358 bool doDisable(bool wait = false);
359
362 bool doEnable();
363
366
368 [[nodiscard]] bool isDisabled() const;
369
371 [[nodiscard]] bool isInitialized() const;
372
374 [[nodiscard]] bool isTransient() const;
375
377 [[nodiscard]] bool isOnlyRealtime() const;
378
379 /* -------------------------------------------------------------------------------------------------------- */
380 /* Member variables */
381 /* -------------------------------------------------------------------------------------------------------- */
382
384 ax::NodeEditor::NodeId id = 0;
388 std::string name;
390 std::vector<InputPin> inputPins;
392 std::vector<OutputPin> outputPins;
393
395 bool callbacksEnabled = false;
396
398 std::multimap<InsTime, std::pair<OutputPin*, size_t>> pollEvents;
399
400 protected:
403 ImVec2 _guiConfigDefaultWindowSize{ 500.0F, 400.0F };
404
406 bool _hasConfig = false;
407
410
412 bool _onlyRealTime = false;
413
414 private:
416 mutable std::mutex _stateMutex;
417
419 std::atomic<Mode> _mode = Mode::REAL_TIME;
420
422 bool _reinitialize = false;
423
425 bool _disable = false;
426
428 bool _showConfig = false;
429
436
438 bool _configWindowFocus = false;
439
441 ImVec2 _size{ 0, 0 };
442
444 static inline bool _autostartWorker = true;
445
446 std::chrono::duration<int64_t> _workerTimeout = std::chrono::minutes(1);
447 std::thread _worker;
448 std::mutex _workerMutex;
449 std::condition_variable _workerConditionVariable;
450 bool _workerWakeup = false;
451
454 static void workerThread(Node* node);
455
457 virtual void workerTimeoutHandler();
458
462
466
467 friend class gui::NodeEditorApplication;
468 friend class NAV::GroupBox;
469
476
480 friend void NAV::to_json(json& j, const Node& node);
484 friend void NAV::from_json(const json& j, Node& node);
485
488};
489
494constexpr bool operator==(const Node::Kind& lhs, const Node::Kind& rhs) { return lhs.value == rhs.value; }
499constexpr bool operator!=(const Node::Kind& lhs, const Node::Kind& rhs) { return !(lhs == rhs); }
500
505constexpr bool operator==(const Node::Kind& lhs, const Node::Kind::Value& rhs) { return lhs.value == rhs; }
510constexpr bool operator==(const Node::Kind::Value& lhs, const Node::Kind& rhs) { return lhs == rhs.value; }
515constexpr bool operator!=(const Node::Kind& lhs, const Node::Kind::Value& rhs) { return !(lhs == rhs); }
520constexpr bool operator!=(const Node::Kind::Value& lhs, const Node::Kind& rhs) { return !(lhs == rhs); }
521
522} // namespace NAV
nlohmann::json json
json namespace
Definition FlowManager.hpp:21
The class is responsible for all time-related tasks.
void to_json(json &j, const Node &node)
Converts the provided node into a json object.
void deinitialize()
Deinitialize all Nodes.
void from_json(const json &j, Node &node)
Converts the provided json object into a node object.
void RegisterNodeTypes()
Register all available Node types for the program.
void execute()
Main task of the FlowExecutor thread.
Pin class.
void ShowRunMenu()
Show the run menu dropdown.
Group Box.
Definition GroupBox.hpp:22
Input pins of nodes.
Definition Pin.hpp:491
The class is responsible for all time-related tasks.
Definition InsTime.hpp:710
Parent class for all data transmitted over Flow pins.
Definition NodeData.hpp:28
Abstract parent class for all nodes.
Definition Node.hpp:92
bool _workerWakeup
Variable to prevent the worker from sleeping.
Definition Node.hpp:450
bool isDisabled() const
Checks if the node is disabled.
bool isOnlyRealtime() const
Checks if the node is only working in real time (sensors, network interfaces, ...)
bool isInitialized() const
Checks if the node is initialized.
bool doDeinitialize(bool wait=false)
Asks the node worker to deinitialize the node.
void releaseInputValue(size_t portIndex)
Unblocks the connected node. Has to be called when the input value should be released and getInputVal...
bool _reinitialize
Flag if the node should be reinitialize after deinitializing.
Definition Node.hpp:422
bool _disable
Flag if the node should be disabled after deinitializing.
Definition Node.hpp:425
bool doDisable(bool wait=false)
Asks the node worker to disable the node.
State
Possible states of the node.
Definition Node.hpp:176
@ DoInitialize
Node should be initialized.
Definition Node.hpp:179
@ Shutdown
Node is shutting down.
Definition Node.hpp:185
@ DoShutdown
Node should shut down.
Definition Node.hpp:184
@ Initializing
Node is currently initializing.
Definition Node.hpp:180
@ Initialized
Node is initialized (green)
Definition Node.hpp:181
@ DoDeinitialize
Node should be deinitialized.
Definition Node.hpp:182
@ Disabled
Node is disabled and won't be initialized.
Definition Node.hpp:177
@ Deinitializing
Node is currently deinitializing.
Definition Node.hpp:183
@ Deinitialized
Node is deinitialized (red)
Definition Node.hpp:178
void wakeWorker()
Wakes the worker thread.
OutputPin & outputPinFromId(ax::NodeEditor::PinId pinId)
Returns the pin with the given id.
ImVec2 _size
Size of the node in pixels.
Definition Node.hpp:441
std::mutex _configWindowMutex
Mutex to show the config window (prevents initialization to modify values within the config window)
Definition Node.hpp:431
virtual void onDeleteLink(OutputPin &startPin, InputPin &endPin)
Called when a link is to be deleted.
ImVec2 _guiConfigDefaultWindowSize
Definition Node.hpp:403
bool workerInitializeNode()
Called by the worker to initialize the node.
const ImVec2 & getSize() const
Get the size of the node.
bool hasInputPinWithSameTime(const InsTime &insTime) const
Checks wether there is an input pin with the same time.
std::vector< OutputPin > outputPins
List of output pins.
Definition Node.hpp:392
void notifyOutputValueChanged(size_t pinIdx, const InsTime &insTime, const std::scoped_lock< std::mutex > &guard)
Notifies connected nodes about the change.
Node(Node &&)=delete
Move constructor.
virtual void restore(const json &j)
Restores the node from a json object.
Node(std::string name)
Constructor.
virtual void afterCreateLink(OutputPin &startPin, InputPin &endPin)
Called when a new link was established.
virtual void deinitialize()
Deinitialize the Node.
virtual bool initialize()
Initialize the Node.
bool workerDeinitializeNode()
Called by the worker to deinitialize the node.
std::optional< InputPin::IncomingLink::ValueWrapper< T > > getInputValue(size_t portIndex) const
Get Input Value connected on the pin. Only const data types.
Definition Node.hpp:283
std::multimap< InsTime, std::pair< OutputPin *, size_t > > pollEvents
Map with callback events (sorted by time)
Definition Node.hpp:398
virtual void afterDeleteLink(OutputPin &startPin, InputPin &endPin)
Called when a link was deleted.
Kind kind
Kind of the Node.
Definition Node.hpp:386
Node & operator=(Node &&)=delete
Move assignment operator.
static std::string toString(State state)
Converts the state into a printable text.
InputPin & inputPinFromId(ax::NodeEditor::PinId pinId)
Returns the pin with the given id.
size_t outputPinIndexFromId(ax::NodeEditor::PinId pinId) const
Returns the index of the pin.
std::vector< InputPin > inputPins
List of input pins.
Definition Node.hpp:390
bool doInitialize(bool wait=false)
Asks the node worker to initialize the node.
virtual json save() const
Saves the node into a json object.
State _state
Current state of the node.
Definition Node.hpp:415
Mode
Different Modes the Node can work in.
Definition Node.hpp:190
@ POST_PROCESSING
Node running in post-processing mode.
Definition Node.hpp:192
@ REAL_TIME
Node running in real-time mode.
Definition Node.hpp:191
bool callbacksEnabled
Enables the callbacks.
Definition Node.hpp:395
static void workerThread(Node *node)
Worker thread.
bool _configWindowFocus
Flag if the config window should be focused.
Definition Node.hpp:438
std::atomic< Mode > _mode
Mode the node is currently running in.
Definition Node.hpp:419
std::string nameId() const
Node name and id.
bool _showConfig
Flag if the config window is shown.
Definition Node.hpp:428
std::thread _worker
Worker handling initialization and processing of data.
Definition Node.hpp:447
bool _lockConfigDuringRun
Lock the config when executing post-processing.
Definition Node.hpp:409
virtual void restoreAtferLink(const json &j)
Restores link related properties of the node from a json object.
size_t inputPinIndexFromId(ax::NodeEditor::PinId pinId) const
Returns the index of the pin.
Node & operator=(const Node &)=delete
Copy assignment operator.
bool _configWindowIsCollapsed
Flag if the config window is collapsed.
Definition Node.hpp:435
std::mutex _workerMutex
Mutex to interact with the worker condition variable.
Definition Node.hpp:448
std::string name
Name of the Node.
Definition Node.hpp:388
bool _onlyRealTime
Whether the node can run in post-processing or only real-time.
Definition Node.hpp:412
bool doEnable()
Enable the node.
virtual void flush()
Function called by the flow executer after finishing to flush out remaining data.
bool doReinitialize(bool wait=false)
Asks the node worker to reinitialize the node.
std::chrono::duration< int64_t > _workerTimeout
Periodic timeout of the worker to check if new data available.
Definition Node.hpp:446
std::condition_variable _workerConditionVariable
Condition variable to signal the worker thread to do something.
Definition Node.hpp:449
virtual void workerTimeoutHandler()
Handler which gets triggered if the worker runs into a periodic timeout.
Node(const Node &)=delete
Copy constructor.
virtual ~Node()
Destructor.
bool _configWindowForceCollapse
Flag if the config window should be forced collapsed.
Definition Node.hpp:433
std::scoped_lock< std::mutex > requestOutputValueLock(size_t pinIdx)
Blocks the thread till the output values was read by all connected nodes.
void invokeCallbacks(size_t portIndex, const std::shared_ptr< const NodeData > &data)
Calls all registered callbacks on the specified output port.
virtual bool resetNode()
Resets the node. It is guaranteed that the node is initialized when this is called.
static bool _autostartWorker
Flag which prevents the worker to be autostarted if false.
Definition Node.hpp:444
State getState() const
Get the current state of the node.
Mode getMode() const
Get the current mode of the node.
bool _hasConfig
Flag if the config window should be shown.
Definition Node.hpp:406
virtual std::string type() const =0
String representation of the Class Type.
virtual void guiConfig()
ImGui config window which is shown on double click.
std::mutex _stateMutex
Mutex to interact with the worker state variable.
Definition Node.hpp:416
virtual bool onCreateLink(OutputPin &startPin, InputPin &endPin)
Called when a new link is to be established.
bool isTransient() const
Checks if the node is changing its state currently.
Output pins of nodes.
Definition Pin.hpp:338
Application class providing all relevant GUI callbacks.
Definition NodeEditorApplication.hpp:36
bool operator==(const ImVec4 &lhs, const ImVec4 &rhs)
Equal comparison operator.
bool operator!=(const ImVec4 &lhs, const ImVec4 &rhs)
Unequal comparison operator.
Kind information class.
Definition Node.hpp:96
constexpr Kind(Value kind)
Implicit Constructor from Value type.
Definition Node.hpp:110
Kind()=default
Default Constructor.
Value value
Value of the node kind.
Definition Node.hpp:171
Value
Possible kinds of Nodes.
Definition Node.hpp:99
@ Blueprint
Node with header.
Definition Node.hpp:100
@ GroupBox
Group box which can group other nodes and drag them together.
Definition Node.hpp:102
@ Simple
Node without header, which displays its name in the center of the content.
Definition Node.hpp:101
Kind & operator=(Value v)
Assignment operator from Value type.
Definition Node.hpp:139
friend constexpr bool operator==(const Node::Kind &lhs, const Node::Kind &rhs)
Equal compares Node::Kind values.
Definition Node.hpp:494
Kind(const std::string &string)
Constructor from std::string.
Definition Node.hpp:116
friend constexpr bool operator!=(const Node::Kind &lhs, const Node::Kind &rhs)
Inequal compares Node::Kind values.
Definition Node.hpp:499