23#include "aeongames/StringId.hpp"
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();
38#define FactoryImplementation(X) \
39 std::unique_ptr<X> Construct##X ( uint32_t aIdentifier )\
41 return Factory<X>::Construct ( aIdentifier ); \
43 std::unique_ptr<X> Construct##X ( const std::string& aIdentifier )\
45 return Factory<X>::Construct ( aIdentifier ); \
47 std::unique_ptr<X> Construct##X ( const StringId& aIdentifier )\
49 return Factory<X>::Construct ( aIdentifier.GetId() ); \
51 bool Register##X##Constructor ( const StringId& aIdentifier, const std::function<std::unique_ptr<X>() >& aConstructor ) \
53 return Factory<X>::RegisterConstructor ( aIdentifier, aConstructor );\
55 bool Unregister##X##Constructor ( const StringId& aIdentifier )\
57 return Factory<X>::UnregisterConstructor ( aIdentifier );\
59 void Enumerate##X##Constructors ( const std::function<bool ( const StringId& ) >& aEnumerator )\
61 Factory<X>::EnumerateConstructors ( aEnumerator );\
63 std::vector<std::string> Get##X##ConstructorNames()\
65 return Factory<X>::GetConstructorNames();\
71#define FactoryImplementation1Arg(X,Y) \
72 std::unique_ptr<X> Construct##X ( uint32_t aIdentifier, Y ARG )\
74 return Factory<X,Y>::Construct ( aIdentifier, ARG ); \
76 std::unique_ptr<X> Construct##X ( const std::string& aIdentifier, Y ARG )\
78 return Factory<X,Y>::Construct ( aIdentifier, ARG ); \
80 std::unique_ptr<X> Construct##X ( const StringId& aIdentifier, Y ARG )\
82 return Factory<X,Y>::Construct ( aIdentifier.GetId(), ARG ); \
84 bool Register##X##Constructor ( const StringId& aIdentifier, const std::function<std::unique_ptr<X>(Y) >& aConstructor ) \
86 return Factory<X,Y>::RegisterConstructor ( aIdentifier, aConstructor );\
88 bool Unregister##X##Constructor ( const StringId& aIdentifier )\
90 return Factory<X,Y>::UnregisterConstructor ( aIdentifier );\
92 void Enumerate##X##Constructors ( const std::function<bool ( const StringId& ) >& aEnumerator )\
94 Factory<X,Y>::EnumerateConstructors ( aEnumerator );\
96 std::vector<std::string> Get##X##ConstructorNames()\
98 return Factory<X,Y>::GetConstructorNames();\
106 template<
class T,
typename... Types>
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 )
118 auto it = std::find_if ( Constructors.begin(), Constructors.end(),
121 return aIdentifier == std::get<0> ( aConstructor );
123 if ( it != Constructors.end() )
125 return std::get<1> ( *it ) ( args... );
133 static std::unique_ptr<T>
Construct (
const std::string& aIdentifier, Types... args )
135 return Construct (
crc32i ( aIdentifier.data(), aIdentifier.size() ), args... );
143 auto it = std::find_if ( Constructors.begin(), Constructors.end(),
146 return aIdentifier == std::get<0> ( aConstructor );
148 if ( it == Constructors.end() )
150 Constructors.emplace_back ( aIdentifier, aConstructor );
160 auto it = std::find_if ( Constructors.begin(), Constructors.end(),
163 return aIdentifier == std::get<0> ( aConstructor );
165 if ( it != Constructors.end() )
167 Constructors.erase ( it );
176 for (
auto& i : Constructors )
178 if ( !aEnumerator ( std::get<0> ( i ) ) )
188 std::vector<std::string> names{Constructors.size() };
189 std::transform ( Constructors.begin(), Constructors.end(), names.begin(),
192 return std::get<0> ( constructor ).GetString();
199 static std::vector < Constructor > Constructors;
202 template<
class T,
typename... Types>
203 std::vector<
typename Factory<T, Types...>::Constructor> Factory<T, Types...>::Constructors;
212 template<
class T,
typename... Types>
213 std::unique_ptr<T>
Construct ( uint32_t aIdentifier, Types... args )
219 template<
class T,
typename... Types>
220 std::unique_ptr<T>
Construct (
const std::string& aIdentifier, Types... args )
226 template<
class T,
typename... Types>
233 template<
class T,
typename... Types>
240 template<
class T,
typename... Types>
247 template<
class T,
typename... Types>
254 template<
class T,
typename... Types>
Generic factory that registers and invokes named constructors for a given type.
static std::unique_ptr< T > Construct(uint32_t aIdentifier, Types... args)
Constructs an object by its numeric identifier.
static bool RegisterConstructor(const StringId &aIdentifier, const std::function< std::unique_ptr< T >(Types... args) > &aConstructor)
Registers a constructor function with the given identifier.
std::tuple< StringId, std::function< std::unique_ptr< T >(Types... args) > > Constructor
Tuple pairing a StringId identifier with a constructor function.
static std::unique_ptr< T > Construct(const std::string &aIdentifier, Types... args)
Constructs an object by its string identifier.
static void EnumerateConstructors(const std::function< bool(const StringId &) > &aEnumerator)
Enumerates all registered constructors, calling the provided function for each.
static bool UnregisterConstructor(const StringId &aIdentifier)
Unregisters the constructor with the given identifier.
static std::vector< std::string > GetConstructorNames()
Returns the names of all registered constructors.
CRC-based compile-time string identifier.
constexpr uint32_t GetId() const
Get the CRC32 identifier.
<- This is here just for the literals
std::unique_ptr< T > Construct(uint32_t aIdentifier, Types... args)
Free function template that constructs an object by numeric identifier.
bool RegisterConstructor(const StringId &aIdentifier, const std::function< std::unique_ptr< T >(Types... args) > &aConstructor)
Free function template that registers a constructor.
std::vector< std::string > GetConstructorNames()
Free function template that returns all registered constructor names.
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.
void EnumerateConstructors(const std::function< bool(const StringId &) > &aEnumerator)
Free function template that enumerates all registered constructors.
bool UnregisterConstructor(const StringId &aIdentifier)
Free function template that unregisters a constructor.