I'm trying to create module system for my game engine, but I have encountered a problem. There are two classes Module and ModuleFactory. ModuleFactory class stores Module class and all it's components. I want the Module class to be able to specify what parameters it needs to be registered, but you can't use typenames before they have been defined.
ModuleFactory class:
template<typename Base, typename TCreateValue, typename ... Args>
class ModuleFactory {
public:
using TRegistryMap = std::unordered_map<TypeId, TCreateValue>;
static TRegistryMap &ModuleRegistry() {
static TRegistryMap registry;
return registry;
}
template<typename T>
class Registry : public Base {
public:
static T* Get() {
return moduleInstance;
}
protected:
static bool Register(Args ... args) {
ModuleFactory::Registry()[TypeInfo<Base>::template GetTypeId<T>()] = {[]() {
moduleInstance = new T();
return std::unique_ptr<Base>(moduleInstance);
}, args...};
return true;
};
inline static T *moduleInstance = nullptr;
};
};
Module class:
class Module : public ModuleFactory<Module, Module::TCreateValue, Module::Stage> {
//You can't use TCreateValue and Stage before their declaration, so this throws error.
public:
enum class Stage : uint8_t {
Never, Always, Pre, Tick, Post, Render
};
class TCreateValue {
public:
std::function<std::unique_ptr<Module>()> create;
Stage stage;
};
};
Just SomeClass:
class SomeClass : public Module::Registry<SomeClass> {
inline static bool Registered = Register(Stage::Always);
};
As I said before I want the Module class to be able to set what parameters it needs for it's registartion. Any ideas on how can I solve this problem or redesign my module layout and still achieve the same goal. Only idea I have is to move TCreateValue and Stage outside of Module class, but I don't want to have mess in my code.