Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template<typename T, typename Class> using GetterFunc_t = std::function<T(const Class&)>;
- template<typename T, typename Class> using SetterFunc_t = std::function<void(Class&, const T&)>;
- class IProperty {
- public:
- virtual ~IProperty() {};
- };
- template <typename T, typename Class>
- class Property : public IProperty {
- public:
- Property(const GetterFunc_t<T, Class>& getter, const SetterFunc_t<T, Class>& setter) :
- getter(getter),
- setter(setter)
- {
- }
- T get(const Class& obj)
- {
- return getter(obj);
- }
- void set(Class& obj, const T& value)
- {
- setter(obj, value);
- }
- private:
- GetterFunc_t<T, Class> getter;
- SetterFunc_t<T, Class> setter;
- };
- template <typename Class>
- class MetaObject {
- public:
- template<typename T>
- void addProperty(const std::string& propertyName, T (Class::*propertyPtr))
- {
- GetterFunc_t<T, Class> getter = [propertyPtr](const Class& obj) -> T { return obj.*propertyPtr; };
- SetterFunc_t<T, Class> setter = [propertyPtr] (Class& obj, const T& newValue) { obj.*propertyPtr = newValue; };
- properties[propertyName] = std::make_unique<Property<T, Class>>(getter, setter);
- }
- template<typename T>
- T getProperty(const Class& obj, const std::string& propertyName)
- {
- auto property = findProperty<T>(propertyName);
- if (property) {
- return property->get(obj);
- }
- return T();
- }
- template <typename T>
- void setProperty(Class& obj, const std::string& propertyName, const T& value)
- {
- auto property = findProperty<T>(propertyName);
- if (property) {
- property->set(obj, value);
- }
- }
- private:
- template <typename T>
- Property<T, Class>* findProperty(const std::string& propertyName)
- {
- auto it = properties.find(propertyName);
- if (it != properties.end()) {
- return getConcreteProperty<T>(it->second.get());
- }
- return nullptr;
- }
- template <typename T>
- Property<T, Class>* getConcreteProperty(IProperty* property)
- {
- return dynamic_cast<Property<T, Class>*>(property);
- }
- std::unordered_map<std::string, std::unique_ptr<IProperty>> properties;
- };
- class Animation
- {
- public:
- static void registerClass(MetaObject<Animation>& metaA)
- {
- metaA.addProperty("name", &Animation::name);
- metaA.addProperty("isLooped", &Animation::isLooped);
- metaA.addProperty("frameCount", &Animation::frameCount);
- }
- private:
- std::string name;
- bool isLooped;
- int frameCount;
- FloatRect frame;
- };
- int main()
- {
- MetaObject<Animation> metaA;
- Animation::registerClass(metaA);
- Animation a;
- metaA.setProperty(a, "name", std::string("walk"));
- metaA.setProperty(a, "isLooped", false);
- metaA.setProperty(a, "frameCount", 10);
- std::cout << "Name = " << metaA.getProperty<std::string>(a, "name") << std::endl;
- std::cout << "isLooped = " << metaA.getProperty<bool>(a, "isLooped") << std::endl;
- std::cout << "frameCount = " << metaA.getProperty<int>(a, "frameCount") << std::endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement