hx3d  1
2D/3D Simple Game Framework
engine.cpp
1 /*
2  Engine.
3  Copyright (C) 2015 Denis BOURGE
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
21 #include "hx3d/ecs/engine.hpp"
22 
23 namespace hx3d {
24 namespace ecs {
25 
26 Engine::Engine() {}
27 
29  Ptr<Entity> entity(Make<Entity>(lastEntityAvailable()));
30  _entities[entity->getId()] = entity;
31  _components[entity->getId()] = std::map<std::type_index, Ptr<Component>>();
32  _bits[entity->getId()] = Bitset();
33 
34  return entity;
35 }
36 
37 void Engine::registerEntity(const Ptr<Entity>& entity) {
38  if (entity->getId() != 0) {
39  Log.Error("Engine: entity `%d` already registered.", entity->getId());
40  return;
41  }
42 
43  entity->setId(lastEntityAvailable());
44  _entities[entity->getId()] = entity;
45  _components[entity->getId()] = std::map<std::type_index, Ptr<Component>>();
46  _bits[entity->getId()] = Bitset();
47 }
48 
49 void Engine::removeEntity(const Ptr<Entity>& entity) {
50  _toRemove.push_back(entity->getId());
51 }
52 
53 unsigned int Engine::getComponentSize(const Ptr<Entity>& entity) {
54  if (_components.find(entity->getId()) == _components.end()) {
55  Log.Error("No entity %ld", entity->getId());
56  return 0;
57  }
58 
59  const std::map<std::type_index, Ptr<Component>>& compMap = _components[entity->getId()];
60  return compMap.size();
61 }
62 
63 unsigned int Engine::getEntityCount() {
64  return _entities.size();
65 }
66 
67 unsigned int Engine::getBits(const Ptr<Entity>& entity) {
68  const unsigned int id = entity->getId();
69  return _bits[id].getBits();
70 }
71 
72 void Engine::update(const float delta) {
73  for (auto& id: _entities) {
74  for (auto& pair: _systems) {
75  const Ptr<System>& sys = pair.second;
76  if (sys->canProcess(_bits[id.first].getBits())) {
77  sys->process(id.second, delta);
78  }
79  }
80  }
81 
82  cleanEntities();
83 }
84 
85 void Engine::cleanEntities() {
86  for (const unsigned int i: _toRemove) {
87  removeComponents(i);
88 
89  _bits.erase(i);
90  _entities.erase(i);
91  }
92 
93  _toRemove.clear();
94 }
95 
96 unsigned int Engine::lastEntityAvailable() {
97  unsigned int first = 1;
98  for (auto& pair: _entities) {
99  if (pair.first != first)
100  break;
101 
102  ++first;
103  }
104 
105  return first;
106 }
107 
108 void Engine::removeComponents(const unsigned int entityId) {
109  if (_components.find(entityId) != _components.end()) {
110  while (_components[entityId].size() > 0) {
111  const auto& comp = *(_components[entityId].begin());
112 
113  if (_onComponentRemoved.find(comp.first) != _onComponentRemoved.end()) {
114  _onComponentRemoved[comp.first](comp.second, _entities[entityId]);
115  }
116 
117  _components[entityId].erase(comp.first);
118  }
119  }
120 }
121 
123  for (auto& entity: _entities) {
124  removeComponents(entity.first);
125  }
126 
127  _components.clear();
128  _bits.clear();
129  _toRemove.clear();
130  _entities.clear();
131 
132  _systems.clear();
133 
134  _onComponentAdded.clear();
135  _onComponentRemoved.clear();
136 }
137 
138 } /* ecs */
139 } /* hx3d */
hx3d framework namespace
Definition: audio.hpp:26
void clear()
Remove everything from the engine.
Definition: engine.cpp:122
void Error(const std::string fmt,...)
Write an error message.
Definition: log.cpp:72
void update(const float delta)
Update the engine.
Definition: engine.cpp:72
static hx3d::LogImpl Log
Current log implementation.
Definition: log.hpp:91
Bitset helper in an unsigned int.
Definition: bitset.hpp:32
Ptr< Entity > createEntity()
Create a new entity with the last entity id available.
Definition: engine.cpp:28
void removeEntity(const Ptr< Entity > &entity)
Mark the entity for deletion from the engine.
Definition: engine.cpp:49
unsigned int getComponentSize(const Ptr< Entity > &entity)
Get the number of components for an entity.
Definition: engine.cpp:53
unsigned int getEntityCount()
Get the number of entities.
Definition: engine.cpp:63
unsigned int getBits(const Ptr< Entity > &entity)
Get the bits corresponding to the entity components.
Definition: engine.cpp:67
std::shared_ptr< T > Ptr
Quick-typing shared ptr.
Definition: ptr.hpp:34
void registerEntity(const Ptr< Entity > &entity)
Affect an ID to a uninitialized entity.
Definition: engine.cpp:37