Created
January 20, 2014 20:21
-
-
Save remram44/8528304 to your computer and use it in GitHub Desktop.
Object registry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| CMAKE_MINIMUM_REQUIRED(VERSION 2.6) | |
| set(CMAKE_CXX_FLAGS "-g -Wall") | |
| PROJECT(mark_fields) | |
| # Sets up project-wide include dirs | |
| INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}") | |
| INCLUDE_DIRECTORIES("${PROJECT_BINARY_DIR}") | |
| # Builds proxychain tool | |
| ADD_EXECUTABLE(test main.cpp registered_object.cpp) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "registered_object.h" | |
| #include <iostream> | |
| #include <string> | |
| class MyObject : public RegisteredObject { | |
| protected: | |
| int x, y; | |
| std::string name; | |
| public: | |
| MyObject(int x_, int y_, const std::string &name_) | |
| : x(x_), y(y_), name(name_) | |
| { | |
| } | |
| BEGIN_FIELDS(MyObject); | |
| REGISTER_FIELD(x, "X coordinate"); | |
| REGISTER_FIELD(y, "Y coordinate"); | |
| REGISTER_FIELD(name, "Some meaningful name"); | |
| END_FIELDS(MyObject); | |
| }; | |
| REGISTER_OBJECT(MyObject); | |
| int main() | |
| { | |
| MyObject m(4, 2, "Hello"); | |
| print_fields(&m); | |
| print_classes(); | |
| std::cout << "meta gives: \"" << get_meta("MyObject")->getClassname() | |
| << "\"" << std::endl; | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "registered_object.h" | |
| #include <iostream> | |
| std::map<std::string, const MetaObject *(*)()> ObjectRegistrar::classes; | |
| ObjectRegistrar::ObjectRegistrar(const std::string &name, const MetaObject *(*gmo)()) | |
| { | |
| classes[name] = gmo; | |
| } | |
| void print_fields(const RegisteredObject *o) | |
| { | |
| const MetaObject *meta = o->getMetaObjectInst(); | |
| const std::vector<Field*> &fields = meta->getFields(); | |
| std::vector<Field*>::const_iterator it; | |
| std::cout << "Fields for " << meta->getClassname() << std::endl; | |
| for(it = fields.begin(); it != fields.end(); ++it) | |
| { | |
| Field &f = **it; | |
| std::cout << " " << f.name << " (" << f.description | |
| << "): " << f.getValue(o) << std::endl; | |
| } | |
| } | |
| void print_classes() | |
| { | |
| std::map<std::string, const MetaObject *(*)()>::const_iterator it; | |
| it = ObjectRegistrar::classes.begin(); | |
| std::cout << "Registered classes:" << std::endl; | |
| for(; it != ObjectRegistrar::classes.end(); ++it) | |
| std::cout << " " << it->first << std::endl; | |
| } | |
| const MetaObject *get_meta(const char *classname) | |
| { | |
| std::map<std::string, const MetaObject *(*)()>::const_iterator it; | |
| it = ObjectRegistrar::classes.find(classname); | |
| if(it != ObjectRegistrar::classes.end()) | |
| return it->second(); | |
| else | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef REGISTERED_OBJECT_H | |
| #define REGISTERED_OBJECT_H | |
| #include <map> | |
| #include <sstream> | |
| #include <vector> | |
| #define BEGIN_FIELDS(c) \ | |
| private: \ | |
| typedef c __Object_type; \ | |
| virtual const MetaObject *getMetaObjectInst() const \ | |
| { \ | |
| return c::getMetaObject(); \ | |
| } \ | |
| public: \ | |
| static const MetaObject *getMetaObject() \ | |
| { \ | |
| static MetaObject *i = 0; \ | |
| if(i == 0) \ | |
| { \ | |
| i = new MetaObject(#c) | |
| #define REGISTER_FIELD(f, descr) \ | |
| i->addField(#f, &__Object_type::f, descr) | |
| #define END_FIELDS(c) \ | |
| } \ | |
| return i; \ | |
| } \ | |
| private: \ | |
| typedef int __Object_dummy | |
| class RegisteredObject; | |
| class MetaObject; | |
| class ObjectRegistrar { | |
| public: | |
| static std::map<std::string, const MetaObject *(*)()> classes; | |
| public: | |
| ObjectRegistrar(const std::string &name, const MetaObject *(*gmo)()); | |
| }; | |
| #define REGISTER_OBJECT(c) ObjectRegistrar c##_reg(#c, &c::getMetaObject) | |
| class Field { | |
| public: | |
| const char *const name; | |
| const char *const description; | |
| virtual std::string getValue(const RegisteredObject *o) const = 0; | |
| protected: | |
| Field(const char *n, const char *d) | |
| : name(n), description(d) | |
| { | |
| } | |
| }; | |
| template<class C, typename T> | |
| class ActualField : public Field { | |
| private: | |
| T C::*ptr; | |
| public: | |
| ActualField(const char *n, const char *d, T C::*p) | |
| : Field(n, d), ptr(p) | |
| { | |
| } | |
| std::string getValue(const RegisteredObject *o) const | |
| { | |
| const C *c = static_cast<const C*>(o); | |
| std::ostringstream oss; | |
| oss << c->*ptr; | |
| return oss.str(); | |
| } | |
| }; | |
| class MetaObject { | |
| private: | |
| const char *const m_Classname; | |
| std::vector<Field*> m_Fields; | |
| public: | |
| MetaObject(const char *classname) | |
| : m_Classname(classname) | |
| { | |
| } | |
| template<class C, typename T> | |
| void addField(const char *name, T C::*ptr, const char *description) | |
| { | |
| m_Fields.push_back(new ActualField<C, T>(name, description, ptr)); | |
| } | |
| const char *const getClassname() const | |
| { | |
| return m_Classname; | |
| } | |
| const std::vector<Field*> &getFields() const | |
| { | |
| return m_Fields; | |
| } | |
| }; | |
| class RegisteredObject { | |
| public: | |
| virtual const MetaObject *getMetaObjectInst() const = 0; | |
| }; | |
| void print_fields(const RegisteredObject *o); | |
| void print_classes(); | |
| const MetaObject *get_meta(const char *classname); | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment