Skip to content

Instantly share code, notes, and snippets.

@alexesDev
Last active December 17, 2015 19:09
Show Gist options
  • Select an option

  • Save alexesDev/5658257 to your computer and use it in GitHub Desktop.

Select an option

Save alexesDev/5658257 to your computer and use it in GitHub Desktop.
#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