Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NodeFactory.hpp
1#pragma once
2#include <Dataflow/RaDataflow.hpp>
3
4#include <Dataflow/Core/Node.hpp>
5
6#include <Core/Utils/StdOptional.hpp>
7
8#include <functional>
9#include <iostream>
10#include <unordered_map>
11
12#define REGISTER_TYPE_TO_FACTORY( FACTORY, TYPE, NAMESPACE ) \
13 FACTORY->register_node_creator<TYPE>( TYPE::node_typename() + "_", #NAMESPACE )
14
15namespace Ra {
16namespace Dataflow {
17namespace Core {
18
19class DataflowGraph;
20
26class RA_DATAFLOW_CORE_API NodeFactory
27{
28 public:
30 explicit NodeFactory( std::string name );
31
32 [[nodiscard]] auto name() const -> std::string;
33
42 using NodeCreatorFunctor = std::function<std::shared_ptr<Node>( const nlohmann::json& data )>;
43
52 template <typename T>
53 auto register_node_creator( NodeCreatorFunctor nodeCreator,
54 const std::string& nodeCategory = "RadiumNodes" ) -> bool;
55
65 template <typename T>
66 auto register_node_creator( const std::string& instanceNamePrefix,
67 const std::string& nodeCategory = "RadiumNodes" ) -> bool;
76 auto register_node_creator( const std::string& nodeType,
77 NodeCreatorFunctor nodeCreator,
78 const std::string& nodeCategory = "RadiumNodes" ) -> bool;
79
88 [[nodiscard]] auto create_node( const std::string& nodeType,
89 const nlohmann::json& data,
90 DataflowGraph* owningGraph = nullptr ) -> std::shared_ptr<Node>;
91
105 [[nodiscard]] auto factory_map() const -> const ContainerType&;
106
107 private:
112 auto next_node_id() -> size_t;
113
114 ContainerType m_nodesCreators;
115 size_t m_nodesCreated { 0 };
116 std::string m_name;
117};
118
122class RA_DATAFLOW_CORE_API NodeFactorySet
123{
124 public:
126
127 using key_type = container_type::key_type;
128 using mapped_type = container_type::mapped_type;
129 using value_type = container_type::value_type;
130
131 using const_iterator = container_type::const_iterator;
132 using iterator = container_type::iterator;
133
140 auto add_factory( mapped_type factory ) -> bool;
141
148 auto has_factory( const key_type& name ) -> Ra::Core::Utils::optional<mapped_type>;
149
155 auto remove_factory( const key_type& name ) -> bool;
156
173 [[nodiscard]] auto create_node( const std::string& nodeType,
174 const nlohmann::json& data,
175 DataflowGraph* owningGraph = nullptr ) -> std::shared_ptr<Node>;
176
177 /* Wrappers to the interface of the underlying container
178 * see https://en.cppreference.com/w/cpp/container/map
179 */
180 auto begin() const -> const_iterator;
181 auto end() const -> const_iterator;
182 auto cbegin() const -> const_iterator;
183 auto cend() const -> const_iterator;
184 auto find( const key_type& key ) const -> const_iterator;
185 auto insert( value_type value ) -> std::pair<iterator, bool>;
186 auto erase( const key_type& key ) -> size_t;
187
188 const std::string& default_factory_name() { return m_default_factory_name; }
189
190 private:
191 container_type m_factories;
192 const std::string m_default_factory_name { "Dataflow Nodes" };
193};
194
206namespace NodeFactoriesManager {
207RA_DATAFLOW_CORE_API auto factory_manager() -> NodeFactorySet&;
208
218RA_DATAFLOW_CORE_API auto register_factory( NodeFactorySet::mapped_type factory ) -> bool;
219
225RA_DATAFLOW_CORE_API auto create_factory( const NodeFactorySet::key_type& name )
226 -> NodeFactorySet::mapped_type;
227
233RA_DATAFLOW_CORE_API auto factory( const NodeFactorySet::key_type& name )
234 -> NodeFactorySet::mapped_type;
235
241RA_DATAFLOW_CORE_API auto unregister_factory( const NodeFactorySet::key_type& name ) -> bool;
242
246RA_DATAFLOW_CORE_API auto default_factory() -> NodeFactorySet::mapped_type;
247} // namespace NodeFactoriesManager
248
249// -----------------------------------------------------------------
250// ---------------------- inline methods ---------------------------
251
252template <typename T>
254 const std::string& nodeCategory ) -> bool {
255 return register_node_creator( T::node_typename(), std::move( nodeCreator ), nodeCategory );
256}
257
258template <typename T>
259auto NodeFactory::register_node_creator( const std::string& instanceNamePrefix,
260 const std::string& nodeCategory ) -> bool {
261 return register_node_creator(
262 T::node_typename(),
263 [this, instanceNamePrefix]( const nlohmann::json& data ) {
264 std::string instanceName;
265 if ( data.contains( "instance" ) ) {
266 instanceName = data["instance"];
267 this->next_node_id(); // increment even if not used to avoid collision on creation
268 // after loading files
269 }
270 else { instanceName = instanceNamePrefix + std::to_string( this->next_node_id() ); }
271 auto node = std::make_shared<T>( instanceName );
272 if ( !node->fromJson( data ) ) return std::shared_ptr<T> { nullptr };
273 return node;
274 },
275 nodeCategory );
276}
277
278inline auto NodeFactory::factory_map() const -> const NodeFactory::ContainerType& {
279 return m_nodesCreators;
280}
281
282inline auto NodeFactorySet::add_factory( NodeFactorySet::mapped_type factory ) -> bool {
283 const auto [loc, inserted] = insert( { factory->name(), std::move( factory ) } );
284 return inserted;
285}
286
287inline auto NodeFactorySet::has_factory( const NodeFactorySet::key_type& name )
288 -> Ra::Core::Utils::optional<NodeFactorySet::mapped_type> {
289 if ( auto fct = m_factories.find( name ); fct != m_factories.end() ) { return fct->second; }
290 return {};
291}
292
293inline auto NodeFactorySet::remove_factory( const NodeFactorySet::key_type& name ) -> bool {
294 return erase( name );
295}
296inline auto NodeFactorySet::begin() const -> NodeFactorySet::const_iterator {
297 return m_factories.begin();
298}
299inline auto NodeFactorySet::end() const -> NodeFactorySet::const_iterator {
300 return m_factories.end();
301}
302inline auto NodeFactorySet::cbegin() const -> NodeFactorySet::const_iterator {
303 return m_factories.cbegin();
304}
305inline auto NodeFactorySet::cend() const -> NodeFactorySet::const_iterator {
306 return m_factories.cend();
307}
308inline auto NodeFactorySet::find( const NodeFactorySet::key_type& key ) const
309 -> NodeFactorySet::const_iterator {
310 return m_factories.find( key );
311}
312inline auto NodeFactorySet::insert( NodeFactorySet::value_type value )
314 return m_factories.insert( std::move( value ) );
315}
316inline auto NodeFactorySet::erase( const NodeFactorySet::key_type& key ) -> size_t {
317 return m_factories.erase( key );
318}
319
320} // namespace Core
321} // namespace Dataflow
322} // namespace Ra
T begin(T... args)
Represent a set of connected nodes that define a Direct Acyclic Computational Graph Ownership of node...
auto add_factory(mapped_type factory) -> bool
auto has_factory(const key_type &name) -> Ra::Core::Utils::optional< mapped_type >
Test if a factory exists in the set with the given name.
auto remove_factory(const key_type &name) -> bool
Remove the identified factory from the set.
auto factory_map() const -> const ContainerType &
auto register_node_creator(NodeCreatorFunctor nodeCreator, const std::string &nodeCategory="RadiumNodes") -> bool
T end(T... args)
T make_shared(T... args)
T move(T... args)
auto factory(const NodeFactorySet::key_type &name) -> NodeFactorySet::mapped_type
Gets the given factory from the manager.
auto unregister_factory(const NodeFactorySet::key_type &name) -> bool
Unregister the factory from the manager.
auto register_factory(NodeFactorySet::mapped_type factory) -> bool
Register a factory into the manager. The key will be fetched from the factory (its name)
auto default_factory() -> NodeFactorySet::mapped_type
Gets the "default" factory for nodes exported by the Core dataflow library.
auto create_factory(const NodeFactorySet::key_type &name) -> NodeFactorySet::mapped_type
Create and register a factory to the manager.
auto factory_manager() -> NodeFactorySet &
Allow static initialization without init order problems.
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4
T to_string(T... args)