Chi-Tech
ChiObjectFactory.h
Go to the documentation of this file.
1#ifndef CHITECH_OBJECT_FACTORY_H
2#define CHITECH_OBJECT_FACTORY_H
3
5#include "ChiObject.h"
6
8
9/**Small utility macro for joining two words.*/
10#define ChiObjectFactoryJoinWordsA(x, y) x##y
11/**IDK why this is needed. Seems like counter doesnt work properly without it*/
12#define ChiObjectFactoryJoinWordsB(x, y) ChiObjectFactoryJoinWordsA(x, y)
13
14/**Macro for registering an object within the ChiObjectFactory singleton.
15 * \param namespace_name Name of the namespace within which the object is.
16 * \param object_name Name of the object in the registry.
17 * Example:
18 * \code
19 * RegisterChiObject(kaka, Zorba);
20 * \endcode
21 * \note Remember to include the header "ChiObject/ChiObjectFactory.h".*/
22#define RegisterChiObject(namespace_name, object_name) \
23 static char ChiObjectFactoryJoinWordsB( \
24 unique_var_name_object_##object_name##_, __COUNTER__) = \
25 ChiObjectFactory::AddObjectToRegistry<object_name, ChiObject>( \
26 #namespace_name, #object_name)
27
28/**Macro for registering an object (parameters only) within the
29 * ChiObjectFactory singleton.
30 * \param namespace_name Name of the namespace within which the object is.
31 * \param object_name Name of the object in the registry.
32 * Example:
33 * \code
34 * RegisterChiObjectParametersOnly(kaka, Zorba);
35 * \endcode
36 *
37 * \note Remember to include the header "ChiObject/object_maker.h"*/
38#define RegisterChiObjectParametersOnly(namespace_name, object_name) \
39 static char ChiObjectFactoryJoinWordsB( \
40 unique_var_name_object_##object_name##_, __COUNTER__) = \
41 ChiObjectFactory::AddObjectToRegistryParamsOnly<object_name>( \
42 #namespace_name, #object_name)
43
44/**Macro for registering a pure input parameters block within the
45 * ChiObjectFactory singleton AND giving it a custom name
46 * \param namespace_name Name of the namespace within which the object is.
47 * \param block_name Name of the object in the registry.
48 * \param syntax_function Actual syntax function for this object
49 * Example:
50 * \code
51 * RegisterSyntaxBlock(kaka, Zorba, ZorbaSyntaxFunction);
52 * \endcode
53 *
54 * \note Remember to include the header "ChiObject/object_maker.h"*/
55#define RegisterSyntaxBlock(namespace_name, block_name, syntax_function) \
56 static char ChiObjectFactoryJoinWordsB( \
57 unique_var_name_syntax_##block_name##_, __COUNTER__) = \
58 ChiObjectFactory::AddSyntaxBlockToRegistry( \
59 #namespace_name, #block_name, syntax_function)
60
61class ChiObject;
62
63// ##################################################################
64/**Singleton object for handling the registration and making of ChiObjects.*/
66{
67public:
68 using ObjectPtr = std::shared_ptr<ChiObject>;
69
72
73 // Structure storing the entities necessary for creating an object
75 {
78 };
79
80 // Deleted copy, move constructors and copy assignment operator
84
85 static ChiObjectFactory& GetInstance() noexcept;
86
87 const std::map<std::string, ObjectRegistryEntry>& Registry() const;
88 bool RegistryHasKey(const std::string& key) const;
89
90 template <typename T, typename base_T>
91 static char AddObjectToRegistry(const std::string& namespace_name,
92 const std::string& object_name)
93 {
94 auto& object_maker = GetInstance();
95
96 const std::string name = namespace_name + "::" + object_name;
97 object_maker.AssertRegistryKeyAvailable(name, __PRETTY_FUNCTION__);
98
99 ObjectRegistryEntry reg_entry;
100 reg_entry.get_in_params_func = &CallGetInputParamsFunction<T>;
101 reg_entry.constructor_func = &CallObjectConstructor<T, base_T>;
102 object_maker.object_registry_.insert(std::make_pair(name, reg_entry));
103
104 return 0;
105 }
106
107 template <typename T>
108 static char AddObjectToRegistryParamsOnly(const std::string& namespace_name,
109 const std::string& object_name)
110 {
111 auto& object_maker = GetInstance();
112
113 const std::string name = namespace_name + "::" + object_name;
114 object_maker.AssertRegistryKeyAvailable(name, __PRETTY_FUNCTION__);
115
116 ObjectRegistryEntry reg_entry;
117 reg_entry.get_in_params_func = &CallGetInputParamsFunction<T>;
118 object_maker.object_registry_.insert(std::make_pair(name, reg_entry));
119
120 return 0;
121 }
122
123 static char AddSyntaxBlockToRegistry(const std::string& namespace_name,
124 const std::string& block_name,
125 ObjectGetInParamsFunc syntax_function)
126 {
127 auto& object_maker = GetInstance();
128
129 const std::string name = namespace_name + "::" + block_name;
130 object_maker.AssertRegistryKeyAvailable(name, __PRETTY_FUNCTION__);
131
132 ObjectRegistryEntry reg_entry;
133 reg_entry.get_in_params_func = syntax_function;
134 object_maker.object_registry_.insert(std::make_pair(name, reg_entry));
135
136 return 0;
137 }
138
139 size_t MakeRegisteredObject(const chi::ParameterBlock& params) const;
140 size_t MakeRegisteredObjectOfType(const std::string& type,
141 const chi::ParameterBlock& params) const;
142
143 /**Returns the input parameters of a registered object.*/
145 GetRegisteredObjectParameters(const std::string& type) const;
146
147 /**\brief Dumps the object registry to stdout.*/
148 void DumpRegister() const;
149
150private:
151 std::map<std::string, ObjectRegistryEntry> object_registry_;
152
153 /**Private constructor because this is a singleton.*/
154 ChiObjectFactory() = default;
155
156 /**Utility redirection to call an object's static `GetInputParameters`
157 * function.*/
158 template <typename T>
160 {
161 return T::GetInputParameters();
162 }
163
164 /**Utility redirection to call an object's constructor with a specified list
165 * of input parameters.*/
166 template <typename T, typename base_T>
167 static std::shared_ptr<base_T>
169 {
170 return std::make_shared<T>(params);
171 }
172
173 void AssertRegistryKeyAvailable(const std::string& key,
174 const std::string& calling_function) const;
175};
176
177#endif // CHITECH_OBJECT_FACTORY_H
chi::InputParameters(*)() ObjectGetInParamsFunc
ChiObjectFactory()=default
void DumpRegister() const
Dumps the object registry to stdout.
bool RegistryHasKey(const std::string &key) const
void AssertRegistryKeyAvailable(const std::string &key, const std::string &calling_function) const
size_t MakeRegisteredObject(const chi::ParameterBlock &params) const
static char AddSyntaxBlockToRegistry(const std::string &namespace_name, const std::string &block_name, ObjectGetInParamsFunc syntax_function)
std::map< std::string, ObjectRegistryEntry > object_registry_
chi::InputParameters GetRegisteredObjectParameters(const std::string &type) const
const std::map< std::string, ObjectRegistryEntry > & Registry() const
ChiObjectFactory(const ChiObjectFactory &)=delete
std::shared_ptr< ChiObject > ObjectPtr
static char AddObjectToRegistry(const std::string &namespace_name, const std::string &object_name)
ChiObjectFactory(const ChiObjectFactory &&)=delete
ObjectPtr(*)(const chi::InputParameters &) ObjectConstructorFunc
static chi::InputParameters CallGetInputParamsFunction()
static std::shared_ptr< base_T > CallObjectConstructor(const chi::InputParameters &params)
size_t MakeRegisteredObjectOfType(const std::string &type, const chi::ParameterBlock &params) const
static ChiObjectFactory & GetInstance() noexcept
ChiObjectFactory & operator=(const ChiObjectFactory &)=delete
static char AddObjectToRegistryParamsOnly(const std::string &namespace_name, const std::string &object_name)
ObjectGetInParamsFunc get_in_params_func
ObjectConstructorFunc constructor_func