Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.29
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Node.hpp
1#pragma once
2#include <Dataflow/RaDataflow.hpp>
3
4#include <Core/Containers/VariableSet.hpp>
5#include <Core/Utils/Index.hpp>
6#include <Dataflow/Core/PortFactory.hpp>
7#include <Dataflow/Core/PortIn.hpp>
8#include <Dataflow/Core/PortOut.hpp>
9
10#include <nlohmann/json.hpp>
11
12#include <memory>
13#include <string>
14#include <type_traits> // conditional, is_same
15#include <vector>
16
17namespace Ra {
18namespace Dataflow {
19namespace Core {
20
39class RA_DATAFLOW_CORE_API Node
40{
41 public:
42 using PortIndex = Ra::Core::Utils::Index;
43
44 template <typename Port>
46
47 template <typename Port>
49 template <typename Port>
50 using PortRawPtr = Port*;
51
52 template <typename Type>
54 template <typename Type>
56
57 template <typename Type>
59 template <typename Type>
61
63 using PortBaseRawPtr = PortRawPtr<PortBase>;
65
67 using PortBaseInRawPtr = PortRawPtr<PortBaseIn>;
69
71 using PortBaseOutRawPtr = PortRawPtr<PortBaseOut>;
73
74 template <typename Port>
76
77 template <typename T>
79
84 Node() = delete;
85 Node( const Node& ) = delete;
86 Node& operator=( const Node& ) = delete;
88
90 virtual ~Node() = default;
91
93 bool operator==( const Node& node );
94
97
105 virtual void init();
106
114 virtual bool compile();
115
123 virtual bool execute() = 0;
124
131 virtual void destroy();
133
136
144 auto port_by_name( const std::string& type, const std::string& name ) const
146
148 auto input_by_name( const std::string& name ) const -> IndexAndPort<PortBaseInRawPtr>;
150 auto output_by_name( const std::string& name ) const -> IndexAndPort<PortBaseOutRawPtr>;
151
159 PortBaseRawPtr port_by_index( const std::string& type, PortIndex index ) const;
161 auto input_by_index( PortIndex index ) const { return port_base( m_inputs, index ); }
163 auto output_by_index( PortIndex index ) const { return port_base( m_outputs, index ); }
165 template <typename T>
166 auto input_by_index( PortIndex index ) const {
167 return port<T>( m_inputs, index );
168 }
170 template <typename T>
171 auto output_by_index( PortIndex index ) const {
172 return port<T>( m_outputs, index );
173 }
174
180 const PortBaseInCollection& inputs() const;
181
187 const PortBaseOutCollection& outputs() const;
188
191
193 const std::string& model_name() const;
195 const std::string& display_name() const { return m_display_name; }
197 void set_display_name( const std::string& name ) { m_display_name = name; }
198
200 const std::string& instance_name() const;
201
203 void set_instance_name( const std::string& name );
204
206
211
217 void toJson( nlohmann::json& data ) const;
218
224 bool fromJson( const nlohmann::json& data );
225
227
235 void add_metadata( const nlohmann::json& data );
236
238 const nlohmann::json& metadata();
239
240 inline bool is_initialized() const { return m_initialized; }
241
243 Ra::Core::VariableSet& parameters() { return m_parameters; }
244
246 Ra::Core::VariableSet& input_variables();
247
249 inline bool is_output();
250
252 inline bool is_input();
253
254 protected:
261 Node( const std::string& instance, const std::string& typeName );
262
272 template <typename PortType>
273 auto port_by_name( const PortCollection<PortPtr<PortType>>& ports,
274 const std::string& name ) const -> IndexAndPort<PortRawPtr<PortType>>;
283 template <typename PortType>
284 auto port_base( const PortCollection<PortPtr<PortType>>& ports, PortIndex idx ) const
285 -> PortRawPtr<PortType>;
295 template <typename T, typename PortType>
296 auto port( const PortCollection<PortPtr<PortType>>& ports, PortIndex index ) const {
297 return static_cast<typename std::conditional<
299 /*then*/ PortInRawPtr<T>,
300 /*else*/ PortOutRawPtr<T>>::type>( port_base( ports, index ) );
301 }
309 virtual bool fromJsonInternal( const nlohmann::json& data );
317 virtual void toJsonInternal( nlohmann::json& data ) const;
325 template <typename PortType>
326 PortIndex add_port( PortCollection<PortPtr<PortType>>&, PortPtr<PortType> port );
328 PortIndex add_input( PortBaseInPtr in );
330 PortIndex add_output( PortBaseOutPtr out );
331
339 template <typename T, typename... U>
340 auto add_input( U&&... u ) {
341 auto idx = add_input( std::make_shared<PortIn<T>>( this, std::forward<U>( u )... ) );
342 return input_port<T>( idx );
343 }
351 template <typename T, typename... U>
352 auto add_output( U&&... u ) {
353 auto idx = add_output( std::make_shared<PortOut<T>>( this, std::forward<U>( u )... ) );
354 return output_port<T>( idx );
355 }
356
364 template <typename T>
365 auto input_port( PortIndex index ) {
366 return std::static_pointer_cast<PortIn<T>>( m_inputs[index] );
367 }
368
370 template <typename T>
371 auto output_port( PortIndex index ) {
372 return std::static_pointer_cast<PortOut<T>>( m_outputs[index] );
373 }
374
382 void remove_input( PortIndex index ) { m_inputs[index].reset(); }
384 void remove_output( PortIndex index ) { m_outputs[index].reset(); }
385
386 template <typename T>
387 auto add_parameter( const std::string& name, const T& value ) {
388 return m_parameters.insertVariable<T>( name, value ).first;
389 }
390
391 template <typename T>
392 bool remove_parameter( const std::string& name ) {
393 return m_parameters.deleteVariable( name );
394 }
395
396 template <typename T>
397 bool remove_parameter( ParamHandle<T>& handle ) {
398 return m_parameters.deleteVariable( handle );
399 }
400
402 bool m_initialized { false };
408 std::string m_display_name { "" };
409
414
420
422 nlohmann::json m_metadata;
423};
424
425// -----------------------------------------------------------------
426// ---------------------- inline methods ---------------------------
427
428inline void Node::init() {
429 m_initialized = true;
430}
431
432inline void Node::destroy() {
433 m_inputs.clear();
434 m_outputs.clear();
437}
438
439inline const nlohmann::json& Node::metadata() {
440 return m_metadata;
441}
442
443inline const std::string& Node::model_name() const {
444 return m_model_name;
445}
446
447inline const std::string& Node::instance_name() const {
448 return m_instance_name;
449}
450
451inline void Node::set_instance_name( const std::string& newName ) {
452 m_instance_name = newName;
453}
454
456 return m_inputs;
457}
458
460 return m_outputs;
461}
462
463inline bool Node::operator==( const Node& node ) {
464 return ( m_model_name == node.model_name() ) && ( m_instance_name == node.instance_name() );
465}
466
467template <typename PortType>
468inline Node::PortIndex Node::add_port( PortCollection<PortPtr<PortType>>& ports,
469 PortPtr<PortType> port ) {
470 PortIndex index;
471 // look for a free slot
472 auto it = std::find_if( ports.begin(), ports.end(), []( const auto& p ) { return !p; } );
473 if ( it != ports.end() ) {
474 it->swap( port );
475 index = std::distance( ports.begin(), it );
476 }
477 else {
478 ports.push_back( std::move( port ) );
479 index = ports.size() - 1;
480 }
481 return index;
482}
483
484inline Node::PortIndex Node::add_input( PortBaseInPtr in ) {
485 return add_port( m_inputs, std::move( in ) );
486}
487
488inline Node::PortIndex Node::add_output( PortBaseOutPtr out ) {
489 return add_port( m_outputs, std::move( out ) );
490}
491
492inline bool Node::compile() {
493 return true;
494}
495
498 for ( const auto& p : m_inputs ) {
499 if ( p->has_default_value() ) p->insert( m_input_variables );
500 }
501
502 return m_input_variables;
503}
504
505inline bool Node::is_output() {
506 bool ret = true;
507 for ( const auto& p : m_outputs ) {
508 ret = ret && ( p->link_count() == 0 );
509 }
510 return ret;
511}
512
513inline bool Node::is_input() {
514 bool ret = true;
515 //
516 for ( const auto& p : m_inputs ) {
517 ret = ret && p->has_default_value() && !p->is_linked();
518 }
519 return ret;
520}
521
522template <typename PortType>
524 const std::string& name ) const -> IndexAndPort<PortRawPtr<PortType>> {
525 // p might be nullptr if has been removed from ports
526 auto itr = std::find_if(
527 ports.begin(), ports.end(), [n = name]( const auto& p ) { return p && p->name() == n; } );
528 PortRawPtr<PortType> port { nullptr };
529 PortIndex portIndex;
530 if ( itr != ports.cend() ) {
531 port = itr->get();
532 portIndex = std::distance( ports.begin(), itr );
533 }
534 return { portIndex, port };
535}
536
537template <typename PortType>
538auto Node::port_base( const PortCollection<PortPtr<PortType>>& ports, PortIndex index ) const
539 -> PortRawPtr<PortType> {
540 if ( 0 <= index && size_t( index ) < ports.size() ) { return ports[index].get(); }
541 return nullptr;
542}
543
544} // namespace Core
545} // namespace Dataflow
546} // namespace Ra
Heterogeneous container storing "Variables", that maps a name (std::string) to a value (of any type T...
typename VariableContainer< T >::iterator VariableHandle
Handle of a variable A handle on a variable with type T is an iterator into the BaseContainer....
void clear()
remove all elements from the container
Base abstract class for all the nodes added and used by the node system.
Definition Node.hpp:40
PortIndex add_output(PortBaseOutPtr out)
Convenience alias to add_port(outputs(), out)
Definition Node.hpp:488
auto input_port(PortIndex index)
Gets a typed (input/output) port.
Definition Node.hpp:365
void remove_input(PortIndex index)
Remove the given port from the managed (input/output) ports.
Definition Node.hpp:382
std::string m_model_name
The type name of the node. Initialized once at construction.
Definition Node.hpp:404
std::string m_instance_name
The instance name of the node.
Definition Node.hpp:406
auto input_by_index(PortIndex index) const
Convenience alias with typed port.
Definition Node.hpp:166
Ra::Core::VariableSet m_input_variables
Definition Node.hpp:419
virtual ~Node()=default
make Node a base abstract class
const std::string & instance_name() const
Gets the instance name of the node.
Definition Node.hpp:447
bool operator==(const Node &node)
Two nodes are considered equal if there model and instance names are the same.
Definition Node.hpp:463
virtual bool compile()
Compile the node to check its validity.
Definition Node.hpp:492
virtual void init()
Initializes the node content.
Definition Node.hpp:428
PortIndex add_input(PortBaseInPtr in)
Convenience alias to add_port(inputs(), in)
Definition Node.hpp:484
const PortBaseInCollection & inputs() const
Gets the in ports of the node.
Definition Node.hpp:455
bool is_output()
Node is output if none of the output ports is linked.
Definition Node.hpp:505
const std::string & display_name() const
Gets the display name of the node (e.g. for gui), no need to be unique in a graph.
Definition Node.hpp:195
void set_instance_name(const std::string &name)
Sets the instance name the node (unused?) instance name must be unique in a graph.
Definition Node.hpp:451
auto add_input(U &&... u)
Adds a typed input port.
Definition Node.hpp:340
void set_display_name(const std::string &name)
Set the display name.
Definition Node.hpp:197
Ra::Core::VariableSet & input_variables()
Return a variable set of input ports default value reference, if any.
Definition Node.hpp:496
auto port(const PortCollection< PortPtr< PortType > > &ports, PortIndex index) const
Gets a port in a collection by its index.
Definition Node.hpp:296
auto output_by_index(PortIndex index) const
Convenience alias with typed port.
Definition Node.hpp:171
auto input_by_index(PortIndex index) const
Convenience alias to port_by_index("in", index)
Definition Node.hpp:161
PortCollection< PortPtr< PortBaseIn > > m_inputs
The in ports of the node (own by the node)
Definition Node.hpp:411
PortCollection< PortPtr< PortBaseOut > > m_outputs
The out ports of the node (own by the node)
Definition Node.hpp:413
const std::string & model_name() const
Gets the model (type/class) name of the node.
Definition Node.hpp:443
bool is_input()
Node is input if all input ports have default values and not linked.
Definition Node.hpp:513
Ra::Core::VariableSet & parameters()
Return node's parameters.
Definition Node.hpp:243
auto port_by_name(const std::string &type, const std::string &name) const -> IndexAndPort< PortBaseRawPtr >
Get a port by its name.
Definition Node.cpp:72
PortIndex add_port(PortCollection< PortPtr< PortType > > &, PortPtr< PortType > port)
Adds a port to port collection.
Definition Node.hpp:468
bool m_initialized
Flag that checks if the node is already initialized.
Definition Node.hpp:402
auto add_output(U &&... u)
Adds a typed output port.
Definition Node.hpp:352
virtual bool execute()=0
Executes the node.
nlohmann::json m_metadata
Additional data on the node, added by application or gui or ...
Definition Node.hpp:422
const nlohmann::json & metadata()
Give access to extra json data stored on the node.
Definition Node.hpp:439
void remove_output(PortIndex index)
Remove the given port from the managed (input/output) ports.
Definition Node.hpp:384
auto output_by_index(PortIndex index) const
Convenience alias to port_by_index("out", index)
Definition Node.hpp:163
auto port_base(const PortCollection< PortPtr< PortType > > &ports, PortIndex idx) const -> PortRawPtr< PortType >
Gets the PortBase In or Out by its index.
Definition Node.hpp:538
virtual void destroy()
Delete the node's content.
Definition Node.hpp:432
auto output_port(PortIndex index)
Gets a typed (input/output) port.
Definition Node.hpp:371
Ra::Core::VariableSet m_parameters
The editable parameters of the node.
Definition Node.hpp:416
const PortBaseOutCollection & outputs() const
Gets the out ports of the node.
Definition Node.hpp:459
Input port accepting data of type T.
Definition PortOut.hpp:17
Forward PortOut classes used by getLink and reflect.
Definition PortOut.hpp:73
T distance(T... args)
T find_if(T... args)
T forward(T... args)
T make_shared(T... args)
T move(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4
T static_pointer_cast(T... args)