Aeon Engine c550894
AeonGames Open Source Game Engine
Loading...
Searching...
No Matches
Factory.h
1/*
2Copyright (C) 2016-2021,2025,2026 Rodrigo Jose Hernandez Cordoba
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16#include <vector>
17#include <string>
18#include <functional>
19#include <memory>
20#include <utility>
21#include <tuple>
22#include <algorithm>
23#include "aeongames/StringId.hpp"
24
27#define FactoryDefinition(X,...) \
28 std::unique_ptr<X> Construct##X ( uint32_t aIdentifier,##__VA_ARGS__);\
29 std::unique_ptr<X> Construct##X ( const std::string& aIdentifier,##__VA_ARGS__ );\
30 std::unique_ptr<X> Construct##X ( const StringId& aIdentifier,##__VA_ARGS__ );\
31 bool Register##X##Constructor ( const StringId& aIdentifier, const std::function<std::unique_ptr<X>(__VA_ARGS__) >& aConstructor ); \
32 bool Unregister##X##Constructor ( const StringId& aIdentifier );\
33 void Enumerate##X##Constructors ( const std::function<bool ( const StringId& ) >& aEnumerator ); \
34 void std::vector<std::string> Get##X##ConstructorNames();
35
38#define FactoryImplementation(X) \
39 std::unique_ptr<X> Construct##X ( uint32_t aIdentifier )\
40 { \
41 return Factory<X>::Construct ( aIdentifier ); \
42 } \
43 std::unique_ptr<X> Construct##X ( const std::string& aIdentifier )\
44 { \
45 return Factory<X>::Construct ( aIdentifier ); \
46 } \
47 std::unique_ptr<X> Construct##X ( const StringId& aIdentifier )\
48 { \
49 return Factory<X>::Construct ( aIdentifier.GetId() ); \
50 } \
51 bool Register##X##Constructor ( const StringId& aIdentifier, const std::function<std::unique_ptr<X>() >& aConstructor ) \
52 { \
53 return Factory<X>::RegisterConstructor ( aIdentifier, aConstructor );\
54 }\
55 bool Unregister##X##Constructor ( const StringId& aIdentifier )\
56 {\
57 return Factory<X>::UnregisterConstructor ( aIdentifier );\
58 }\
59 void Enumerate##X##Constructors ( const std::function<bool ( const StringId& ) >& aEnumerator )\
60 {\
61 Factory<X>::EnumerateConstructors ( aEnumerator );\
62 }\
63 std::vector<std::string> Get##X##ConstructorNames()\
64 {\
65 return Factory<X>::GetConstructorNames();\
66 }
67
71#define FactoryImplementation1Arg(X,Y) \
72 std::unique_ptr<X> Construct##X ( uint32_t aIdentifier, Y ARG )\
73 { \
74 return Factory<X,Y>::Construct ( aIdentifier, ARG ); \
75 } \
76 std::unique_ptr<X> Construct##X ( const std::string& aIdentifier, Y ARG )\
77 { \
78 return Factory<X,Y>::Construct ( aIdentifier, ARG ); \
79 } \
80 std::unique_ptr<X> Construct##X ( const StringId& aIdentifier, Y ARG )\
81 { \
82 return Factory<X,Y>::Construct ( aIdentifier.GetId(), ARG ); \
83 } \
84 bool Register##X##Constructor ( const StringId& aIdentifier, const std::function<std::unique_ptr<X>(Y) >& aConstructor ) \
85 { \
86 return Factory<X,Y>::RegisterConstructor ( aIdentifier, aConstructor );\
87 }\
88 bool Unregister##X##Constructor ( const StringId& aIdentifier )\
89 {\
90 return Factory<X,Y>::UnregisterConstructor ( aIdentifier );\
91 }\
92 void Enumerate##X##Constructors ( const std::function<bool ( const StringId& ) >& aEnumerator )\
93 {\
94 Factory<X,Y>::EnumerateConstructors ( aEnumerator );\
95 }\
96 std::vector<std::string> Get##X##ConstructorNames()\
97 {\
98 return Factory<X,Y>::GetConstructorNames();\
99 }
100
101namespace AeonGames
102{
106 template<class T, typename... Types>
108 {
109 public:
111 using Constructor = std::tuple<StringId, std::function < std::unique_ptr<T> ( Types... args ) >>;
116 static std::unique_ptr<T> Construct ( uint32_t aIdentifier, Types... args )
117 {
118 auto it = std::find_if ( Constructors.begin(), Constructors.end(),
119 [aIdentifier] ( const Constructor & aConstructor )
120 {
121 return aIdentifier == std::get<0> ( aConstructor );
122 } );
123 if ( it != Constructors.end() )
124 {
125 return std::get<1> ( *it ) ( args... );
126 }
127 return nullptr;
128 }
129
133 static std::unique_ptr<T> Construct ( const std::string& aIdentifier, Types... args )
134 {
135 return Construct ( crc32i ( aIdentifier.data(), aIdentifier.size() ), args... );
136 }
137
141 static bool RegisterConstructor ( const StringId& aIdentifier, const std::function < std::unique_ptr<T> ( Types... args ) > & aConstructor )
142 {
143 auto it = std::find_if ( Constructors.begin(), Constructors.end(),
144 [aIdentifier] ( const Constructor & aConstructor )
145 {
146 return aIdentifier == std::get<0> ( aConstructor );
147 } );
148 if ( it == Constructors.end() )
149 {
150 Constructors.emplace_back ( aIdentifier, aConstructor );
151 return true;
152 }
153 return false;
154 }
155
158 static bool UnregisterConstructor ( const StringId& aIdentifier )
159 {
160 auto it = std::find_if ( Constructors.begin(), Constructors.end(),
161 [aIdentifier] ( const Constructor & aConstructor )
162 {
163 return aIdentifier == std::get<0> ( aConstructor );
164 } );
165 if ( it != Constructors.end() )
166 {
167 Constructors.erase ( it );
168 return true;
169 }
170 return false;
171 }
172
174 static void EnumerateConstructors ( const std::function<bool ( const StringId& ) >& aEnumerator )
175 {
176 for ( auto& i : Constructors )
177 {
178 if ( !aEnumerator ( std::get<0> ( i ) ) )
179 {
180 return;
181 }
182 }
183 }
184
186 static std::vector<std::string> GetConstructorNames()
187 {
188 std::vector<std::string> names{Constructors.size() };
189 std::transform ( Constructors.begin(), Constructors.end(), names.begin(),
190 [] ( const Constructor & constructor )
191 {
192 return std::get<0> ( constructor ).GetString();
193 } );
194 return names;
195 }
196
197 private:
199 static std::vector < Constructor > Constructors;
200 };
201
202 template<class T, typename... Types>
203 std::vector<typename Factory<T, Types...>::Constructor> Factory<T, Types...>::Constructors;
205
212 template<class T, typename... Types>
213 std::unique_ptr<T> Construct ( uint32_t aIdentifier, Types... args )
214 {
215 return Factory<T, Types...>::Construct ( aIdentifier, args... );
216 }
217
219 template<class T, typename... Types>
220 std::unique_ptr<T> Construct ( const std::string& aIdentifier, Types... args )
221 {
222 return Factory<T, Types...>::Construct ( aIdentifier, args... );
223 }
224
226 template<class T, typename... Types>
227 std::unique_ptr<T> Construct ( const StringId& aIdentifier, Types... args )
228 {
229 return Factory<T, Types...>::Construct ( aIdentifier.GetId(), args... );
230 }
231
233 template<class T, typename... Types>
234 bool RegisterConstructor ( const StringId& aIdentifier, const std::function<std::unique_ptr<T> ( Types... args ) >& aConstructor )
235 {
236 return Factory<T, Types...>::RegisterConstructor ( aIdentifier, aConstructor );
237 }
238
240 template<class T, typename... Types>
241 bool UnregisterConstructor ( const StringId& aIdentifier )
242 {
243 return Factory<T, Types...>::UnregisterConstructor ( aIdentifier );
244 }
245
247 template<class T, typename... Types>
248 void EnumerateConstructors ( const std::function<bool ( const StringId& ) >& aEnumerator )
249 {
251 }
252
254 template<class T, typename... Types>
255 std::vector<std::string> GetConstructorNames()
256 {
258 }
259}
Generic factory that registers and invokes named constructors for a given type.
Definition Factory.h:108
static std::unique_ptr< T > Construct(uint32_t aIdentifier, Types... args)
Constructs an object by its numeric identifier.
Definition Factory.h:116
static bool RegisterConstructor(const StringId &aIdentifier, const std::function< std::unique_ptr< T >(Types... args) > &aConstructor)
Registers a constructor function with the given identifier.
Definition Factory.h:141
std::tuple< StringId, std::function< std::unique_ptr< T >(Types... args) > > Constructor
Tuple pairing a StringId identifier with a constructor function.
Definition Factory.h:111
static std::unique_ptr< T > Construct(const std::string &aIdentifier, Types... args)
Constructs an object by its string identifier.
Definition Factory.h:133
static void EnumerateConstructors(const std::function< bool(const StringId &) > &aEnumerator)
Enumerates all registered constructors, calling the provided function for each.
Definition Factory.h:174
static bool UnregisterConstructor(const StringId &aIdentifier)
Unregisters the constructor with the given identifier.
Definition Factory.h:158
static std::vector< std::string > GetConstructorNames()
Returns the names of all registered constructors.
Definition Factory.h:186
CRC-based compile-time string identifier.
Definition StringId.hpp:31
constexpr uint32_t GetId() const
Get the CRC32 identifier.
Definition StringId.hpp:52
<- This is here just for the literals
Definition AABB.hpp:31
std::unique_ptr< T > Construct(uint32_t aIdentifier, Types... args)
Free function template that constructs an object by numeric identifier.
Definition Factory.h:213
bool RegisterConstructor(const StringId &aIdentifier, const std::function< std::unique_ptr< T >(Types... args) > &aConstructor)
Free function template that registers a constructor.
Definition Factory.h:234
std::vector< std::string > GetConstructorNames()
Free function template that returns all registered constructor names.
Definition Factory.h:255
uint32_t crc32i(const char *message, size_t size, uint32_t previous_crc)
Compute the CRC32 of a given message, continuing from a previous CRC value.
Definition CRC.cpp:27
void EnumerateConstructors(const std::function< bool(const StringId &) > &aEnumerator)
Free function template that enumerates all registered constructors.
Definition Factory.h:248
bool UnregisterConstructor(const StringId &aIdentifier)
Free function template that unregisters a constructor.
Definition Factory.h:241