Skip to main content
Active reading. Fixed the question formation - missing auxiliary (or helping) verb - see e.g. <https://www.youtube.com/watch?v=t4yWEt0OSpg&t=1m49s> (see also <https://www.youtube.com/watch?v=kS5NfSzXfrI> (QUASM)) - alternatively, drop the question mark.
Source Link
Peter Mortensen
  • 31.4k
  • 22
  • 110
  • 134

How tocan I have macros as arguments inside macros?

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!"); } };   

How to have macros as arguments inside macros?

Easiest solution would be to have a macro that takes other macros as argument:

// 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 of being spawned through the Factory, meaning this macro doesn't work.

ENGINE_CLASS(Foo, { ENGINE_SPAWNABLE }) : public GameObject { public: Foo() { printf("hey!"); } };   

How can I have macros as arguments inside macros?

The easiest solution would be to have a macro that takes other macros as arguments:

// 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 to being spawned through the Factory, meaning this macro doesn't work.

ENGINE_CLASS(Foo, { ENGINE_SPAWNABLE }) : public GameObject { public: Foo() { printf("hey!"); } }; 
removed meta & social content, improved language, asked a question
Source Link
philipxy
  • 15.2k
  • 6
  • 44
  • 101

But it's not clear howHow can a macro can be placed inside of the ENGINE_CLASS macro.?

Any help would be appreciated.

But it's not clear how a macro can be placed inside of the ENGINE_CLASS macro.

Any help would be appreciated.

How can a macro be placed inside of the ENGINE_CLASS macro?

add more code
Source Link

Here is the GameObjectFactory, which has the SPAWNABLE macro, which allows the class to be spawned. It becomesis an easy test for whether this macro"macro inside macromacro" implementation works:

// 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 };  

Here is the SPAWNABLE macro, which allows the class to be spawned. It becomes an easy test for this macro inside macro implementation:

#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 

Here is the GameObjectFactory, which has the SPAWNABLE macro, which allows the class to be spawned. It is an easy test for whether this "macro inside macro" implementation works:

// 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 };  
fix spelling
Source Link
Loading
Source Link
Loading