aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Wicks <wicks.db@gmail.com>2013-09-02 16:04:51 -0400
committerAlec Thomas <alec@swapoff.org>2013-09-02 21:46:40 -0400
commitb02261bd25a5fc307dd6b9f8fd0a87fb2d3d91f1 (patch)
treeb91bfaa68a50ea5fe0a94a0a18fb9efb4ce4f602
parenta557458977abe907fec3f241071f339a1999012d (diff)
Added remove<C>() method for removal of components by type.
Along with this, there is a ComponentRemovedEvent<T> that is delivered whenever a component is removed from an entity.
-rw-r--r--entityx/Entity.h35
-rw-r--r--entityx/Entity_test.cc20
2 files changed, 55 insertions, 0 deletions
diff --git a/entityx/Entity.h b/entityx/Entity.h
index 8eee892..09cff22 100644
--- a/entityx/Entity.h
+++ b/entityx/Entity.h
@@ -114,6 +114,9 @@ public:
entityx::shared_ptr<C> assign(Args && ... args);
template <typename C>
+ entityx::shared_ptr<C> remove();
+
+ template <typename C>
entityx::shared_ptr<C> component();
template <typename A>
@@ -220,6 +223,17 @@ struct ComponentAddedEvent : public Event<ComponentAddedEvent<T>> {
entityx::shared_ptr<T> component;
};
+/**
+ * Emitted when any component is removed from an entity.
+ */
+template <typename T>
+struct ComponentRemovedEvent : public Event<ComponentRemovedEvent<T>> {
+ ComponentRemovedEvent(Entity entity, entityx::shared_ptr<T> component) :
+ entity(entity), component(component) {}
+
+ Entity entity;
+ entityx::shared_ptr<T> component;
+};
/**
* Manages Entity::Id creation and component assignment.
@@ -443,6 +457,21 @@ class EntityManager : public entityx::enable_shared_from_this<EntityManager>, bo
}
/**
+ * Remove a Component from an Entity::Id
+ *
+ * Emits a ComponentRemovedEvent<C> event.
+ */
+ template <typename C>
+ entityx::shared_ptr<C> remove(Entity::Id id) {
+ entityx::shared_ptr<C> component = entityx::static_pointer_cast<C>(entity_components_.at(C::family()).at(id.index()));
+ entity_components_.at(C::family()).at(id.index()).reset();
+ entity_component_mask_.at(id.index()) &= ~(uint64_t(1) << C::family());
+ if (component)
+ event_manager_->emit<ComponentRemovedEvent<C>>(Entity(shared_from_this(), id), component);
+ return component;
+ }
+
+ /**
* Retrieve a Component assigned to an Entity::Id.
*
* @returns Component instance, or empty shared_ptr<> if the Entity::Id does not have that Component.
@@ -593,6 +622,12 @@ entityx::shared_ptr<C> Entity::assign(Args && ... args) {
}
template <typename C>
+entityx::shared_ptr<C> Entity::remove(){
+ assert(valid() && component<C>());
+ return manager_.lock()->remove<C>(id_);
+}
+
+template <typename C>
entityx::shared_ptr<C> Entity::component() {
assert(valid());
return manager_.lock()->component<C>(id_);
diff --git a/entityx/Entity_test.cc b/entityx/Entity_test.cc
index b779873..e207ade 100644
--- a/entityx/Entity_test.cc
+++ b/entityx/Entity_test.cc
@@ -335,6 +335,26 @@ TEST_F(EntityManagerTest, TestComponentAddedEvent) {
ASSERT_EQ(10, receiver.direction_events);
}
+TEST_F(EntityManagerTest, TestComponentRemovedEvent) {
+ struct ComponentRemovedReceiver : public Receiver<ComponentRemovedReceiver> {
+ void receive(const ComponentRemovedEvent<Direction> &event) {
+ removed = event.component;
+ }
+
+ entityx::shared_ptr<Direction> removed;
+ };
+
+ ComponentRemovedReceiver receiver;
+ ev->subscribe<ComponentRemovedEvent<Direction>>(receiver);
+
+ ASSERT_FALSE(receiver.removed);
+ Entity e = em->create();
+ e.assign<Direction>(1.0, 2.0);
+ auto p = e.remove<Direction>();
+ ASSERT_EQ(receiver.removed, p);
+ ASSERT_FALSE(e.component<Direction>());
+}
+
TEST_F(EntityManagerTest, TestEntityAssignment) {
Entity a, b;
a = em->create();