Skip to content

Commit dad637c

Browse files
committed
Fix unpack and entities_with_components with > 2 args.
1 parent 1da4ce1 commit dad637c

File tree

2 files changed

+56
-35
lines changed

2 files changed

+56
-35
lines changed

entityx/Entity.h

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,8 @@ class Entity {
121121
template <typename C>
122122
ptr<C> component();
123123

124-
template <typename A>
125-
void unpack(ptr<A> &a);
126-
template <typename A, typename B, typename ... Args>
127-
void unpack(ptr<A> &a, ptr<B> &b, Args && ... args);
124+
template <typename A, typename ... Args>
125+
void unpack(ptr<A> &a, ptr<Args> & ... args);
128126

129127
/**
130128
* Destroy and invalidate this Entity.
@@ -347,7 +345,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
347345
}
348346

349347
template <typename A, typename B, typename ... Args>
350-
View &unpack_to(ptr<A> &a, ptr<B> &b, Args && ... args) {
348+
View &unpack_to(ptr<A> &a, ptr<B> &b, ptr<Args> & ... args) {
351349
unpack_to<A>(a);
352350
return unpack_to<B, Args ...>(b, args ...);
353351
}
@@ -515,27 +513,17 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
515513
}
516514

517515
/**
518-
* Find Entities that have all of the specified Components.
516+
* Find Entities that have all of the specified Components and assign them
517+
* to the given parameters.
519518
*/
520519
template <typename C, typename ... Components>
521-
View entities_with_components(ptr<C> &c, Components && ... args) {
520+
View entities_with_components(ptr<C> &c, ptr<Components> & ... args) {
522521
auto mask = component_mask(c, args ...);
523522
return
524523
View(shared_from_this(), View::ComponentMaskPredicate(entity_component_mask_, mask))
525524
.unpack_to(c, args ...);
526525
}
527526

528-
/**
529-
* Unpack components directly into pointers.
530-
*
531-
* Components missing from the entity will be set to nullptr.
532-
*
533-
* Useful for fast bulk iterations.
534-
*
535-
* ptr<Position> p;
536-
* ptr<Direction> d;
537-
* unpack<Position, Direction>(e, p, d);
538-
*/
539527
template <typename A>
540528
void unpack(Entity::Id id, ptr<A> &a) {
541529
a = component<A>(id);
@@ -552,10 +540,10 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
552540
* ptr<Direction> d;
553541
* unpack<Position, Direction>(e, p, d);
554542
*/
555-
template <typename A, typename B, typename ... Args>
556-
void unpack(Entity::Id id, ptr<A> &a, ptr<B> &b, Args && ... args) {
557-
unpack<A>(id, a);
558-
unpack<B, Args ...>(id, b, args ...);
543+
template <typename A, typename ... Args>
544+
void unpack(Entity::Id id, ptr<A> &a, ptr<Args> & ... args) {
545+
a = component<A>(id);
546+
unpack<Args ...>(id, args ...);
559547
}
560548

561549
/**
@@ -582,7 +570,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
582570
}
583571

584572
template <typename C1, typename C2, typename ... Components>
585-
ComponentMask component_mask(const ptr<C1> &c1, const ptr<C2> &c2, Components && ... args) {
573+
ComponentMask component_mask(const ptr<C1> &c1, const ptr<C2> &c2, ptr<Components> & ... args) {
586574
return component_mask<C1>(c1) | component_mask<C2, Components ...>(c2, args...);
587575
}
588576

@@ -649,16 +637,10 @@ ptr<C> Entity::component() {
649637
return manager_.lock()->component<C>(id_);
650638
}
651639

652-
template <typename A>
653-
void Entity::unpack(ptr<A> &a) {
654-
assert(valid());
655-
manager_.lock()->unpack(id_, a);
656-
}
657-
658-
template <typename A, typename B, typename ... Args>
659-
void Entity::unpack(ptr<A> &a, ptr<B> &b, Args && ... args) {
640+
template <typename A, typename ... Args>
641+
void Entity::unpack(ptr<A> &a, ptr<Args> & ... args) {
660642
assert(valid());
661-
manager_.lock()->unpack(id_, a, b, args ...);
643+
manager_.lock()->unpack(id_, a, args ...);
662644
}
663645

664646
} // namespace entityx

entityx/Entity_test.cc

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ using namespace entityx;
2121

2222
using std::ostream;
2323
using std::vector;
24+
using std::string;
2425

2526
template <typename T>
2627
int size(const T &t) {
@@ -61,6 +62,18 @@ ostream &operator << (ostream &out, const Direction &direction) {
6162
return out;
6263
}
6364

65+
struct Tag : Component<Tag> {
66+
explicit Tag(string tag) : tag(tag) {}
67+
68+
bool operator == (const Tag &other) const { return tag == other.tag; }
69+
70+
string tag;
71+
};
72+
73+
ostream &operator << (ostream &out, const Tag &tag) {
74+
out << "Tag(" << tag.tag << ")";
75+
return out;
76+
}
6477

6578
class EntityManagerTest : public ::testing::Test {
6679
protected:
@@ -204,10 +217,14 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) {
204217
position_directions.push_back(std::make_pair(
205218
f.assign<Position>(7.0f, 8.0f),
206219
f.assign<Direction>(9.0f, 10.0f)));
220+
auto thetag = f.assign<Tag>("tag");
207221
g.assign<Position>(5.0f, 6.0f);
208222
int i = 0;
209223

224+
210225
ptr<Position> position;
226+
ASSERT_EQ(3, size(em->entities_with_components(position)));
227+
211228
ptr<Direction> direction;
212229
for (auto unused_entity : em->entities_with_components(position, direction)) {
213230
(void)unused_entity;
@@ -219,18 +236,40 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) {
219236
++i;
220237
}
221238
ASSERT_EQ(2, i);
239+
ptr<Tag> tag;
240+
i = 0;
241+
for (auto unused_entity : em->entities_with_components(position, direction, tag)) {
242+
(void)unused_entity;
243+
ASSERT_TRUE(static_cast<bool>(position));
244+
ASSERT_TRUE(static_cast<bool>(direction));
245+
ASSERT_TRUE(static_cast<bool>(tag));
246+
auto pd = position_directions.at(1);
247+
ASSERT_EQ(position, pd.first);
248+
ASSERT_EQ(direction, pd.second);
249+
ASSERT_EQ(tag, thetag);
250+
i++;
251+
}
252+
ASSERT_EQ(1, i);
222253
}
223254

224255
TEST_F(EntityManagerTest, TestUnpack) {
225256
Entity e = em->create();
226-
auto p = e.assign<Position>();
227-
auto d = e.assign<Direction>();
257+
auto p = e.assign<Position>(1.0, 2.0);
258+
auto d = e.assign<Direction>(3.0, 4.0);
259+
auto t = e.assign<Tag>("tag");
228260

229261
ptr<Position> up;
230262
ptr<Direction> ud;
231-
e.unpack<Position, Direction>(up, ud);
263+
ptr<Tag> ut;
264+
e.unpack(up);
265+
ASSERT_EQ(p, up);
266+
e.unpack(up, ud);
267+
ASSERT_EQ(p, up);
268+
ASSERT_EQ(d, ud);
269+
e.unpack(up, ud, ut);
232270
ASSERT_EQ(p, up);
233271
ASSERT_EQ(d, ud);
272+
ASSERT_EQ(t, ut);
234273
}
235274

236275
// gcc 4.7.2 does not allow this struct to be declared locally inside the TEST_F.

0 commit comments

Comments
 (0)