Last active
December 17, 2015 19:09
-
-
Save alexesDev/5658641 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/function.hpp> | |
| #include <boost/utility.hpp> | |
| #include <boost/type_traits.hpp> | |
| #include <boost/preprocessor/punctuation/comma_if.hpp> | |
| #include <boost/preprocessor/repetition/repeat.hpp> | |
| typedef float Real; | |
| typedef std::string String; | |
| #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 BaseEntity \ | |
| { \ | |
| BOOST_PP_REPEAT(n, ENTITY_DEFINE_COMPONENT, component)\ | |
| public: \ | |
| text(BaseEntity *parent) : BaseEntity(parent) \ | |
| { \ | |
| BOOST_PP_REPEAT(n, ENTITY_DEFINE_ENTITY_SETTER, setEntity)\ | |
| } \ | |
| BOOST_PP_REPEAT(n, ENTITY_DEFINE_COMPONENT_GETTER, get) \ | |
| }; | |
| class BaseEntity | |
| { | |
| BaseEntity *mParent; | |
| public: | |
| BaseEntity(BaseEntity *parent) : mParent(parent) | |
| { | |
| } | |
| const BaseEntity &getParent() | |
| { | |
| return *mParent; | |
| } | |
| }; | |
| template <typename ...Dummy> | |
| class Entity; | |
| BOOST_PP_REPEAT(ENTITY_MAX_COMPONENT_COUNT, ENTITY_DECLARATION, Entity) | |
| class RenderEngine | |
| { | |
| }; | |
| class OgreRenderEngine : public RenderEngine | |
| { | |
| }; | |
| class Scene : public BaseEntity | |
| { | |
| RenderEngine *mRenderEngine; | |
| public: | |
| Scene(RenderEngine *renderEngine) : BaseEntity(nullptr), mRenderEngine(renderEngine) | |
| { | |
| } | |
| void show() | |
| { | |
| } | |
| void hide() | |
| { | |
| } | |
| }; | |
| class Component | |
| { | |
| BaseEntity *mEntity; | |
| public: | |
| void setEntity(BaseEntity &value) | |
| { | |
| mEntity = &value; | |
| } | |
| const BaseEntity &getEntity() | |
| { | |
| return *mEntity; | |
| } | |
| }; | |
| class Transforms : public Component | |
| { | |
| public: | |
| Transforms &setPosition(Real x, Real y, Real z) | |
| { | |
| return *this; | |
| } | |
| Transforms &setScale(Real x, Real y, Real z) | |
| { | |
| return *this; | |
| } | |
| Transforms &setOrientation(Real w, Real x, Real y, Real z) | |
| { | |
| return *this; | |
| } | |
| }; | |
| class MeshRenderer : public Component | |
| { | |
| public: | |
| MeshRenderer &setName(const String &value) | |
| { | |
| return *this; | |
| } | |
| MeshRenderer &setMaterialName(const String &value) | |
| { | |
| return *this; | |
| } | |
| }; | |
| class Script : public Component | |
| { | |
| public: | |
| Script &setName(const String &value) | |
| { | |
| return *this; | |
| } | |
| }; | |
| class Camera : public Component | |
| { | |
| public: | |
| Camera &setPosition(Real x, Real y, Real z) | |
| { | |
| return *this; | |
| } | |
| Camera &lookAt(Real x, Real y, Real z) | |
| { | |
| return *this; | |
| } | |
| }; | |
| class CubeController : public Script | |
| { | |
| public: | |
| CubeController() : Script() | |
| { | |
| setName("cube_controller.as"); | |
| } | |
| }; | |
| class CubeEntity : public Entity<Transforms, MeshRenderer, CubeController> | |
| { | |
| public: | |
| CubeEntity(BaseEntity *parent) : Entity(parent) | |
| { | |
| get<MeshRenderer>() | |
| .setName("cube.mesh") | |
| .setMaterialName("Bricks"); | |
| } | |
| }; | |
| int main() | |
| { | |
| OgreRenderEngine renderEngine; | |
| Scene scene(&renderEngine); | |
| Entity<Camera> camera(&scene); | |
| camera.get<Camera>() | |
| .setPosition(50, 50, 50) | |
| .lookAt(0, 0, 0); | |
| for(int i = 0; i < 10; ++i) | |
| { | |
| CubeEntity cube(&scene); | |
| cube.get<Transforms>() | |
| .setPosition(i * 2, 0, 0) | |
| .setOrientation(1, 0.5, 0, 0); | |
| } | |
| scene.show(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment