From e231a289306fadcda13093d47587613600ec2d89 Mon Sep 17 00:00:00 2001 From: Zack Mulgrew Date: Mon, 29 Feb 2016 01:22:57 -0800 Subject: Allow Entity cloning via EntityManager::create_from_copy --- entityx/Entity.h | 22 ++++++++++++++++++++++ entityx/Entity_test.cc | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/entityx/Entity.h b/entityx/Entity.h index b55a45f..0f037b4 100644 --- a/entityx/Entity.h +++ b/entityx/Entity.h @@ -332,6 +332,7 @@ class BaseComponentHelper { public: virtual ~BaseComponentHelper() {} virtual void remove_component(Entity e) = 0; + virtual void copy_component_to(Entity source, Entity target) = 0; }; template @@ -340,6 +341,9 @@ public: void remove_component(Entity e) override { e.remove(); } + void copy_component_to(Entity source, Entity target) override { + target.assign_from_copy(*(source.component().get())); + } }; /** @@ -565,6 +569,24 @@ class EntityManager : entityx::help::NonCopyable { return entity; } + /** + * Create a new Entity by copying another. Copy-constructs each component. + * + * Emits EntityCreatedEvent. + */ + Entity create_from_copy(Entity original) { + assert(original.valid()); + auto clone = create(); + auto mask = original.component_mask(); + for (size_t i = 0; i < component_helpers_.size(); i++) { + BaseComponentHelper *helper = component_helpers_[i]; + if (helper && mask.test(i)) + helper->copy_component_to(original, clone); + } + return clone; + } + + /** * Destroy an existing Entity::Id and its associated Components. * diff --git a/entityx/Entity_test.cc b/entityx/Entity_test.cc index e07a567..9e75ee3 100644 --- a/entityx/Entity_test.cc +++ b/entityx/Entity_test.cc @@ -501,6 +501,25 @@ TEST_CASE_METHOD(EntityManagerFixture, "TestComponentAssignmentFromCopy") { REQUIRE(!copy); } +TEST_CASE_METHOD(EntityManagerFixture, "TestEntityCreateFromCopy") { + Entity a = em.create(); + a.assign(); + ComponentHandle original = a.component(); + ComponentHandle aPosition = a.assign(1, 2); + Entity b = em.create_from_copy(a); + ComponentHandle copy = b.component(); + ComponentHandle bPosition = b.component(); + REQUIRE(original); + REQUIRE(original->copied == false); + REQUIRE(copy); + REQUIRE(copy->copied == 1); + REQUIRE(aPosition->x == bPosition->x); + REQUIRE(aPosition->y == bPosition->y); + REQUIRE(aPosition.get() != bPosition.get()); + REQUIRE(a.component_mask() == b.component_mask()); + REQUIRE(a != b); +} + TEST_CASE_METHOD(EntityManagerFixture, "TestComponentHandleInvalidatedWhenComponentDestroyed") { Entity a = em.create(); ComponentHandle position = a.assign(1, 2); -- cgit v1.2.3