GNode library (C++)
Loading...
Searching...
No Matches
graph.hpp
Go to the documentation of this file.
1/* Copyright (c) 2023 Otto Link. Distributed under the terms of the GNU General
2 * Public License. The full license is in the file LICENSE, distributed with
3 * this software. */
4
16#pragma once
17#include <functional>
18#include <map>
19#include <memory>
20#include <unordered_set>
21
22#include "gnode/link.hpp"
23#include "gnode/node.hpp"
24#include "gnode/point.hpp"
25#include "gnode/event.hpp"
26
27typedef unsigned int uint;
28
29namespace gnode
30{
31
36class Graph
37{
38public:
42 Graph() = default;
43
49 Graph(const std::string &id) : id(id) {}
50
54 virtual ~Graph() = default;
55
63 virtual std::string add_node(const std::shared_ptr<Node> &p_node,
64 const std::string &id = "");
65
74 template <typename U, typename... Args> std::string add_node(Args... args)
75 {
76 return this->add_node(std::make_shared<U>(args...));
77 }
78
82 void clear();
83
90 std::vector<Point> compute_graph_layout_sugiyama();
91
97 std::string get_id() const { return this->id; };
98
109 bool new_link(const std::string &from,
110 int port_from,
111 const std::string &to,
112 int port_to);
113
124 bool new_link(const std::string &from,
125 const std::string &port_label_from,
126 const std::string &to,
127 const std::string &port_label_to);
128
139 bool remove_link(const std::string &from,
140 int port_from,
141 const std::string &to,
142 int port_to);
143
154 bool remove_link(const std::string &from,
155 const std::string &port_label_from,
156 const std::string &to,
157 const std::string &port_label_to);
158
165 void export_to_graphviz(const std::string &fname = "export.dot",
166 const std::string &graph_label = "graph");
167
174 void export_to_mermaid(const std::string &fname = "export.mmd",
175 const std::string &graph_label = "graph");
176
183 std::map<std::string, std::vector<std::string>> get_connectivity_downstream()
184 const;
185
191 std::vector<std::string> get_connectivity_downstream(
192 const std::string &node_id) const;
193
200 std::map<std::string, std::vector<std::string>> get_connectivity_upstream()
201 const;
202
208 std::vector<std::string> get_connectivity_upstream(
209 const std::string &node_id) const;
210
216 uint get_id_count() const { return this->id_count; }
217
218 uint *get_id_count_ref() { return &this->id_count; }
219
225 const std::vector<Link> &get_links() const { return this->links; }
226
239 std::vector<LinkView> get_link_views(const std::string &node_id) const;
240
245 Node *get_node(const std::string &node_id) const
246 {
247 auto it = nodes.find(node_id);
248 return (it != nodes.end()) ? it->second.get() : nullptr;
249 }
250
260 template <typename T = Node>
261 T *get_node_ref_by_id(const std::string &node_id) const
262 {
263 auto it = nodes.find(node_id);
264 if (it == nodes.end()) return nullptr;
265
266 T *ptr = dynamic_cast<T *>(it->second.get());
267 if (!ptr)
268 throw std::runtime_error("Failed to cast node with ID: " + node_id +
269 " to the specified type.");
270
271 return ptr;
272 }
273
279 const std::map<std::string, std::shared_ptr<Node>> &get_nodes()
280 {
281 return this->nodes;
282 }
283
285 std::vector<std::string> get_nodes_to_update(
286 const std::vector<std::string> &node_ids);
287
288 std::vector<std::string> get_nodes_to_update(const std::string &node_id);
289
309 bool has_cycle() const;
310
318 bool is_node_id_available(const std::string &node_id);
319
333 bool is_reachable(const std::string &start,
334 const std::string &target,
335 std::unordered_set<std::string> visited = {}) const;
336
343 virtual void post_update() {}
344
348 void print();
349
355 virtual void remove_node(const std::string &id);
356
362 void set_id(const std::string &new_id) { this->id = new_id; };
363
369 void set_id_count(uint new_id_count) { this->id_count = new_id_count; }
370
380
389 std::function<bool(const std::string &node_id)> cancel_update_callback;
390
392 std::vector<std::string> topological_sort(
393 const std::vector<std::string> &dirty_node_ids) const;
394
401 virtual void update();
402
408 virtual void update(const std::string &node_id);
409
415 virtual void update(const std::vector<std::string> &node_ids);
416
417protected:
421 std::map<std::string, std::shared_ptr<Node>> nodes;
422
426 std::vector<Link> links;
427
428private:
433
437 std::string id = "";
438};
439
440// helper
441
442template <typename T> bool contains(const std::vector<T> &vec, const T &value)
443{
444 return std::find(vec.begin(), vec.end(), value) != vec.end();
445}
446
447} // namespace gnode
Thread-safe publisher-subscriber event stream.
Definition event.hpp:100
The Graph class provides methods for manipulating nodes and connections in a directed graph structure...
Definition graph.hpp:37
bool new_link(const std::string &from, int port_from, const std::string &to, int port_to)
Connect two nodes in the graph using port indices.
std::vector< LinkView > get_link_views(const std::string &node_id) const
Returns the link views connected to a node.
virtual ~Graph()=default
Destroy the Graph object.
std::string add_node(Args... args)
Add a new node of a specific type to the graph.
Definition graph.hpp:74
virtual void update()
Mark all nodes as dirty and update the entire graph.
void set_id(const std::string &new_id)
Set the graph ID.
Definition graph.hpp:362
std::vector< Link > links
A list of links between nodes in the graph.
Definition graph.hpp:426
uint * get_id_count_ref()
Definition graph.hpp:218
uint get_id_count() const
Get the current count of unique identifiers.
Definition graph.hpp:216
std::string id
Graph id.
Definition graph.hpp:437
std::vector< std::string > get_connectivity_downstream(const std::string &node_id) const
Returns the downstream nodes connected to a node.
void print()
Print the current graph structure.
void export_to_mermaid(const std::string &fname="export.mmd", const std::string &graph_label="graph")
Export the graph to a Mermaid file.
std::vector< Point > compute_graph_layout_sugiyama()
Compute the layout of the graph using the Sugiyama algorithm.
uint id_count
Keep track of unique identifiers.
Definition graph.hpp:432
std::vector< std::string > get_nodes_to_update(const std::string &node_id)
bool has_cycle() const
Checks whether the graph contains a cycle.
void clear()
Clear the graph, remove all the nodes and the links.
bool is_node_id_available(const std::string &node_id)
Check if a node ID is available in the graph.
Node * get_node(const std::string &node_id) const
Get a pointer to a node by its ID.
Definition graph.hpp:245
virtual void remove_node(const std::string &id)
Remove a node from the graph by its ID.
std::map< std::string, std::shared_ptr< Node > > nodes
A map of node IDs to shared pointers of Node objects.
Definition graph.hpp:421
Event< const std::string &, const std::vector< std::string > &, bool > graph_progress_event
Event triggered before and after a node is updated.
Definition graph.hpp:379
virtual void update(const std::vector< std::string > &node_ids)
Update a specific list of node IDs.
std::vector< std::string > get_nodes_to_update(const std::vector< std::string > &node_ids)
Get node list for update priority.
bool remove_link(const std::string &from, int port_from, const std::string &to, int port_to)
Disconnect two nodes in the graph using port indices.
std::string get_id() const
Return the graph ID.
Definition graph.hpp:97
Graph(const std::string &id)
Construct a new Graph object.
Definition graph.hpp:49
const std::vector< Link > & get_links() const
Get the link storage.
Definition graph.hpp:225
virtual void post_update()
Method called after the graph update process is completed.
Definition graph.hpp:343
bool remove_link(const std::string &from, const std::string &port_label_from, const std::string &to, const std::string &port_label_to)
Disconnect two nodes in the graph using port labels.
std::function< bool(const std::string &node_id)> cancel_update_callback
Optional callback to cancel an update, checked before each node.
Definition graph.hpp:389
void export_to_graphviz(const std::string &fname="export.dot", const std::string &graph_label="graph")
Export the graph to a Graphviz DOT file.
Graph()=default
Construct a new Graph object.
const std::map< std::string, std::shared_ptr< Node > > & get_nodes()
Get a reference to the nodes map.
Definition graph.hpp:279
virtual std::string add_node(const std::shared_ptr< Node > &p_node, const std::string &id="")
Add a new node to the graph.
T * get_node_ref_by_id(const std::string &node_id) const
Get a pointer to a node by its ID.
Definition graph.hpp:261
std::map< std::string, std::vector< std::string > > get_connectivity_upstream() const
Get the upstream connectivity of the graph.
bool is_reachable(const std::string &start, const std::string &target, std::unordered_set< std::string > visited={}) const
Checks whether a target node is reachable from a start node.
bool new_link(const std::string &from, const std::string &port_label_from, const std::string &to, const std::string &port_label_to)
Connect two nodes in the graph using port labels.
std::vector< std::string > topological_sort(const std::vector< std::string > &dirty_node_ids) const
Kahn's algorithm for node sorting for update priority.
std::vector< std::string > get_connectivity_upstream(const std::string &node_id) const
Returns the upstream nodes connected to a node.
virtual void update(const std::string &node_id)
Update a specific node by its ID.
std::map< std::string, std::vector< std::string > > get_connectivity_downstream() const
Get the downstream connectivity of the graph.
void set_id_count(uint new_id_count)
Set the current count of unique identifiers.
Definition graph.hpp:369
Abstract Node class that represents a basic building block in a graph-based system.
Definition node.hpp:35
Thread-safe publisher-subscriber event stream.
unsigned int uint
Definition graph.hpp:27
Definition data.hpp:23
bool contains(const std::vector< T > &vec, const T &value)
Definition graph.hpp:442
Defines the Point struct used to represent a 2D point in space.