fork download
  1. #include <iostream>
  2. // component regitry
  3. #include <unordered_map>
  4. #include <functional>
  5. #include <memory>
  6.  
  7. #define DEBUG_COMPONENT_CREATION(X)
  8.  
  9. #include <cstdint> // for std::uint64_t
  10. #include <random>
  11.  
  12. template <typename T>
  13. class CGUID_t
  14. {
  15. public:
  16. typedef T TGuidValueType;
  17. constexpr static T INVALID_GUID = -1;
  18.  
  19. CGUID_t() : value(Generate()) {}
  20.  
  21. //CGUID(T value_) : value(value_) {}
  22. bool IsValid() const { return value != INVALID_GUID; }
  23. T GetValue() const { return value; }
  24.  
  25. static T Generate()
  26. {
  27. std::random_device rd; //Will be used to obtain a seed for the random number engine
  28. std::mt19937 generator(rd()); //Standard mersenne_twister_engine seeded with rd()
  29. std::uniform_int_distribution<T> distribution(static_cast<T>(1), static_cast<T>(-1));
  30. return distribution(generator);
  31. }
  32.  
  33. private:
  34. T value;
  35. };
  36.  
  37. typedef CGUID_t<std::uint64_t> CGUID;
  38.  
  39. struct IComponent
  40. {
  41. IComponent()
  42. {
  43. DEBUG_COMPONENT_CREATION(uid);
  44. }
  45.  
  46. virtual ~IComponent() {};
  47.  
  48. virtual void Update() = 0;
  49. virtual void Init() = 0;
  50. virtual void Shutdown() = 0;
  51. virtual void RegisterForUpdate() = 0;
  52.  
  53. CGUID GetGUID() const { return guid; }
  54.  
  55. private:
  56. CGUID guid;
  57. };
  58.  
  59. #undef DEBUG_COMPONENT_CREATION
  60.  
  61. struct STEST
  62. {
  63. STEST()
  64. {
  65. std::cout << "[Info] STEST" << std::endl;
  66.  
  67. }
  68. ~STEST()
  69. {
  70. std::cout << "[Info] ~STEST" << std::endl;
  71.  
  72. }
  73. };
  74.  
  75. template <class PRODUCT_PTR = IComponent>
  76. class CComponentFactory
  77. {
  78. public:
  79. CComponentFactory()
  80. {
  81. std::cout << "[Info] CComponentFactory" << std::endl;
  82. }
  83. static void Register(const std::string id, std::function<PRODUCT_PTR*()> funCreate)
  84. {
  85. // uses pair's converting move constructor
  86. // auto const res = GetMap().emplace(std::make_pair(id, pComponent));
  87.  
  88. #if 1
  89. auto search = GetMap().find(id);
  90. if(search == GetMap().end()) {
  91. std::cout << "[Info] Registered Component " << id << std::endl;
  92. GetMap()[id] = funCreate;
  93. }
  94. else {
  95. std::cout << "[Warning] CComponentFactory::Register: Component " << id << " already registered!!" << std::endl;
  96. }
  97.  
  98. #else
  99. // auto const res = std::pair<std::string,bool>("a",false); //GetMap().emplace(id, pComponent);
  100. auto aa = std::pair<std::string, const PRODUCT_PTR*>(id, pComponent);
  101. auto const res = GetMap().emplace(aa);
  102. // auto const res = GetMap().emplace(id, pComponent);
  103. if (!res.second)
  104. {
  105. // insertion failed
  106. std::cout << "[Warning] CComponentFactory::Register: Component " << id << " already registered!!" << std::endl;
  107. }
  108. #endif
  109. }
  110.  
  111. static std::unique_ptr<PRODUCT_PTR> Construct(const std::string& id)
  112. {
  113. auto search = GetMap().find(id);
  114. if(search != GetMap().end()) {
  115. std::cout << "[Info] Constructed Component " << search->first << std::endl;
  116. return std::unique_ptr<PRODUCT_PTR>(search->second());
  117. }
  118. else {
  119. std::cout << "[Warning] Failed to Construct Component " << id << std::endl;
  120. return std::unique_ptr<PRODUCT_PTR>(nullptr);
  121. }
  122. }
  123.  
  124. private:
  125. using TComponentFactoryMap = std::unordered_map<std::string, std::function<PRODUCT_PTR*()>>;
  126.  
  127. static TComponentFactoryMap& GetMap() {
  128. static TComponentFactoryMap s_map; // NOTE: GETS CONSTRUCTED TWICE!!! once befor main() and once in main()
  129. static STEST s_stest;
  130. static int i = 0;
  131. std::cout << "[Info] i: " << i++ << " addr: " << &i << std::endl;
  132. return s_map;
  133. }
  134. };
  135.  
  136. class RenderComponent : public IComponent
  137. {
  138. public:
  139.  
  140. RenderComponent()
  141. {
  142. std::cout << "Creating componenet with GUID: " << GetGUID().GetValue() << std::endl;
  143. }
  144.  
  145. virtual ~RenderComponent() override
  146. {
  147. std::cout << "Destroying componenet with GUID: " << GetGUID().GetValue() << std::endl;
  148. }
  149.  
  150. virtual void Init() override {};
  151. virtual void Update() override {};
  152. virtual void Shutdown() override {};
  153. virtual void RegisterForUpdate() override {};
  154.  
  155. };
  156.  
  157. template <class TEST_TYPE_PTR>
  158. class CRegister_RenderComponent
  159. {
  160. public:
  161. CRegister_RenderComponent()
  162. {
  163. CComponentFactory<TEST_TYPE_PTR>::Register(std::string("RenderComponent"), []() { return new TEST_TYPE_PTR;});
  164. }
  165. };
  166. static CRegister_RenderComponent<RenderComponent> s_CRegister_RenderComponent;
  167. static CRegister_RenderComponent<RenderComponent> s_CRegister_RenderComponent2;
  168.  
  169. bool test_icomponent()
  170. {
  171.  
  172. RenderComponent rc;
  173. bool bValid = rc.GetGUID().IsValid();
  174.  
  175. std::cout << "componenet with GUID: " << rc.GetGUID().GetValue() << " is " << (bValid ? "Valid" : "Invalid") << std::endl;
  176.  
  177. if (auto uPtr = CComponentFactory<IComponent>::Construct("RenderComponent")) {
  178. std::cout << "Construted component " << (uPtr->GetGUID().GetValue()) << std::endl;
  179. }
  180.  
  181. return true;
  182. }
  183.  
  184. int main()
  185. {
  186. test_icomponent();
  187. return 0;
  188. }
Success #stdin #stdout 0s 15256KB
stdin
Standard input is empty
stdout
[Info] STEST
[Info] i: 0 addr: 0x2b624a64a254
[Info] i: 1 addr: 0x2b624a64a254
[Info] Registered Component RenderComponent
[Info] i: 2 addr: 0x2b624a64a254
[Info] i: 3 addr: 0x2b624a64a254
[Info] i: 4 addr: 0x2b624a64a254
[Warning] CComponentFactory::Register: Component RenderComponent already registered!!
Creating componenet with GUID: 8888140488541529660
componenet with GUID: 8888140488541529660 is Valid
[Info] STEST
[Info] i: 0 addr: 0x2b624a64a2b8
[Info] i: 1 addr: 0x2b624a64a2b8
[Warning] Failed to Construct Component RenderComponent
Destroying componenet with GUID: 8888140488541529660
[Info] ~STEST
[Info] ~STEST