Dominik2000

Members
  • Content count

    58
  • Joined

  • Last visited

Community Reputation

279 Neutral

About Dominik2000

  • Rank
    Member
  1. Yes, sorry I mean EntityX. I ask if I could take this as reference, to get an imagination of what an ecs system has to do.
  2. What's with the EntityXY framework? I look at this, while implementing my framework, the system manager is greatly the same.   But my question to the post of crancran remains, could the message queue for moving the entities combined with an event manager which I need anyway?
  3. The first approach could be combined with an async messaging system, which I need anyway. Is this correct? This message queue is nothing else, or?
  4. In your first approch, do you mean that in this queue, there is a move entity position to ... entry, for the scene manager of irrlicht?   The second approch would be a special irrlicht wrapper system, which do all the things with the scene manager, and the irrlicht render system only do the update?   Thank you for clarifying.
  5. I use Irrlicht as graphic engine. The render system is not responsible for creating the entity but it must show the mesh on the screen, and so the render system has to create the entity in irrlicht. The movement system must change the position component, and the render system request the position and renders the entity. Maybe irrlicht is the problem...
  6. Hello,   sorry for writing so many ECS related topics, but as I'm programming, I come over more and more problems...   My architecture has an entity manager and a system manager, the entity manager manages all entities (entities are only ids), and every component has it's component pool which gives the component for the id back. The system manager has all systems (render system, audio system,...).   Then I have an additional class scene manager, which, for example, creates the scene in the beginning of the game. The scene manager routes all work to the render system, he told the render system to create an entity with the given mesh, on the given position and so on. And here I have my question, most of the articles say, that the movement system is a system. In my opinion, systems are low level classes, and managers (or how the will ever be named) are high level. The movement system moves my entities, that means, the movement system checks the velocity component and the position component of the entity, and moves the position of the entity by the given velocity, and told the render manager that the entity is moved. That means for me, that the movement system is not a system but a manager (it's high level, because it has nothing to do with the rendering of the entity).   Or should all systems knows the entity manager and the renderer checks all positions of the entities and moves them? But also then, the movement system is high level.   Is the ecs architecture combining high level and low level systems? This really is hard to solve for me, I know, that there is no given ECS way to go, but you have much more knowledge of this pattern I think.   Thank you! Dominik
  7. I have a simple entity manager with pointers to my component pools. My components are simple POC structs. My component pool is a template class.   Components: #ifndef COMPONENTS_H #define COMPONENTS_H #include "Datatypes/vector3.h" enum MESH_TYPE { STATIC_GROUND_MESH, ANIMATED_MESH }; typedef struct { Vector3 position; Vector3 rotation; } SpatialComponent; typedef struct { float farClipping; Vector3 target; } CameraComponent; typedef struct { MESH_TYPE type; std::string name; } MeshComponent; typedef struct { Vector3 translate; Vector3 rotate; } MovementComponent; #endif // COMPONENTS_H ComponentPool: #ifndef COMPONENTPOOL_H #define COMPONENTPOOL_H #include "components.h" #include "datatypes.h" #include <boost/container/flat_map.hpp> #include <algorithm> #include <vector> #include <iostream> #include <climits> #include <typeinfo> class ComponentPoolBase { }; template <typename T> class ComponentPool : public ComponentPoolBase, public boost::container::flat_map< EntityId, T > { typedef boost::container::flat_map< EntityId, T > Components_t; public: ComponentPool() { } T& Get(const EntityId& entityId) { return this->at(entityId); } int Size() { return this->size(); } bool Has(EntityId entityId) { typename Components_t::iterator itr = this->find(entityId); if(itr == this->end()) { return false; } return true; } bool Add(EntityId entityId) { try { this->insert(boost::container::container_detail::pair< EntityId, T >(entityId, T())); std::cout << "New component entity id: " << entityId << " Type: " << typeid(T).name() << std::endl; std::cout << "Count: " << this->size() << std::endl; return true; } catch (std::exception& ex) { std::cout << "Exception: " << ex.what() << std::endl; } return false; } bool Remove(EntityId entityId) { try { this[entityId] = NULL; std::cout << "Delete component entity id: " << entityId << " Type: " << typeid(T).name() << std::endl; return true; } catch (std::exception& ex) { std::cout << "Exception: " << ex.what() << std::endl; } return false; } }; #endif // COMPONENTPOOL_H EntityManager: #ifndef ENTITYMANAGER_H #define ENTITYMANAGER_H #include "Component/componentpool.h" #include "Component/components.h" #include "datatypes.h" #include <iostream> #include <queue> class EntityManager { typedef std::queue< EntityId > EntityList_t; public: EntityManager(); ~EntityManager(); void Init(); void Shutdown(); EntityId CreateEntity(const std::string& name); void DestroyEntity(EntityId entityId); EntityId GetCreatedEntities(); EntityId GetRemovedEntities(); ComponentPool<SpatialComponent>* m_pSpatialComponents; ComponentPool<CameraComponent>* m_pCameraComponents; ComponentPool<MeshComponent>* m_pMeshComponents; ComponentPool<MovementComponent>* m_pMovementComponents; private: EntityList_t* m_pCreatedEntities; EntityList_t* m_pRemovedEntities; EntityId getNextId() { return ++s_NextId; } static EntityId s_NextId; }; #endif // ENTITYMANAGER_H My great problem, are the pointers to the ComponentPool. I want to store this in a vector with unique pointer, because the entity manager is the only one, who is responsible for the lifetime of my entites and components.   I thought it should be this way: std::vector<std::unique_ptr<ComponentPool<ComponentPoolBase*>>> m_ComponentPools; And I add a unique pointer this way: m_ComponentPools.push_back(std::unique_ptr<ComponentPool<SpatialComponent>>(new ComponentPool<SpatialComponent>())); But this doesn't work with a not matching function error in the compiler. Why?   Is there a better solution to implement this component pool and entity manager?
  8. Pathfinding AI in an ECS game

    OK that seems logical and better, thank you I try to force every part of the game to ecs but that is not very good I think. Another question is, how to calculate such an navigation mesh? Based upon the description file of the entity?
  9. Hello,   when I have an ECS system, where the entities are only ids, the components PODs and the systems (in my case managers, because systems are low level) have all the logic. How can I implement Pathfinding. My thought is, that I have a component PathfindingComponent, where some points are defined, where the vehicle (as example) can drive. That means, if I have a straight street, I have 2 points, the begin and the end of the street piece, in my PathfindingComponent. If a street is added to the scene, my PathfindingManager will be notified, and see there is a component, and add the point from the component to his store. Now the AI comes in say, the vehicle have to drive to a specified street tile, and add a new waypoint (the entity id) to the WaypointComponent of the vehicle. The pathfinding now knows, where to drive an can look for a path. Is this ok? Are there any errors in my thinking?   One problem occurs I think: What if I have a street tile which has parking slots. One for a bus and 4 for cars. These 5 points are also in the pathfinding system, but now, the AI cannot say, drive to the street tile with the entity id, the AI have to say where exactly on the street tile. How can this be solved? Are the parking slots saved in an array in another component, or should the AI exactly say where to drive?   I hope it is clear, what I mean, if not, ask and I will try to describe it better.   Dominik
  10. I have a component based system. For camera I have a camera component (clipping range, ...) and a position component. There is a input sytem also, which converts the input to a key enum from my engine, and routes the input to the different key input handlers. For every action I have a handler. The handler checks in its queue, if a specific button is pressed (maybe with a modifier) and calls a function in a class through std::bind.   Now my question should I move the camera (edit position component) directly in the input system (input handler recognises W key -> MESSAGE::MOVE_CAMERA_FORWARD -> move function in input system will be called with MESSAGE::MOVE_CAMERA_FORWARD), or should this be a completly different system (movement system)? A movement system is responsible to move other entities too, so I need it anyway, or?   Thanks Dominik
  11. I don't know how I can get to the components from entity manager. I have to compare the type with the component pools type. But how? Sean means, that a base class for components is bad, they should be plain old data. Also in my component pool I have no componenttypeid or such things, so I can't cast to a fix component type.   Should I work with specialized templates? Or is there another better solution?
  12. I tried to create a packed array component pool with vectors and templates. The solution should be similar to Sean's posted article.   Is it too complicated, it's the first time, that I tried this? #ifndef COMPONENTPOOL_H #define COMPONENTPOOL_H #include "components.h" #include "datatypes.h" #include <algorithm> #include <vector> #include <iostream> #include <climits> struct Index { EntityId id; unsigned short index; }; template <typename T> class ComponentPool { public: ComponentPool() { m_NumObjects = 0; } ID Add(EntityId entityId, T component) { Index in; in.id = entityId; in.index = m_NumObjects++; m_Indexes.reserve(entityId); m_Indexes.insert(m_Indexes.begin() + entityId - 1, in); // -1 because entityId starts with 1 m_Components.push_back(component); std::cout << "New component entity id: " << in.id << " Type: " << typeid(T).name() << std::endl; return in.id; } void Remove(EntityId entityId) { Index &in = m_Indexes[entityId - 1]; // -1 because entityId starts with 1 Index swapIndex; for(std::vector< Index >::iterator itr = m_Indexes.begin(); itr != m_Indexes.end(); ++itr) { if((*itr).index == (m_NumObjects - 1)) { swapIndex = (*itr); break; } } T &component = m_Components[in.index]; component = m_Components[--m_NumObjects]; swapIndex.index = in.index; std::cout << "Delete component entity id: " << in.id << " Type: " << typeid(T).name() << std::endl; std::cout << "Remaining components: " << m_NumObjects << std::endl; in.id = 0; in.index = USHRT_MAX; } private: unsigned int m_NumObjects; std::vector< Index > m_Indexes; typedef std::vector< T > Components_t; Components_t m_Components; }; #endif // COMPONENTPOOL_H Then I have a components.h, with structs of all components: #ifndef COMPONENTS_H #define COMPONENTS_H typedef struct { float x; float y; float z; } PositionComponent; ... #endif // COMPONENTS_H Is this valid, is my implementation corrrect with the vectors?
  13. The goal was, to automatically create the components dependent of it's type. So I needed an vector, which stores all component pools.   Your solution needs a switch statement with all component types. I thought this is not very flexible because for all components I need to add a variable, and when I parsed my LUA script, I have to map the "PositionComponent" from Lua to the PositionComponent component pool.   Now I think, my prefered way, is much more difficult to handle, and I'm not sure if it's possible.
  14. Yeah you're right, it's not unflexible. But the system which needs the components, add the components to the entity manager in your case. I thought the entity manager should care about creating the entity with the components (getting it from lua which components are needed for the entity), and not the systems.
  15. But this is very unflexible or? For every component I need a getComponent method.