3#include <Dataflow/RaDataflow.hpp>
5#include <Dataflow/Core/Node.hpp>
15#define BASIC_NODE_INIT( TYPE, BASE ) \
17 explicit TYPE( const std::string& name ) : TYPE( name, TYPE::node_typename() ) {} \
18 static const std::string& node_typename() { \
19 static std::string demangledName = #TYPE; \
20 return demangledName; \
22 TYPE( const std::string& instanceName, const std::string& typeName ) : \
23 BASE( instanceName, typeName )
25class RA_DATAFLOW_CORE_API GraphNode :
public Node
27 BASIC_NODE_INIT( GraphNode, Node ) {}
30 bool execute()
override {
31 CORE_ASSERT( m_inputs.size() == m_outputs.size(),
32 "GraphNode input and output size differ" );
34 for (
size_t i = 0; i < m_inputs.size(); ++i ) {
35 auto factory = PortFactory::getInstance();
36 auto output_setter =
factory->output_setter( m_outputs[i]->type() );
37 auto input_getter =
factory->input_getter( m_inputs[i]->type() );
38 output_setter( m_outputs[i].get(), input_getter( m_inputs[i].get() ) );
43 void remove_unlinked_ports() {
44 CORE_ASSERT( m_inputs.size() == m_outputs.size(),
45 "GraphNode input and output size differ" );
47 int last_index = m_inputs.size();
48 for (
int i = 0; i < last_index; ++i ) {
49 if ( !m_inputs[i]->is_linked() && m_outputs[i]->link_count() == 0 ) {
50 std::swap( m_inputs[i], m_inputs[last_index - 1] );
51 std::swap( m_outputs[i], m_outputs[last_index - 1] );
56 m_inputs.erase( m_inputs.begin() + last_index, m_inputs.end() );
57 m_outputs.erase( m_outputs.begin() + last_index, m_outputs.end() );
60 void set_graph( Node* node ) { m_graph = node; }
61 Node* graph()
const {
return m_graph; }
64 auto add_ports( PortBaseRawPtr port ) {
65 auto factory = PortFactory::getInstance();
66 auto in_name = find_available_name(
"in", port->name() );
67 auto in =
factory->make_input_port(
this, in_name, port->type() );
68 auto out_name = find_available_name(
"out", port->name() );
69 auto out =
factory->make_output_port(
this, out_name, port->type() );
71 auto input_idx = add_input( in );
72 auto output_idx = add_output( out );
81 while ( port_by_name( type, new_name ).first.isValid() ) {
88 void make_port_helper(
89 const nlohmann::json& ports,
92 for (
const auto& port : ports ) {
93 size_t index = port[
"port_index"];
96 port_map[index] = ctor(
this, name, type );
100 bool fromJsonInternal(
const nlohmann::json& data )
override {
101 auto factory = PortFactory::getInstance();
105 if (
const auto& ports = data.find(
"inputs" ); ports != data.end() ) {
106 auto ctor =
std::bind( &PortFactory::make_input_port_from_name, factory, _1, _2, _3 );
107 make_port_helper<PortBaseInPtr>( *ports, inputs, ctor );
109 if (
const auto& ports = data.find(
"outputs" ); ports != data.end() ) {
110 auto ctor =
std::bind( &PortFactory::make_output_port_from_name, factory, _1, _2, _3 );
111 make_port_helper<PortBaseOutPtr>( *ports, outputs, ctor );
116 for (
const auto& [key, value] : inputs ) {
117 assert( m_inputs.size() == key );
118 m_inputs.push_back( value );
120 for (
const auto& [key, value] : outputs ) {
121 assert( m_outputs.size() == key );
122 m_outputs.push_back( value );
124 CORE_ASSERT( m_inputs.size() == m_outputs.size(),
125 "json do not contains same number of inputs and outputs for GraphNode" );
131 Node* m_graph {
nullptr };
134class RA_DATAFLOW_CORE_API GraphInputNode :
public GraphNode
136 BASIC_NODE_INIT( GraphInputNode, GraphNode ) {}
139 PortIndex add_output_port( PortBaseInRawPtr port ) {
140 auto [input_idx, output_idx, in, out] = add_ports( port );
141 if ( in && out ) port->connect( out.get() );
146class RA_DATAFLOW_CORE_API GraphOutputNode :
public GraphNode
148 BASIC_NODE_INIT( GraphOutputNode, GraphNode ) {}
151 PortIndex add_input_port( PortBaseOutRawPtr port ) {
152 auto [input_idx, output_idx, in, out] = add_ports( port );
153 if ( in && out ) in->connect( port );
auto factory(const NodeFactorySet::key_type &name) -> NodeFactorySet::mapped_type
Gets the given factory from the manager.
hepler function to manage enum as underlying types in VariableSet