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