Last active
December 17, 2015 19:09
-
-
Save alexesDev/5658257 to your computer and use it in GitHub Desktop.
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 <iostream> | |
| #include <boost/utility.hpp> | |
| #include <boost/type_traits.hpp> | |
| #include <boost/preprocessor/punctuation/comma_if.hpp> | |
| #include <boost/preprocessor/repetition/repeat.hpp> | |
| #define ENTITY_MAX_COMPONENT_COUNT 10 | |
| #define ENTITY_TYPENAMES(z, n, text) BOOST_PP_COMMA_IF(n) text##n | |
| #define ENTITY_DEFINE_COMPONENT(z, n, text) T##n text##n; | |
| #define ENTITY_DEFINE_ENTITY_SETTER(z, n, text) component##n.text(*this); | |
| #define ENTITY_DEFINE_COMPONENT_GETTER(z, n, text) \ | |
| template<class INNER_T> \ | |
| typename boost::enable_if<boost::is_base_of<T##n, INNER_T>, INNER_T>::type & text() \ | |
| { \ | |
| return component##n;\ | |
| } | |
| #define ENTITY_DECLARATION(z, n, text) \ | |
| template<BOOST_PP_REPEAT(n, ENTITY_TYPENAMES, class T)> \ | |
| class text<BOOST_PP_REPEAT(n, ENTITY_TYPENAMES, T)> : public Entity \ | |
| { \ | |
| BOOST_PP_REPEAT(n, ENTITY_DEFINE_COMPONENT, component)\ | |
| public: \ | |
| text(const std::string &name) : Entity(name) \ | |
| { \ | |
| BOOST_PP_REPEAT(n, ENTITY_DEFINE_ENTITY_SETTER, setEntity)\ | |
| } \ | |
| BOOST_PP_REPEAT(n, ENTITY_DEFINE_COMPONENT_GETTER, get) \ | |
| }; | |
| class Entity | |
| { | |
| std::string mName; | |
| public: | |
| Entity(const std::string &name) : mName(name) | |
| { | |
| } | |
| const std::string &getName() const | |
| { | |
| return mName; | |
| } | |
| }; | |
| template <typename ...Dummy> | |
| class SmartEntity; | |
| BOOST_PP_REPEAT(ENTITY_MAX_COMPONENT_COUNT, ENTITY_DECLARATION, SmartEntity) | |
| class Component | |
| { | |
| const Entity *mEntity; | |
| public: | |
| void setEntity(const Entity &value) | |
| { | |
| mEntity = &value; | |
| } | |
| const Entity &getEntity() | |
| { | |
| return *mEntity; | |
| } | |
| }; | |
| class Component1 : public Component | |
| { | |
| public: | |
| void some(){ std::cout << "Call Component1::some() of " << getEntity().getName() << std::endl; } | |
| }; | |
| class Component2 : public Component | |
| { | |
| public: | |
| void otherSome(){ std::cout << "Call Component2::some() of " << getEntity().getName() << std::endl; } | |
| }; | |
| int main() | |
| { | |
| SmartEntity<Component1, Component2> entity("Entity_with_2_components"); | |
| entity.get<Component1>().some(); | |
| entity.get<Component2>().otherSome(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment