diff options
author | Lars Pensjö <lars.pensjo@gmail.com> | 2013-03-10 02:00:06 +0100 |
---|---|---|
committer | Alec Thomas <alec@swapoff.org> | 2013-03-10 13:06:41 -0400 |
commit | b827494ca47b2e4331ce9eaa0745ce74655a3747 (patch) | |
tree | 3138e2f0822d6e791fbf687c7d585f926c0839b6 | |
parent | 3068ee5a693d8191fc7aaa4fb0fc3b1220a004d2 (diff) |
Two bugfixes in Entity.
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.
-rw-r--r-- | README.md | 22 | ||||
-rw-r--r-- | entityx/Components_test.cc | 3 | ||||
-rw-r--r-- | entityx/Entity.cc | 3 | ||||
-rw-r--r-- | entityx/Entity.h | 15 | ||||
-rw-r--r-- | entityx/Entity_test.cc | 26 |
5 files changed, 61 insertions, 8 deletions
@@ -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. diff --git a/entityx/Components_test.cc b/entityx/Components_test.cc index 8fe05ec..8c4d210 100644 --- a/entityx/Components_test.cc +++ b/entityx/Components_test.cc @@ -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; } diff --git a/entityx/Entity.cc b/entityx/Entity.cc index 41fbb4c..a17813f 100644 --- a/entityx/Entity.cc +++ b/entityx/Entity.cc @@ -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; } diff --git a/entityx/Entity.h b/entityx/Entity.h index 0116a22..f5028b0 100644 --- a/entityx/Entity.h +++ b/entityx/Entity.h @@ -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; }; diff --git a/entityx/Entity_test.cc b/entityx/Entity_test.cc index cc3d11f..36a607b 100644 --- a/entityx/Entity_test.cc +++ b/entityx/Entity_test.cc @@ -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) { |