My module system design is trying to use typenames before their declaration. How can I design better module layout?

44 views Asked by At

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.

0

There are 0 answers