From b02261bd25a5fc307dd6b9f8fd0a87fb2d3d91f1 Mon Sep 17 00:00:00 2001 From: David Wicks Date: Mon, 2 Sep 2013 16:04:51 -0400 Subject: Added remove() method for removal of components by type. Along with this, there is a ComponentRemovedEvent that is delivered whenever a component is removed from an entity. --- entityx/Entity.h | 35 +++++++++++++++++++++++++++++++++++ entityx/Entity_test.cc | 20 ++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/entityx/Entity.h b/entityx/Entity.h index 8eee892..09cff22 100644 --- a/entityx/Entity.h +++ b/entityx/Entity.h @@ -113,6 +113,9 @@ public: template entityx::shared_ptr assign(Args && ... args); + template + entityx::shared_ptr remove(); + template entityx::shared_ptr component(); @@ -220,6 +223,17 @@ struct ComponentAddedEvent : public Event> { entityx::shared_ptr component; }; +/** + * Emitted when any component is removed from an entity. + */ +template +struct ComponentRemovedEvent : public Event> { + ComponentRemovedEvent(Entity entity, entityx::shared_ptr component) : + entity(entity), component(component) {} + + Entity entity; + entityx::shared_ptr component; +}; /** * Manages Entity::Id creation and component assignment. @@ -442,6 +456,21 @@ class EntityManager : public entityx::enable_shared_from_this, bo return assign(entity, entityx::make_shared(args ...)); } + /** + * Remove a Component from an Entity::Id + * + * Emits a ComponentRemovedEvent event. + */ + template + entityx::shared_ptr remove(Entity::Id id) { + entityx::shared_ptr component = entityx::static_pointer_cast(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>(Entity(shared_from_this(), id), component); + return component; + } + /** * Retrieve a Component assigned to an Entity::Id. * @@ -592,6 +621,12 @@ entityx::shared_ptr Entity::assign(Args && ... args) { return manager_.lock()->assign(id_, args ...); } +template +entityx::shared_ptr Entity::remove(){ + assert(valid() && component()); + return manager_.lock()->remove(id_); +} + template entityx::shared_ptr Entity::component() { assert(valid()); 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 { + void receive(const ComponentRemovedEvent &event) { + removed = event.component; + } + + entityx::shared_ptr removed; + }; + + ComponentRemovedReceiver receiver; + ev->subscribe>(receiver); + + ASSERT_FALSE(receiver.removed); + Entity e = em->create(); + e.assign(1.0, 2.0); + auto p = e.remove(); + ASSERT_EQ(receiver.removed, p); + ASSERT_FALSE(e.component()); +} + TEST_F(EntityManagerTest, TestEntityAssignment) { Entity a, b; a = em->create(); -- cgit v1.2.3