Преглед изворни кода

Fixing prototype_factory to work.

Sam Jaffe пре 7 година
родитељ
комит
6c3bb22bbe
1 измењених фајлова са 36 додато и 17 уклоњено
  1. 36 17
      prototype_factory.hpp

+ 36 - 17
prototype_factory.hpp

@@ -8,6 +8,7 @@
 #pragma once
 
 #include <functional>
+#include <string>
 #include <unordered_map>
 
 /*
@@ -37,25 +38,43 @@
  *
  * class Widget { ... };
  * class Button : public Widget { ... };
- * using WidgetGenerator = prototype_factory<std::unique_ptr<Widget>, ...>;
+ * using WidgetGenerator = objects::prototype::factory<std::unique_ptr<Widget>, ...>;
  * WidgetGenerator::bind("Button",
  *                       [](...) { return std::make_unique<Button>(...); });
  */
-template <typename Base, typename... Args>
-class prototype_factory {
-public:
-  using rval_t = Base;
-  using producer = std::function<rval_t(Args &&...)>;
-  
-  static rval_t get(std::string const & type_id, Args &&... args) {
-    auto it = _factories.find(type_id);
-    if (it == _factories.end()) { return rval_t(); }
-    else { return (it->second)(std::forward<Args>(args)...); }
+namespace objects { namespace prototype {
+  template <typename Base, typename... Args>
+  class factory {
+  public:
+    using rval_t = Base;
+    using producer = std::function<rval_t(Args &&...)>;
+    
+    static factory & instance();
+    
+    rval_t get(std::string const & type_id, Args &&... args) {
+      auto it = _factories.find(type_id);
+      if (it == _factories.end()) { return rval_t(); }
+      else { return (it->second)(std::forward<Args>(args)...); }
+    }
+    
+    bool bind(std::string const & type_id, producer p) {
+      return _factories.insert(std::make_pair(type_id, p)).second;
+    }
+  private:
+    factory() = default;
+    std::unordered_map<std::string, producer> _factories;
+  };
+} }
+
+#define INSTANTIATE_PROTOTYPE_FACTORY(...) \
+  template <> ::objects::prototype::factory<__VA_ARGS__> & \
+  ::objects::prototype::factory<__VA_ARGS__>::instance() { \
+    static ::objects::prototype::factory<__VA_ARGS__> _instance; \
+    return _instance; \
   }
-  
-  static bool bind(std::string const & type_id, producer p) {
-    return _factories.insert(std::make_pair(type_id, p)).second;
+
+#define INSTANTIATE_PROTOTYPE_FACTORY_2(Typedef) \
+  template <> Typedef & Typedef::instance() { \
+    static Typedef _instance; \
+    return _instance; \
   }
-private:
-  static std::unordered_map<std::string, producer> _factories;
-};