From dad637cdec9c24b34ad430aee0e55553d6ea238d Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Tue, 17 Dec 2013 23:46:43 -0500 Subject: Fix unpack and entities_with_components with > 2 args. --- entityx/Entity.h | 46 ++++++++++++++-------------------------------- entityx/Entity_test.cc | 45 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/entityx/Entity.h b/entityx/Entity.h index 6b37ed2..ba1822a 100644 --- a/entityx/Entity.h +++ b/entityx/Entity.h @@ -121,10 +121,8 @@ public: template ptr component(); - template - void unpack(ptr &a); - template - void unpack(ptr &a, ptr &b, Args && ... args); + template + void unpack(ptr &a, ptr & ... args); /** * Destroy and invalidate this Entity. @@ -347,7 +345,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this } template - View &unpack_to(ptr &a, ptr &b, Args && ... args) { + View &unpack_to(ptr &a, ptr &b, ptr & ... args) { unpack_to(a); return unpack_to(b, args ...); } @@ -515,27 +513,17 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this } /** - * Find Entities that have all of the specified Components. + * Find Entities that have all of the specified Components and assign them + * to the given parameters. */ template - View entities_with_components(ptr &c, Components && ... args) { + View entities_with_components(ptr &c, ptr & ... args) { auto mask = component_mask(c, args ...); return View(shared_from_this(), View::ComponentMaskPredicate(entity_component_mask_, mask)) .unpack_to(c, args ...); } - /** - * Unpack components directly into pointers. - * - * Components missing from the entity will be set to nullptr. - * - * Useful for fast bulk iterations. - * - * ptr p; - * ptr d; - * unpack(e, p, d); - */ template void unpack(Entity::Id id, ptr &a) { a = component(id); @@ -552,10 +540,10 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this * ptr d; * unpack(e, p, d); */ - template - void unpack(Entity::Id id, ptr &a, ptr &b, Args && ... args) { - unpack(id, a); - unpack(id, b, args ...); + template + void unpack(Entity::Id id, ptr &a, ptr & ... args) { + a = component(id); + unpack(id, args ...); } /** @@ -582,7 +570,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this } template - ComponentMask component_mask(const ptr &c1, const ptr &c2, Components && ... args) { + ComponentMask component_mask(const ptr &c1, const ptr &c2, ptr & ... args) { return component_mask(c1) | component_mask(c2, args...); } @@ -649,16 +637,10 @@ ptr Entity::component() { return manager_.lock()->component(id_); } -template -void Entity::unpack(ptr &a) { - assert(valid()); - manager_.lock()->unpack(id_, a); -} - -template -void Entity::unpack(ptr &a, ptr &b, Args && ... args) { +template +void Entity::unpack(ptr &a, ptr & ... args) { assert(valid()); - manager_.lock()->unpack(id_, a, b, args ...); + manager_.lock()->unpack(id_, a, args ...); } } // namespace entityx diff --git a/entityx/Entity_test.cc b/entityx/Entity_test.cc index 685a736..925b282 100644 --- a/entityx/Entity_test.cc +++ b/entityx/Entity_test.cc @@ -21,6 +21,7 @@ using namespace entityx; using std::ostream; using std::vector; +using std::string; template int size(const T &t) { @@ -61,6 +62,18 @@ ostream &operator << (ostream &out, const Direction &direction) { return out; } +struct Tag : Component { + explicit Tag(string tag) : tag(tag) {} + + bool operator == (const Tag &other) const { return tag == other.tag; } + + string tag; +}; + +ostream &operator << (ostream &out, const Tag &tag) { + out << "Tag(" << tag.tag << ")"; + return out; +} class EntityManagerTest : public ::testing::Test { protected: @@ -204,10 +217,14 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) { position_directions.push_back(std::make_pair( f.assign(7.0f, 8.0f), f.assign(9.0f, 10.0f))); + auto thetag = f.assign("tag"); g.assign(5.0f, 6.0f); int i = 0; + ptr position; + ASSERT_EQ(3, size(em->entities_with_components(position))); + ptr direction; for (auto unused_entity : em->entities_with_components(position, direction)) { (void)unused_entity; @@ -219,18 +236,40 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) { ++i; } ASSERT_EQ(2, i); + ptr tag; + i = 0; + for (auto unused_entity : em->entities_with_components(position, direction, tag)) { + (void)unused_entity; + ASSERT_TRUE(static_cast(position)); + ASSERT_TRUE(static_cast(direction)); + ASSERT_TRUE(static_cast(tag)); + auto pd = position_directions.at(1); + ASSERT_EQ(position, pd.first); + ASSERT_EQ(direction, pd.second); + ASSERT_EQ(tag, thetag); + i++; + } + ASSERT_EQ(1, i); } TEST_F(EntityManagerTest, TestUnpack) { Entity e = em->create(); - auto p = e.assign(); - auto d = e.assign(); + auto p = e.assign(1.0, 2.0); + auto d = e.assign(3.0, 4.0); + auto t = e.assign("tag"); ptr up; ptr ud; - e.unpack(up, ud); + ptr ut; + e.unpack(up); + ASSERT_EQ(p, up); + e.unpack(up, ud); + ASSERT_EQ(p, up); + ASSERT_EQ(d, ud); + e.unpack(up, ud, ut); ASSERT_EQ(p, up); ASSERT_EQ(d, ud); + ASSERT_EQ(t, ut); } // gcc 4.7.2 does not allow this struct to be declared locally inside the TEST_F. -- cgit v1.2.3