2#include <Dataflow/RaDataflow.hpp>
4#include <Dataflow/Core/GraphNodes.hpp>
5#include <Dataflow/Core/Node.hpp>
6#include <Dataflow/Core/NodeFactory.hpp>
9#include <Core/Utils/BijectiveAssociation.hpp>
10#include <Core/Utils/Color.hpp>
11#include <Core/Utils/Singleton.hpp>
33 bool execute()
override;
34 void destroy()
override;
42 bool loadFromJson(
const std::string& jsonFilePath );
60 template <
typename T,
typename... U>
89 Node::PortIndex portOutIdx,
91 Node::PortIndex portInIdx );
93 bool add_link( Node::PortBaseOutRawPtr outputPort, Node::PortBaseInRawPtr inputPort );
96 template <
typename T,
typename U>
102 Node::PortIndex portOutIdx,
104 Node::PortIndex portInIdx )
const;
107 bool can_link(
const Node* nodeFrom,
108 Node::PortIndex portOutIdx,
110 Node::PortIndex portInIdx )
const;
142 template <
typename T>
158 bool compile()
override;
165 void generate_ports();
171 virtual void clear_nodes();
178 inline void needs_recompile();
190 Node::PortBaseInRawPtr input_node_port(
const std::string& nodeName,
203 Node::PortBaseOutRawPtr output_node_port(
const std::string& nodeName,
206 bool shouldBeSaved() {
return m_should_save; }
233 using Node::add_input;
234 using Node::add_output;
244 void add_input_output_nodes();
253 void remove_unlinked_input_output_ports();
264 bool fromJsonInternal(
const nlohmann::json& data )
override;
265 void toJsonInternal( nlohmann::json& )
const override;
279 bool contains_node_recursive(
const Node* node )
const;
287 backtrack_graph( Node* current,
293 int traverse_graph( Node* current,
298 bool check_last_port_io_nodes(
const Node* nodeFrom,
299 Node::PortIndex portOutIdx,
301 Node::PortIndex portInIdx )
const {
302 if ( nodeFrom == m_input_node.get() && portOutIdx == m_input_node->outputs().size() )
304 if ( nodeTo == m_output_node.get() && portInIdx == m_output_node->inputs().size() )
309 bool are_nodes_valids(
const Node* nodeFrom,
const Node* nodeTo,
bool verbose =
false )
const;
310 static bool are_ports_compatible(
const Node* nodeFrom,
311 const PortBaseOut* portOut,
313 const PortBaseIn* portIn );
314 class RA_DATAFLOW_CORE_API Log
317 static void already_linked(
const Node* node,
const PortBase* port );
318 static void link_type_mismatch(
const Node* nodeFrom,
319 const PortBase* portOut,
321 const PortBase* portIn );
323 static void bad_port_index(
const std::string& type,
325 Node::PortIndex idx );
326 static void try_to_link_input_to_output();
331 bool m_should_save {
false };
335 bool m_ready {
false };
346 bool m_nodesAndLinksProtected {
false };
352template <
typename T,
typename... U>
359template <
typename T,
typename U>
362 using namespace Ra::Core::Utils;
364 static_assert( std::is_same_v<T, U>,
"in and out port's types mismatch" );
366 return add_link( outputPort.get(), inputPort.get() );
370 Node::PortIndex portOutIdx,
372 Node::PortIndex portInIdx )
const {
373 return can_link( nodeFrom.
get(), portOutIdx, nodeTo.
get(), portInIdx );
377 Node::PortIndex portOutIdx,
379 Node::PortIndex portInIdx )
const {
383 if ( !are_nodes_valids( nodeFrom, nodeTo ) ) {
return false; }
384 if ( check_last_port_io_nodes( nodeFrom, portOutIdx, nodeTo, portInIdx ) ) {
385 if ( nodeFrom == m_input_node.
get() )
return portIn !=
nullptr;
386 if ( nodeTo == m_output_node.
get() )
return portOut !=
nullptr;
390 return portIn && portOut && ( portIn->type() == portOut->type() && !portIn->is_linked() );
394 m_should_save =
true;
400 auto n =
node( nodeName );
401 auto p = n->input_by_name( portName );
402 CORE_ASSERT( p.first.isValid(),
"invalid port, node: " + nodeName +
" port: " + portName );
408 auto n =
node( nodeName );
409 auto p = n->output_by_name( portName );
410 CORE_ASSERT( p.first.isValid(),
"invalid port, node: " + nodeName +
" port: " + portName );
418 m_input_node->set_graph(
this );
419 m_output_node->set_graph(
this );
425 if ( m_input_node ) { m_input_node->remove_unlinked_ports(); }
426 if ( m_output_node ) { m_output_node->remove_unlinked_ports(); }
430inline const std::string& DataflowGraph::node_typename() {
431 static std::string demangledTypeName {
"Core DataflowGraph" };
432 return demangledTypeName;
Represent a set of connected nodes that define a Direct Acyclic Computational Graph Ownership of node...
bool add_link(const std::shared_ptr< Node > &nodeFrom, const std::string &nodeFromOutputName, const std::shared_ptr< Node > &nodeTo, const std::string &nodeToInputName)
Connects two nodes of the graph.
void setNodesAndLinksProtection(bool on)
protect nodes and links from deletion.
virtual bool add_node(std::shared_ptr< Node > newNode)
Adds a node to the graph.
Node::PortBaseInRawPtr input_node_port(const std::string &nodeName, const std::string &portName)
Gets an input port form a node of the graph.
size_t node_count() const
Gets the number of nodes.
const std::vector< std::shared_ptr< Node > > & nodes() const
Get the vector of all the nodes on the graph.
std::shared_ptr< Node > node(const std::string &instanceNameNode) const
void generate_ports()
fill input and output ports of graph from its input and output nodes if exists.
void remove_unlinked_input_output_ports()
Removes unsused (unlinked) input/output ports.
bool is_compiled() const
Test if the graph is compiled.
std::shared_ptr< T > node(const std::string &instanceNameNode) const
Node::PortBaseOutRawPtr output_node_port(const std::string &nodeName, const std::string &portName)
Gets an output port from a node of the graph.
const std::vector< std::vector< Node * > > & nodes_by_level() const
Gets the nodes ordered by level (after compilation)
bool can_link(const std::shared_ptr< Node > &nodeFrom, Node::PortIndex portOutIdx, const std::shared_ptr< Node > &nodeTo, Node::PortIndex portInIdx) const
bool nodesAndLinksProtection() const
get the protection status protect nodes and links from deletion
void add_input_output_nodes()
Create (if not already created) input/output node of the graph, and fills graph input/output.
Base abstract class for all the nodes added and used by the node system.
auto input_by_index(PortIndex index) const
Convenience alias to port_by_index("in", index)
auto output_by_index(PortIndex index) const
Convenience alias to port_by_index("out", index)
Input port accepting data of type T.
Forward PortOut classes used by getLink and reflect.
hepler function to manage enum as underlying types in VariableSet
T dynamic_pointer_cast(T... args)