CORGI
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Groups Pages
entity_manager.h
Go to the documentation of this file.
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef CORGI_ENTITY_MANAGER_H_
16 #define CORGI_ENTITY_MANAGER_H_
17 
20 #include "corgi/entity.h"
21 #include "corgi/entity_common.h"
22 #include "corgi/vector_pool.h"
23 #include "corgi/version.h"
24 
25 namespace corgi {
26 
27 /// @file
28 /// @addtogroup corgi_entity_manager
29 /// @{
30 ///
31 /// @typedef EntityRef
32 ///
33 /// @brief This should be used as the primary way to reference an Entity.
34 ///
35 /// An EntityRef can be treated like a pointer to an Entity. In most cases,
36 /// it functions interchangeably with a normal pointer, but it also contains
37 /// extra functionality for determining if the EntityRef is invalid. For
38 /// instance, if the Entity that the EntityRef points to is deallocated, the
39 /// EntityRef will no longer be valid (even if new data exists in the same
40 /// memory location previously held by the deallocated Entity).
41 ///
42 /// EntityRefs are typically passed by reference or const reference. If an
43 /// EntityRef is const, then you can only access the underlying Entity data
44 /// in a read-only manner.
45 typedef VectorPool<Entity>::VectorPoolReference EntityRef;
46 
47 class EntityFactoryInterface;
48 class ComponentInterface;
49 
50 /// @class EntityManager
51 /// @brief The EntityManager is the code that manages all
52 /// Entities and Components in the game. Normally the game will
53 /// instantiate EntityManager, and then use it to create and control
54 /// all of its Entities.
55 ///
56 /// The main uses for this class are:
57 /// * Creating/destroying new Entities.
58 /// * Keeping track of all Components.
59 /// * Spawning and populating new Components from data.
60 /// * Updating Entities/Components. (Usually done once per frame.)
62  public:
63  /// @brief Constructor for the EntityManager.
64  EntityManager();
65 
66  /// @brief Returns the version of the Corgi entity library.
67  const CorgiVersion* GetCorgiVersion() { return version_; }
68 
69  /// @typedef EntityStorageContainer
70  ///
71  /// @brief This is used to track all Entities stored by the EntityManager.
73 
74  /// @brief Helper function for marshalling data from a Component.
75  ///
76  /// @tparam T The data type of the Component data to be returned.
77  ///
78  /// @param[in] entity The Entity associated with the desired data.
79  ///
80  /// @return Returns a pointer to the Component data, or returns
81  /// a nullptr if no such data exists.
82  template <typename T>
83  T* GetComponentData(const EntityRef& entity) {
84  return static_cast<T*>(
85  GetComponentDataAsVoid(entity, ComponentIdLookup<T>::component_id));
86  }
87 
88  /// @brief A helper function for marshalling data from a Component.
89  ///
90  /// @tparam T The data type of the Component data to be returned.
91  ///
92  /// @param[in] entity The Entity associated with the desired data.
93  ///
94  /// @return Returns a const pointer to the Component data, or returns
95  /// a nullptr if no such data exists.
96  template <typename T>
97  const T* GetComponentData(const EntityRef& entity) const {
98  return static_cast<const T*>(
99  GetComponentDataAsVoid(entity, ComponentIdLookup<T>::component_id));
100  }
101 
102  /// @brief A helper function for getting a particular Component, given
103  /// the Component's data type.
104  ///
105  /// @note Asserts if the Component does not exist.
106  ///
107  /// @tparam T The data type of the Component to be returned.
108  ///
109  /// @return Returns a pointer to the Component given its data type.
110  template <typename T>
112  ComponentId id =
114  assert(id != kInvalidComponent);
115  assert(id < components_.size());
116  return static_cast<T*>(components_[id]);
117  }
118 
119  /// @brief A helper function for getting a particular Component, given
120  /// the Component's data type.
121  ///
122  /// @note Asserts if the Component does not exist.
123  ///
124  /// @tparam T The data type of the Component to be returned.
125  ///
126  /// @return Returns a const pointer to the Component given its datatype.
127  template <typename T>
128  const T* GetComponent() const {
129  ComponentId id =
131  assert(id != kInvalidComponent);
132  assert(id < components_.size());
133  return static_cast<const T*>(components_[id]);
134  }
135 
136  /// @brief A helper function for adding a Component to an Entity, given
137  /// its data type.
138  ///
139  /// @note Asserts if the Component does not exist.
140  ///
141  /// @tparam T The data type of the Component that should have the Entity
142  /// added to it.
143  ///
144  /// @param[in] entity An EntityRef that points to the Entity that is being
145  /// added to the Component.
146  template <typename T>
148  ComponentId id =
150  assert(id != kInvalidComponent);
151  assert(id < components_.size());
152  AddEntityToComponent(entity, id);
153  }
154 
155  /// @brief A helper function for getting a particular Component, given the
156  /// component ID.
157  ///
158  /// @param[in] id The component ID for the desired Component.
159  ///
160  /// @note Asserts if the id is less than kMaxComponentCount.
161  ///
162  /// @return Returns a pointer to the Component at the given id, which
163  /// inherits from the ComponentInterface.
165  assert(id < components_.size());
166  return components_[id];
167  }
168 
169  /// @brief A helper function for getting a particular Component, given a
170  /// component ID.
171  ///
172  /// @param[in] id The component ID for the desired Component.
173  ///
174  /// @note Asserts if the id is less than kMaxComponentCount.
175  ///
176  /// @return Returns a const pointer to the Component at the given id,
177  /// which inherits from the ComponentInterface.
178  inline const ComponentInterface* GetComponent(ComponentId id) const {
179  assert(id < components_.size());
180  return components_[id];
181  }
182 
183  /// @brief Returns the number of components that have been registered
184  /// with the entity manager.
185  ///
186  /// @return The total number of components that are currently registered
187  /// with the entity manager.
188  inline size_t ComponentCount() const { return components_.size(); }
189 
190  /// @brief A helper function to get the component ID for a given Component.
191  ///
192  /// @tparam T The data type of the Component whose ID should be returned.
193  ///
194  /// @return Returns the component ID for a given Component.
195  template <typename T>
198  }
199 
200  /// @brief Allocates a new Entity (that is registered with no Components).
201  ///
202  /// @return Returns an EntityRef that points to the new Entity.
204 
205  /// @brief Deletes an Entity by removing it from the EntityManager's list and
206  /// clearing any Component data associated with it.
207  ///
208  /// @note Deletion is deferred until the end of the frame. If you want to
209  /// delete something instantly, use DeleteEntityImmediately.
210  ///
211  /// @param[in] entity An EntityRef that points to the Entity that will be
212  /// deleted at the end of the frame.
213  void DeleteEntity(EntityRef entity);
214 
215  /// @brief Instantly deletes an Entity.
216  ///
217  /// @note In general, you should use DeleteEntity (which defers deletion
218  /// until the end of the update cycle) unless you have a very good reason
219  /// for doing so.
220  ///
221  /// @param[in] entity An EntityRef that points to the Entity that will be
222  /// immediately deleted.
223  void DeleteEntityImmediately(EntityRef entity);
224 
225  /// @brief Registers a new Component with the EntityManager.
226  ///
227  /// @tparam T The data type of the Component that is being registered with the
228  /// EntityManager.
229  ///
230  /// @param[in] new_component A Component to be registered with to the
231  /// EntityManager.
232  ///
233  /// @note The new_component must inherit from the ComponentInterface.
234  ///
235  /// @return Returns the component ID for the new Component.
236  template <typename T>
237  ComponentId RegisterComponent(T* new_component) {
238  static_assert(std::is_base_of<ComponentInterface, T>::value,
239  "'new_component' must inherit from ComponentInterface");
240  ComponentId component_id = static_cast<ComponentId>(components_.size());
241  ComponentIdLookup<T>::component_id = component_id;
242  RegisterComponentHelper(new_component, component_id);
243  return component_id;
244  }
245 
246  /// @brief Removes all Components for an Entity, destroying any data
247  /// associated with it.
248  ///
249  /// @note Normally called by EntityManager prior to deleting an Entity.
250  ///
251  /// @param[in] entity An EntityRef that points to the Entity whose Components
252  /// should be removed.
253  void RemoveAllComponents(EntityRef entity);
254 
255  /// @brief Iterates through all the registered Components and causes them to
256  /// update.
257  ///
258  /// @param[in] delta_time A WorldTime that represents the timestep since
259  /// the last update.
260  void UpdateComponents(WorldTime delta_time);
261 
262  /// @brief Clears all data from all Components, empties the list
263  /// of Components themselves, and then empties the list of Entities.
264  /// This basically resets the EntityManager into its original state.
265  void Clear();
266 
267  /// @brief Returns an iterator to the beginning of the active Entities.
268  /// This is suitable for iterating over every active Entity.
269  ///
270  /// @return Returns a std::iterator to the first active Entity.
271  EntityStorageContainer::Iterator begin() { return entities_.begin(); }
272 
273  /// @brief Returns an iterator to the last of the active Entities.
274  ///
275  /// @return Returns a std::iterator to the last active Entity.
276  EntityStorageContainer::Iterator end() { return entities_.end(); }
277 
278  /// @brief Registers an instance of the EntityFactoryInterface as the
279  /// factory object to be used when Entities are created from arbitrary
280  /// data. The EntityFactory is responsible for parsing arbitrary data and
281  /// correctly transforming it into an Entity.
282  ///
283  /// @note This should be set before attempting to load Entities from data
284  /// files.
285  ///
286  /// @param[in] entity_factory A pointer to a class that inherits from the
287  /// EntityFactoryInterface, which will be registered with the
288  /// EntityManager.
290  entity_factory_ = entity_factory;
291  }
292 
293  /// @brief Creates an Entity from arbitrary data. This is normally invoked
294  /// only by classes that inherit from EntityFactoryInterface.
295  ///
296  /// Any class implementing CreateEntityFromData should establish the input
297  /// format for the 'data' and a way to parse that input 'data' into an Entity.
298  ///
299  /// @param[in] data A void pointer to the data to be used to create the
300  /// Entity.
301  ///
302  /// @return Returns an EntityRef that points to the newly created Entity.
303  EntityRef CreateEntityFromData(const void* data);
304 
305  /// @brief Registers an Entity with a Component. This causes the Component
306  /// to allocate data for the Entity and includes the Entity in that
307  /// Component's update routines.
308  ///
309  /// @param[in] entity An EntityRef that points to the Entity that should be
310  /// registered with the Component.
311  /// @param[in] component_id The component ID of the Component that should
312  /// be registered with the Entity.
313  void AddEntityToComponent(EntityRef entity, ComponentId component_id);
314 
315  /// @brief Deletes all the Entities that are marked for deletion.
316  ///
317  /// @warning Do NOT call this function during any form of Entity update!
318  void DeleteMarkedEntities();
319 
320  private:
321  /// @brief Handles the majority of the work for registering a Component (
322  /// aside from some of the template stuff). In particular, it verifies that
323  /// the request ID is not already in use, puts a pointer to the new Component
324  /// in our components_ array, sets the starting variables, and performs the
325  /// initialization on the Component.
326  ///
327  /// @param[in] new_component A pointer to a class that inherits from the
328  /// ComponentInterface, which will be registered with the component_id.
329  /// @param[in] component_id The component ID to register with the
330  /// new_component.
331  void RegisterComponentHelper(ComponentInterface* new_component,
332  ComponentId component_id);
333 
334  /// @brief Given a component ID and an Entity, returns all data associated
335  /// with that Entity from the given Component.
336  ///
337  /// @note This function will assert if the inputs are not valid. (e.g. The
338  /// Entity is no longer active, or the Component is invalid.)
339  ///
340  /// @param[in] entity The Entity associated with the desired data.
341  /// @param[in] component_id The component ID associated with the desired
342  /// data.
343  ///
344  /// @return Returns the data as a void pointer.
345  ///
346  /// @note The caller is expected to know how to interpret the data, since it
347  /// is returned as a void pointer. Typically a Component is registered with a
348  /// struct (or class) of Component data, however this function returns the
349  /// data as a void pointer, rather than a specific Component data type.
350  void* GetComponentDataAsVoid(EntityRef entity, ComponentId component_id);
351 
352  /// @brief Given a component ID and an Entity, returns all data associated
353  /// with that Entity from the given Component.
354  ///
355  /// @note This function will assert if the inputs are not valid. (e.g. The
356  /// Entity is no longer active, or the Component is invalid.)
357  ///
358  /// @param[in] entity The Entity associated with the desired data.
359  /// @param[in] component_id The component ID associated with the desired
360  /// data.
361  ///
362  /// @return Returns the data as a void pointer.
363  ///
364  /// @note The caller is expected to know how to interpret the data, since it
365  /// is returned as a void pointer. Typically a Component is registered with a
366  /// struct (or class) of Component data, however this function returns the
367  /// data as a void pointer, rather than a specific Component data type.
368  const void* GetComponentDataAsVoid(EntityRef entity,
369  ComponentId component_id) const;
370 
371  /// @var entities_
372  ///
373  /// @brief Storage for all the Entities currently tracked by the
374  /// EntityManager.
375  EntityStorageContainer entities_;
376 
377  /// @var components_
378  ///
379  /// @brief All the Components that are tracked by the system, and are
380  /// ready to have Entities added to them.
381  std::vector<ComponentInterface*> components_;
382 
383  /// @var entities_to_delete_
384  ///
385  /// @brief A list of all the Entities that we plan to delete at the end of the
386  /// frame.
387  ///
388  /// @note These entities are deleted by a call to DeleteMarkedEntities().
389  /// DeleteMarkedEntities should NOT be called called during any form of
390  /// Entity update.
391  std::vector<EntityRef> entities_to_delete_;
392 
393  /// @var entity_factory_
394  ///
395  /// @brief An EntityFactory used for spawning new Entities from data.
396  ///
397  /// @note Provided by the calling program.
398  EntityFactoryInterface* entity_factory_;
399 
400  // Current version of the Corgi Entity Library.
401  const CorgiVersion* version_;
402 };
403 
404 /// @class EntityFactoryInterface
405 ///
406 /// @brief An interface for an Entity factory, which creates Entities
407 /// for a given EntityManager.
409  public:
410  /// @brief A destructor of the entity factory interface.
412 
413  /// @brief Creates an Entity with a given EntityManager, registers it
414  /// with all Components specified, and populates the Component data.
415  ///
416  /// @param[in] data A void pointer to the data used to create
417  /// the new Entity.
418  /// @param[in] entity_manager A pointer to an EntityManager that
419  /// should create the Entity.
420  ///
421  /// @return Returns an EntityRef pointing to the newly created
422  /// Entity.
423  virtual EntityRef CreateEntityFromData(const void* data,
424  EntityManager* entity_manager) = 0;
425 };
426 /// @}
427 
428 } // corgi
429 
430 #endif // CORGI_ENTITY_MANAGER_H_
IteratorTemplate< false > Iterator
Definition: vector_pool.h:56
Iterator begin()
Get an Iterator to the first active element in the VectorPool.
Definition: vector_pool.h:642
EntityStorageContainer::Iterator end()
Returns an iterator to the last of the active Entities.
Definition: entity_manager.h:276
void DeleteEntityImmediately(EntityRef entity)
Instantly deletes an Entity.
void UpdateComponents(WorldTime delta_time)
Iterates through all the registered Components and causes them to update.
T * GetComponent()
A helper function for getting a particular Component, given the Component's data type.
Definition: entity_manager.h:111
A templated struct for holding type-dependent data.
Definition: component_id_lookup.h:36
void Clear()
Clears all data from all Components, empties the list of Components themselves, and then empties the ...
The EntityManager is the code that manages all Entities and Components in the game. Normally the game will instantiate EntityManager, and then use it to create and control all of its Entities.
Definition: entity_manager.h:61
EntityRef AllocateNewEntity()
Allocates a new Entity (that is registered with no Components).
VectorPool< Entity > EntityStorageContainer
This is used to track all Entities stored by the EntityManager.
Definition: entity_manager.h:72
int WorldTime
A typedef that represents time in the game.
Definition: entity_common.h:49
T * GetComponentData(const EntityRef &entity)
Helper function for marshalling data from a Component.
Definition: entity_manager.h:83
size_t ComponentCount() const
Returns the number of components that have been registered with the entity manager.
Definition: entity_manager.h:188
void DeleteMarkedEntities()
Deletes all the Entities that are marked for deletion.
void AddEntityToComponent(EntityRef entity)
A helper function for adding a Component to an Entity, given its data type.
Definition: entity_manager.h:147
const T * GetComponentData(const EntityRef &entity) const
A helper function for marshalling data from a Component.
Definition: entity_manager.h:97
const ComponentId kInvalidComponent
A sentinel value to represent an invalid Component.
Definition: entity_common.h:44
Iterator end()
Gets an Iterator to the last active element in the VectorPool.
Definition: vector_pool.h:650
VectorPool< corgi::Entity >::VectorPoolReference EntityRef
A typedef that should be used as the primary way to reference an Entity.
Definition: component_interface.h:49
void DeleteEntity(EntityRef entity)
Deletes an Entity by removing it from the EntityManager's list and clearing any Component data associ...
ComponentId GetComponentId()
A helper function to get the component ID for a given Component.
Definition: entity_manager.h:196
void set_entity_factory(EntityFactoryInterface *entity_factory)
Registers an instance of the EntityFactoryInterface as the factory object to be used when Entities ar...
Definition: entity_manager.h:289
EntityStorageContainer::Iterator begin()
Returns an iterator to the beginning of the active Entities. This is suitable for iterating over ever...
Definition: entity_manager.h:271
virtual EntityRef CreateEntityFromData(const void *data, EntityManager *entity_manager)=0
Creates an Entity with a given EntityManager, registers it with all Components specified, and populates the Component data.
A reference object for pointing into the vector pool. It acts as a pointer for vector pool elements a...
Definition: vector_pool.h:72
An interface for an Entity factory, which creates Entities for a given EntityManager.
Definition: entity_manager.h:408
const T * GetComponent() const
A helper function for getting a particular Component, given the Component's data type.
Definition: entity_manager.h:128
const ComponentInterface * GetComponent(ComponentId id) const
A helper function for getting a particular Component, given a component ID.
Definition: entity_manager.h:178
virtual ~EntityFactoryInterface()
A destructor of the entity factory interface.
Definition: entity_manager.h:411
EntityManager()
Constructor for the EntityManager.
void RemoveAllComponents(EntityRef entity)
Removes all Components for an Entity, destroying any data associated with it.
ComponentId RegisterComponent(T *new_component)
Registers a new Component with the EntityManager.
Definition: entity_manager.h:237
uint16_t ComponentId
This represents the ID of a Component.
Definition: entity_common.h:36
const CorgiVersion * GetCorgiVersion()
Returns the version of the Corgi entity library.
Definition: entity_manager.h:67
An interface that provides basic Component functionality. All Components will inherit from this class...
Definition: component_interface.h:57
ComponentInterface * GetComponent(ComponentId id)
A helper function for getting a particular Component, given the component ID.
Definition: entity_manager.h:164
EntityRef CreateEntityFromData(const void *data)
Creates an Entity from arbitrary data. This is normally invoked only by classes that inherit from Ent...