Advertisement
eliasdaler

Simple meta-property system

Dec 15th, 2015
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <functional>
  3. #include <memory>
  4. #include <unordered_map>
  5.  
  6. template<typename T> using GetterFunc_t = std::function<T()>;
  7. template<typename T> using SetterFunc_t = std::function<void(const T&)>;
  8.  
  9. class IProperty {
  10. public:
  11.     virtual ~IProperty() {}
  12. };
  13.  
  14. template <typename T>
  15. class Property : public IProperty {
  16. public:
  17.     Property(const GetterFunc_t<T>& getter, const SetterFunc_t<T>& setter) :
  18.         getter(getter),
  19.         setter(setter)
  20.     { }
  21.  
  22.     T get()
  23.     {
  24.         return getter();
  25.     }
  26.  
  27.     void set(const T& value)
  28.     {
  29.         setter(value);
  30.     }
  31. private:
  32.     GetterFunc_t<T> getter;
  33.     SetterFunc_t<T> setter;
  34. };
  35.  
  36. class MetaObject {
  37. public:
  38.     template<typename T>
  39.     void meta_register(const std::string& propertyName, T& propertyRef)
  40.     {
  41.         GetterFunc_t<T> getter = [&propertyRef]() -> T { return propertyRef; };
  42.         SetterFunc_t<T> setter = [&propertyRef](const T& newValue) { propertyRef = newValue; };
  43.         properties[propertyName] = std::make_unique<Property<T>>(getter, setter);
  44.     }
  45.  
  46.     template<typename T>
  47.     T getProperty(const std::string& propertyName)
  48.     {
  49.         auto property = findProperty<T>(propertyName);
  50.         if (property) {
  51.             return property->get();
  52.         }
  53.         return T();
  54.     }
  55.  
  56.     template <typename T>
  57.     void setProperty(const std::string& propertyName, const T& value)
  58.     {
  59.         auto property = findProperty<T>(propertyName);
  60.         if (property) {
  61.             property->set(value);
  62.         }
  63.     }
  64.  
  65. private:
  66.     template <typename T>
  67.     Property<T>* findProperty(const std::string& propertyName)
  68.     {
  69.         auto it = properties.find(propertyName);
  70.         if (it != properties.end()) {
  71.             auto concreteProperty = dynamic_cast<Property<T>*>(it->second.get());
  72.             return concreteProperty;
  73.         }
  74.         return nullptr;
  75.     }
  76.  
  77.     std::unordered_map<std::string, std::unique_ptr<IProperty>> properties;
  78. };
  79.  
  80. // EXAMPLE CLASS
  81.  
  82. class Animation : public MetaObject
  83. {
  84. public:
  85.     Animation()
  86.     {
  87.         meta_register("name", name);
  88.         meta_register("isLooped", isLooped);
  89.         meta_register("frameCount", frameCount);
  90.     }
  91. private:
  92.     std::string name;
  93.     bool isLooped;
  94.     int frameCount;
  95. };
  96.  
  97. int main()
  98. {
  99.     Animation a;
  100.  
  101.     // and now I can do this!
  102.  
  103.     a.setProperty("name", std::string("walk"));
  104.     a.setProperty("isLooped", true);
  105.     a.setProperty("frameCount", 100);
  106.  
  107.     std::cout << "Name = "  << a.getProperty<std::string>("name") << std::endl;
  108.     std::cout << "isLooped = "  << a.getProperty<bool>("isLooped") << std::endl;
  109.     std::cout << "frameCount = " << a.getProperty<int>("frameCount") << std::endl;
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement