aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Pensjö <lars.pensjo@gmail.com>2013-03-10 02:00:06 +0100
committerAlec Thomas <alec@swapoff.org>2013-03-10 13:06:41 -0400
commitb827494ca47b2e4331ce9eaa0745ce74655a3747 (patch)
tree3138e2f0822d6e791fbf687c7d585f926c0839b6
parent3068ee5a693d8191fc7aaa4fb0fc3b1220a004d2 (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.md22
-rw-r--r--entityx/Components_test.cc3
-rw-r--r--entityx/Entity.cc3
-rw-r--r--entityx/Entity.h15
-rw-r--r--entityx/Entity_test.cc26
5 files changed, 61 insertions, 8 deletions
diff --git a/README.md b/README.md
index 01da2c9..924fe1f 100644
--- 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.
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) {