]> code.bitgloo.com Git - clyne/entityx.git/commitdiff
Two bugfixes in Entity.
authorLars Pensjö <lars.pensjo@gmail.com>
Sun, 10 Mar 2013 01:00:06 +0000 (02:00 +0100)
committerAlec Thomas <alec@swapoff.org>
Sun, 10 Mar 2013 17:06:41 +0000 (13:06 -0400)
Fix Entity::operator! and initialize Entity::id_ to invalid value by
default.

Add test to verify operator! and uninitialized Entity.
Suppress warnings about unused variables.

README.md
entityx/Components_test.cc
entityx/Entity.cc
entityx/Entity.h
entityx/Entity_test.cc

index 01da2c915de257a5fcf015930235d07e32b699c5..924fe1f8dc2071dbf58c20dcf2728a9d227af630 100644 (file)
--- a/README.md
+++ b/README.md
@@ -26,9 +26,23 @@ EntityManager entities;
 Entity entity = entities.create();
 ```
 
+And destroying an entity is done with:
+
+```c++
+entities.destroy(entity);
+```
+
+#### Testing for destroyed entities
+
+The Entity type can be seen as a safe pointer.
+Test if it is valid with `entity.exists()`.
+
 ### Components (entity data)
 
-Components are typically [POD types](http://en.wikipedia.org/wiki/Plain_Old_Data_Structures) containing self-contained sets of related data. Implementations are [curiously recurring template pattern](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) (CRTP) subclasses of `Component<T>`.
+Components are typically [POD types](http://en.wikipedia.org/wiki/Plain_Old_Data_Structures) containing self-contained sets of related data.Implementations are [curiously recurring template pattern](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) (CRTP) subclasses of `Component<T>`.
+The idea with ECS is to not have any functionality in the component.
+Components must provide a no-argument constructor.
+The current implementation can handle up to 64 components in total.
 
 #### Creating components
 
@@ -107,8 +121,9 @@ struct MovementSystem : public System<MovementSystem> {
 ### Events (communicating between systems)
 
 Events are objects emitted by systems, typically when some condition is met. Listeners subscribe to an event type and will receive a callback for each event object emitted. An ``EventManager`` coordinates subscription and delivery of events between subscribers and emitters. Typically subscribers will be other systems, but need not be.
+Events are not part of the original ECS pattern, but they are an efficient alternative to component flags for sending infrequent data.
 
-As an example, we might want to implement a very basic collision system using our ``Position` data from above.
+As an example, we might want to implement a very basic collision system using our ``Position`` data from above.
 
 #### Creating event types
 
@@ -168,6 +183,8 @@ DebugCollisions debug_collisions;
 events.subscribe<Collision>(debug_collisions);
 ```
 
+There can be more than one subscriber for an event; each one will be called.
+
 ### Manager (tying it all together)
 
 Managing systems, components and entities can be streamlined by subclassing `Manager`. It is not necessary, but it provides callbacks for configuring systems, initializing entities, and so on.
@@ -209,6 +226,7 @@ EntityX has the following build and runtime requirements:
 - [GTest](http://code.google.com/p/googletest/) (needed for testing only)
 
 **Note:** GTest is no longer installable directly through Homebrew. You can use [this formula](https://raw.github.com/mxcl/homebrew/2bf506e3d90254f81a669a0216f33b2f09589028/Library/Formula/gtest.rb) to install it manually.
+For Debian Linux, install libgtest-dev and then see /usr/share/doc/libgtest-dev/README.Debian.
 
 Once these dependencies are installed you should be able to build and install EntityX as follows. BUILD_TESTING is false by default.
 
index 8fe05ec32e9ef77062e310990b5d3e3a104ec970..8c4d210062a1c5d80a3172dcbc911a7dafeaeaf4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution.
- * 
+ *
  * Author: Alec Thomas <alec@swapoff.org>
  */
 
@@ -24,6 +24,7 @@ int size(const T &t) {
   int n = 0;
   for (auto i : t) {
     ++n;
+    (void)i; // Unused on purpose, suppress warning
   }
   return n;
 }
index 41fbb4cedee6961ac3a6e24f7a1afecaf5d5446f..a17813fd15130245f50c5476e8cd283a2cdaa989 100644 (file)
@@ -13,6 +13,8 @@
 
 namespace entityx {
 
+const Entity::Id Entity::INVALID = Entity::Id(-1);
+
 BaseComponent::Family BaseComponent::family_counter_ = 0;
 
 bool Entity::exists() const {
@@ -20,6 +22,7 @@ bool Entity::exists() const {
 }
 
 void Entity::detach() {
+  id_ = INVALID;
   entities_ = nullptr;
 }
 
index 0116a22e3c0c204194d489faf7f48d24c3c5dbc2..f5028b074fa696f6c013a2817bcae927e958e2c4 100644 (file)
@@ -39,13 +39,18 @@ class Entity {
  public:
   typedef uint64_t Id;
 
-  Entity(): entities_(nullptr) {}
+  /**
+   * Id of an invalid Entity.
+   */
+  static const Id INVALID;
+
+  Entity() {}
 
   /**
    * Alias for exists().
    */
   bool operator ! () const {
-    return exists();
+    return !exists();
   }
 
   bool operator == (const Entity &other) const {
@@ -57,7 +62,7 @@ class Entity {
   }
 
   /**
-   * Detach entity from the EntityManager.
+   * Detach Entity handle from the EntityManager.
    */
   void detach();
 
@@ -85,8 +90,8 @@ class Entity {
 
   Entity(EntityManager *entities, Entity::Id id) : entities_(entities), id_(id) {}
 
-  EntityManager *entities_;
-  Entity::Id id_;
+  EntityManager *entities_ = nullptr;
+  Entity::Id id_ = INVALID;
 };
 
 
index cc3d11f6b419a96ff8de904480b8bdad00ee9fa1..36a607b619ddcbc65ac59b4b8a8ff3bae82bf535 100644 (file)
@@ -28,6 +28,7 @@ int size(const T &t) {
   int n = 0;
   for (auto i : t) {
     ++n;
+    (void)i; // Unused on purpose, suppress warning
   }
   return n;
 }
@@ -76,9 +77,34 @@ class EntityManagerTest : public ::testing::Test {
 
 TEST_F(EntityManagerTest, TestCreateEntity) {
   ASSERT_TRUE(em.size() == 0);
+
+  Entity e2;
+  ASSERT_FALSE(e2.exists());
+  ASSERT_FALSE(em.exists(e2));
+
   Entity e = em.create();
+  ASSERT_TRUE(e.exists());
   ASSERT_TRUE(em.exists(e));
   ASSERT_TRUE(em.size() == 1);
+
+  e2 = e;
+  ASSERT_TRUE(e2.exists());
+  ASSERT_TRUE(em.exists(e2));
+}
+
+TEST_F(EntityManagerTest, TestEntityAsBoolean) {
+  ASSERT_TRUE(em.size() == 0);
+  Entity e = em.create();
+  ASSERT_TRUE(em.exists(e));
+  ASSERT_TRUE(em.size() == 1);
+  ASSERT_FALSE(!e);
+
+  em.destroy(e);
+
+  ASSERT_TRUE(!e);
+
+  Entity e2; // Not initialized
+  ASSERT_TRUE(!e2);
 }
 
 TEST_F(EntityManagerTest, TestEntityReuse) {