EasiestThe easiest solution would be to have a macro that takes other macros as argumentarguments:
// Allows GameObject to be spawnable through SpawnGameObject. No need to use this if the class is never spawned through the engine #define ENGINE_SPAWNABLE(CLASSNAME) \ class CLASSNAME; \ static bool CLASSNAME##Registered \ = (GameObjectFactory::GetInstance().GetGameObjectRegistry()[#CLASSNAME] = &GameObjectFactory::SpawnObject<CLASSNAME>, true) // Registers the class with the factory's registry, and connects that to a templated SpawnGameObject function // Spawns a class of selected name #define SpawnGameObject GameObjectFactory::GetInstance().SpawnGameObjectByName // Singleton game object factory class GameObjectFactory { public: // Gets instance of the simpleton static GameObjectFactory& GetInstance() { static GameObjectFactory Instance; return Instance; } // A templated function to spawn any registered GameObject template <typename TObject> static std::unique_ptr<Object> SpawnObject() { return std::make_unique<TObject>(); } // A factory function that spawns an object of the specified class name std::unique_ptr<Object> SpawnGameObjectByName(const std::string& Name); std::unordered_map<std::string, std::function<std::unique_ptr<Object>()>>& GetGameObjectRegistry(); // Returns the Registry of class names private: std::unordered_map<std::string, std::function<std::unique_ptr<Object>()>> Registry; // Registry that maps class names to factory functions }; The following compiles, however, results in Foo being unable ofto being spawned through the Factory, meaning this macro doesn't work.
ENGINE_CLASS(Foo, { ENGINE_SPAWNABLE }) : public GameObject { public: Foo() { printf("hey!"); } };