aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlec Thomas <alec@swapoff.org>2013-12-17 23:46:43 -0500
committerAlec Thomas <alec@swapoff.org>2013-12-17 23:46:57 -0500
commitdad637cdec9c24b34ad430aee0e55553d6ea238d (patch)
tree1d7d768ee4edc83fa911ce3d05b2253508f76907
parent1da4ce174ab1585c2ad6a9a4c5c7a8b2e3d91991 (diff)
Fix unpack and entities_with_components with > 2 args.
-rw-r--r--entityx/Entity.h46
-rw-r--r--entityx/Entity_test.cc45
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 <typename C>
ptr<C> component();
- template <typename A>
- void unpack(ptr<A> &a);
- template <typename A, typename B, typename ... Args>
- void unpack(ptr<A> &a, ptr<B> &b, Args && ... args);
+ template <typename A, typename ... Args>
+ void unpack(ptr<A> &a, ptr<Args> & ... args);
/**
* Destroy and invalidate this Entity.
@@ -347,7 +345,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
}
template <typename A, typename B, typename ... Args>
- View &unpack_to(ptr<A> &a, ptr<B> &b, Args && ... args) {
+ View &unpack_to(ptr<A> &a, ptr<B> &b, ptr<Args> & ... args) {
unpack_to<A>(a);
return unpack_to<B, Args ...>(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 <typename C, typename ... Components>
- View entities_with_components(ptr<C> &c, Components && ... args) {
+ View entities_with_components(ptr<C> &c, ptr<Components> & ... 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<Position> p;
- * ptr<Direction> d;
- * unpack<Position, Direction>(e, p, d);
- */
template <typename A>
void unpack(Entity::Id id, ptr<A> &a) {
a = component<A>(id);
@@ -552,10 +540,10 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
* ptr<Direction> d;
* unpack<Position, Direction>(e, p, d);
*/
- template <typename A, typename B, typename ... Args>
- void unpack(Entity::Id id, ptr<A> &a, ptr<B> &b, Args && ... args) {
- unpack<A>(id, a);
- unpack<B, Args ...>(id, b, args ...);
+ template <typename A, typename ... Args>
+ void unpack(Entity::Id id, ptr<A> &a, ptr<Args> & ... args) {
+ a = component<A>(id);
+ unpack<Args ...>(id, args ...);
}
/**
@@ -582,7 +570,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
}
template <typename C1, typename C2, typename ... Components>
- ComponentMask component_mask(const ptr<C1> &c1, const ptr<C2> &c2, Components && ... args) {
+ ComponentMask component_mask(const ptr<C1> &c1, const ptr<C2> &c2, ptr<Components> & ... args) {
return component_mask<C1>(c1) | component_mask<C2, Components ...>(c2, args...);
}
@@ -649,16 +637,10 @@ ptr<C> Entity::component() {
return manager_.lock()->component<C>(id_);
}
-template <typename A>
-void Entity::unpack(ptr<A> &a) {
- assert(valid());
- manager_.lock()->unpack(id_, a);
-}
-
-template <typename A, typename B, typename ... Args>
-void Entity::unpack(ptr<A> &a, ptr<B> &b, Args && ... args) {
+template <typename A, typename ... Args>
+void Entity::unpack(ptr<A> &a, ptr<Args> & ... 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 <typename T>
int size(const T &t) {
@@ -61,6 +62,18 @@ ostream &operator << (ostream &out, const Direction &direction) {
return out;
}
+struct Tag : Component<Tag> {
+ 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<Position>(7.0f, 8.0f),
f.assign<Direction>(9.0f, 10.0f)));
+ auto thetag = f.assign<Tag>("tag");
g.assign<Position>(5.0f, 6.0f);
int i = 0;
+
ptr<Position> position;
+ ASSERT_EQ(3, size(em->entities_with_components(position)));
+
ptr<Direction> 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> tag;
+ i = 0;
+ for (auto unused_entity : em->entities_with_components(position, direction, tag)) {
+ (void)unused_entity;
+ ASSERT_TRUE(static_cast<bool>(position));
+ ASSERT_TRUE(static_cast<bool>(direction));
+ ASSERT_TRUE(static_cast<bool>(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<Position>();
- auto d = e.assign<Direction>();
+ auto p = e.assign<Position>(1.0, 2.0);
+ auto d = e.assign<Direction>(3.0, 4.0);
+ auto t = e.assign<Tag>("tag");
ptr<Position> up;
ptr<Direction> ud;
- e.unpack<Position, Direction>(up, ud);
+ ptr<Tag> 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.