3#include <Dataflow/RaDataflow.hpp>
5#include <Core/Containers/VariableSet.hpp>
6#include <Core/Utils/Log.hpp>
7#include <Core/Utils/Observable.hpp>
8#include <Dataflow/Core/Port.hpp>
20class RA_DATAFLOW_CORE_API PortBaseIn :
public PortBase
26 PortBaseIn() =
delete;
27 PortBaseIn(
const PortBaseIn& ) =
delete;
28 PortBaseIn& operator=(
const PortBaseIn& ) =
delete;
31 virtual bool accept( PortBaseOut* portOut )
const;
32 virtual bool connect( PortBaseOut* portOut ) = 0;
33 virtual bool disconnect() = 0;
35 virtual bool is_link_mandatory()
const;
36 virtual bool is_linked()
const = 0;
37 virtual bool has_default_value()
const = 0;
39 virtual PortBaseOut* link() = 0;
42 PortOut<T>* link_as();
45 void set_default_value(
const T& value );
70class PortIn :
public PortBaseIn,
80 PortIn(
const PortIn& ) =
delete;
81 PortIn& operator=(
const PortIn& ) =
delete;
93 PortBaseIn(
node,
name, typeid( T ) ), m_defaultValue { value } {
113 bool accept( PortBaseOut* portOut )
const override;
116 bool connect( PortBaseOut* portOut )
override;
119 bool disconnect()
override;
121 PortBaseOut* link()
override {
return m_from; }
124 void set_default_value(
const T& value ) { m_defaultValue = value; }
125 T& default_value() {
return *m_defaultValue; }
126 bool has_default_value()
const override {
return m_defaultValue.has_value(); }
128 if ( has_default_value() )
132 bool is_linked()
const override {
return m_from !=
nullptr; }
134 template <
typename B = T,
135 std::enable_if_t<std::is_constructible<nlohmann::json, B>::value,
bool> =
true>
136 void to_json_impl( nlohmann::json&
data ) {
137 if ( has_default_value() ) {
data[
"default_value"] = default_value(); }
139 template <
typename B = T,
140 std::enable_if_t<!std::is_constructible<nlohmann::json, B>::value,
bool> =
true>
141 void to_json_impl( nlohmann::json&
data ) {
142 if ( has_default_value() ) {
143 data[
"default_value"] =
144 std::string(
"Default value not saved, missing json export for " ) +
145 Ra::Core::Utils::simplifiedDemangledType<T>();
148 template <
typename B = T,
149 std::enable_if_t<std::is_assignable<nlohmann::json, B>::value,
bool> =
true>
150 void from_json_impl(
const nlohmann::json&
data ) {
151 using namespace Ra::Core::Utils;
152 if (
auto value_it =
data.find(
"default_value" ); value_it !=
data.end() ) {
153 set_default_value( ( *value_it ).template get<T>() );
156 template <
typename B = T,
157 std::enable_if_t<!std::is_assignable<nlohmann::json, B>::value,
int> =
true>
158 void from_json_impl(
const nlohmann::json&
data ) {
161 void to_json( nlohmann::json&
data )
override {
162 PortBase::to_json(
data );
163 to_json_impl(
data );
165 void from_json(
const nlohmann::json&
data )
override {
166 PortBase::from_json(
data );
167 from_json_impl(
data );
171 PortOut<T>* m_from =
nullptr;
172 std::optional<T> m_defaultValue {};
176template <
typename Type>
177using PortInPtr = PortPtr<PortIn<Type>>;
178template <
typename Type>
179using PortInRawPtr =
typename PortInPtr<Type>::element_type*;
181using PortBaseInPtr = PortPtr<PortBaseIn>;
182using PortBaseInRawPtr = PortRawPtr<PortBaseIn>;
185PortOut<T>* PortBaseIn::link_as() {
186 return static_cast<PortIn<T>*
>( this )->getLink();
190void PortBaseIn::set_default_value(
const T& value ) {
191 static_cast<PortIn<T>*
>( this )->set_default_value( value );
195T& PortBaseIn::data() {
196 return static_cast<PortIn<T>*
>( this )->data();
201 if ( is_linked() )
return m_from->data();
202 if ( m_defaultValue )
return *m_defaultValue;
203 CORE_ASSERT(
false,
"should not get here" );
204 using namespace Ra::Core::Utils;
205 LOG( logERROR ) <<
"graph is not valid";
206 return *m_defaultValue;
211 if ( is_linked() ) {
return m_from->has_data(); }
212 return m_defaultValue.has_value();
217 return !m_from && ( PortBaseIn::accept( portOut ) );
221bool PortIn<T>::accept( PortOut<T>* )
const {
226bool PortIn<T>::connect( PortBaseOut* portOut ) {
227 if ( accept( portOut ) ) {
228 m_from =
static_cast<PortOut<T>*
>( portOut );
229 m_from->increase_link_count();
231 this->notify( name(), *
this,
true );
237bool PortIn<T>::connect( PortOut<T>* portOut ) {
238 if ( accept( portOut ) ) {
240 m_from->increase_link_count();
242 this->notify( name(), *
this,
true );
248bool PortIn<T>::disconnect() {
251 m_from->decrease_link_count();
252 this->notify( name(), *
this,
false );
Heterogeneous container storing "Variables", that maps a name (std::string) to a value (of any type T...
auto setVariable(const std::string &name, const T &value) -> std::pair< VariableHandle< T >, bool >
reset (or set if the variable does not exist yet) the value of the variable.
Base abstract class for all the nodes added and used by the node system.
const std::string & name() const
Gets the port's name.
Node * node() const
Gets a pointer to the node this port belongs to.
void set_name(const std::string &name)
Set's port name.
Input port accepting data of type T.
PortIn(Node *node, const std::string &name, const T &value)
T & data()
Gets the data pointed by the connected out port.
PortIn(Node *node, const std::string &name)
Forward PortOut classes used by getLink and reflect.
hepler function to manage enum as underlying types in VariableSet