Advertisement
eliasdaler

Meta-property system v 2.0

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