Radium Engine  1.7.2
Loading...
Searching...
No Matches
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;
77 auto register_node_creator( const std::string& nodeType,
78 NodeCreatorFunctor nodeCreator,
79 const std::string& nodeCategory = "RadiumNodes" ) -> bool;
80
89 [[nodiscard]] auto create_node( const std::string& nodeType,
90 const nlohmann::json& data,
91 DataflowGraph* owningGraph = nullptr ) -> std::shared_ptr<Node>;
92
106 [[nodiscard]] auto factory_map() const -> const ContainerType&;
107
108 private:
113 auto next_node_id() -> size_t;
114
115 ContainerType m_nodesCreators;
116 size_t m_nodesCreated { 0 };
117 std::string m_name;
118};
119
123class RA_DATAFLOW_CORE_API NodeFactorySet
124{
125 public:
127
128 using key_type = container_type::key_type;
129 using mapped_type = container_type::mapped_type;
130 using value_type = container_type::value_type;
131
132 using const_iterator = container_type::const_iterator;
133 using iterator = container_type::iterator;
134
141 auto add_factory( mapped_type factory ) -> bool;
142
149 auto has_factory( const key_type& name ) -> Ra::Core::Utils::optional<mapped_type>;
150
156 auto remove_factory( const key_type& name ) -> bool;
157
174 [[nodiscard]] auto create_node( const std::string& nodeType,
175 const nlohmann::json& data,
176 DataflowGraph* owningGraph = nullptr ) -> std::shared_ptr<Node>;
177
178 /* Wrappers to the interface of the underlying container
179 * see https://en.cppreference.com/w/cpp/container/map
180 */
181 auto begin() const -> const_iterator;
182 auto end() const -> const_iterator;
183 auto cbegin() const -> const_iterator;
184 auto cend() const -> const_iterator;
185 auto find( const key_type& key ) const -> const_iterator;
186 auto insert( value_type value ) -> std::pair<iterator, bool>;
187 auto erase( const key_type& key ) -> size_t;
188
189 const std::string& default_factory_name() { return m_default_factory_name; }
190
191 private:
192 container_type m_factories;
193 const std::string m_default_factory_name { "Dataflow Nodes" };
194};
195
207namespace NodeFactoriesManager {
208RA_DATAFLOW_CORE_API auto factory_manager() -> NodeFactorySet&;
209
219RA_DATAFLOW_CORE_API auto register_factory( NodeFactorySet::mapped_type factory ) -> bool;
220
226RA_DATAFLOW_CORE_API auto create_factory( const NodeFactorySet::key_type& name )
227 -> NodeFactorySet::mapped_type;
228
234RA_DATAFLOW_CORE_API auto factory( const NodeFactorySet::key_type& name )
235 -> NodeFactorySet::mapped_type;
236
242RA_DATAFLOW_CORE_API auto unregister_factory( const NodeFactorySet::key_type& name ) -> bool;
243
247RA_DATAFLOW_CORE_API auto default_factory() -> NodeFactorySet::mapped_type;
248} // namespace NodeFactoriesManager
249
250// -----------------------------------------------------------------
251// ---------------------- inline methods ---------------------------
252
253template <typename T>
255 const std::string& nodeCategory ) -> bool {
256 return register_node_creator( T::node_typename(), std::move( nodeCreator ), nodeCategory );
257}
258
259template <typename T>
260auto NodeFactory::register_node_creator( const std::string& instanceNamePrefix,
261 const std::string& nodeCategory ) -> bool {
262 return register_node_creator(
263 T::node_typename(),
264 [this, instanceNamePrefix]( const nlohmann::json& data ) {
265 std::string instanceName;
266 if ( data.contains( "instance" ) ) {
267 instanceName = data["instance"];
268 this->next_node_id(); // increment even if not used to avoid collision on creation
269 // after loading files
270 }
271 else { instanceName = instanceNamePrefix + std::to_string( this->next_node_id() ); }
272 auto node = std::make_shared<T>( instanceName );
273 if ( !node->fromJson( data ) ) return std::shared_ptr<T> { nullptr };
274 return node;
275 },
276 nodeCategory );
277}
278
279inline auto NodeFactory::factory_map() const -> const NodeFactory::ContainerType& {
280 return m_nodesCreators;
281}
282
283inline auto NodeFactorySet::add_factory( NodeFactorySet::mapped_type factory ) -> bool {
284 const auto [loc, inserted] = insert( { factory->name(), std::move( factory ) } );
285 return inserted;
286}
287
288inline auto NodeFactorySet::has_factory( const NodeFactorySet::key_type& name )
289 -> Ra::Core::Utils::optional<NodeFactorySet::mapped_type> {
290 if ( auto fct = m_factories.find( name ); fct != m_factories.end() ) { return fct->second; }
291 return {};
292}
293
294inline auto NodeFactorySet::remove_factory( const NodeFactorySet::key_type& name ) -> bool {
295 return erase( name );
296}
297inline auto NodeFactorySet::begin() const -> NodeFactorySet::const_iterator {
298 return m_factories.begin();
299}
300inline auto NodeFactorySet::end() const -> NodeFactorySet::const_iterator {
301 return m_factories.end();
302}
303inline auto NodeFactorySet::cbegin() const -> NodeFactorySet::const_iterator {
304 return m_factories.cbegin();
305}
306inline auto NodeFactorySet::cend() const -> NodeFactorySet::const_iterator {
307 return m_factories.cend();
308}
309inline auto NodeFactorySet::find( const NodeFactorySet::key_type& key ) const
310 -> NodeFactorySet::const_iterator {
311 return m_factories.find( key );
312}
313inline auto NodeFactorySet::insert( NodeFactorySet::value_type value )
315 return m_factories.insert( std::move( value ) );
316}
317inline auto NodeFactorySet::erase( const NodeFactorySet::key_type& key ) -> size_t {
318 return m_factories.erase( key );
319}
320
321} // namespace Core
322} // namespace Dataflow
323} // 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)