]> code.bitgloo.com Git - clyne/entityx.git/commitdiff
Added remove<C>() method for removal of components by type.
authorDavid Wicks <wicks.db@gmail.com>
Mon, 2 Sep 2013 20:04:51 +0000 (16:04 -0400)
committerAlec Thomas <alec@swapoff.org>
Tue, 3 Sep 2013 01:46:40 +0000 (21:46 -0400)
Along with this, there is a ComponentRemovedEvent<T> that is
delivered whenever a component is removed from an entity.

entityx/Entity.h
entityx/Entity_test.cc

index 8eee892c3c383ebaa4a7422abad4c51cf61f7b24..09cff223e91d22c266aa26b7917e452eeab24384 100644 (file)
@@ -113,6 +113,9 @@ public:
   template <typename C, typename ... Args>
   entityx::shared_ptr<C> assign(Args && ... args);
 
+  template <typename C>
+  entityx::shared_ptr<C> remove();
+
   template <typename C>
   entityx::shared_ptr<C> component();
 
@@ -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.
@@ -442,6 +456,21 @@ class EntityManager : public entityx::enable_shared_from_this<EntityManager>, bo
     return assign<C>(entity, entityx::make_shared<C>(args ...));
   }
 
+  /**
+   * 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.
    *
@@ -592,6 +621,12 @@ entityx::shared_ptr<C> Entity::assign(Args && ... args) {
   return manager_.lock()->assign<C>(id_, 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());
index b779873e371880a24306232ff880224985cdb7cf..e207adedaf2559487bc0ea4978fee250a2ced805 100644 (file)
@@ -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();