diff options
author | David Wicks <wicks.db@gmail.com> | 2013-09-02 16:04:51 -0400 |
---|---|---|
committer | Alec Thomas <alec@swapoff.org> | 2013-09-02 21:46:40 -0400 |
commit | b02261bd25a5fc307dd6b9f8fd0a87fb2d3d91f1 (patch) | |
tree | b91bfaa68a50ea5fe0a94a0a18fb9efb4ce4f602 | |
parent | a557458977abe907fec3f241071f339a1999012d (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.h | 35 | ||||
-rw-r--r-- | entityx/Entity_test.cc | 20 |
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(); |