From f617f3e65b27be7a600e4f28c85bbd88e0d9df6b Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 24 Oct 2012 16:14:48 -0400 Subject: Fix unpacking bug (segfault from lambda). --- entityx/Entity.h | 77 +++++++++++++++++++++++++------------------------- entityx/Entity_test.cc | 1 + 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/entityx/Entity.h b/entityx/Entity.h index 356c773..013830e 100644 --- a/entityx/Entity.h +++ b/entityx/Entity.h @@ -180,14 +180,10 @@ class EntityManager : boost::noncopyable { while (i_ < manager_.size() && !predicate()) { ++i_; } - if (i_ < manager_.size()) { - unpack(); - } - } - - void unpack() { - for (auto unpacker : unpackers_) { - unpacker(i_); + if (i_ < manager_.size() && !unpackers_.empty()) { + for (auto unpacker : unpackers_) { + unpacker(i_); + } } } @@ -218,20 +214,35 @@ class EntityManager : boost::noncopyable { template View &unpack_to(boost::shared_ptr &a) { - unpackers_.push_back([&] (Entity id) { + unpackers_.push_back(Unpacker(manager_, a)); + // This resulted in a segfault under clang 4.1 on OSX. No idea why. + /*unpackers_.push_back([&a, this](Entity id) { a = manager_.component(id); - }); + });*/ return *this; } template - View &unpack_to(boost::shared_ptr &a, boost::shared_ptr &b, Args *& ... args) { + View &unpack_to(boost::shared_ptr &a, boost::shared_ptr &b, Args && ... args) { unpack_to(a); return unpack_to(b, args ...); } private: friend class EntityManager; + template + struct Unpacker { + Unpacker(EntityManager &manager, boost::shared_ptr &c) : manager(manager), c(c) {} + + void operator () (Entity id) { + c = manager.component(id); + } + + private: + EntityManager &manager; + boost::shared_ptr &c; + }; + View(EntityManager &manager, Predicate predicate) : manager_(manager) { predicates_.push_back(predicate); } @@ -331,44 +342,24 @@ class EntityManager : boost::noncopyable { return boost::static_pointer_cast(c); } - /** - * Get all entities with the given component. - */ - template - View entities_with_components() { - auto mask = component_mask(); - return View(*this, View::ComponentMaskPredicate(entity_component_mask_, mask)); - } - /** * Find Entities that have all of the specified Components. */ - template + template View entities_with_components() { - auto mask = component_mask(); + uint64_t mask = component_mask(); return View(*this, View::ComponentMaskPredicate(entity_component_mask_, mask)); } - /** - * Get all entities with the given component. - */ - template - View entities_with_components(boost::shared_ptr &c) { - auto mask = component_mask(); - return - View(*this, View::ComponentMaskPredicate(entity_component_mask_, mask)) - .unpack_to(c); - } - /** * Find Entities that have all of the specified Components. */ - template - View entities_with_components(boost::shared_ptr &c1, boost::shared_ptr &c2, Components *& ... args) { - auto mask = component_mask(); + template + View entities_with_components(boost::shared_ptr &c, Components && ... args) { + uint64_t mask = component_mask(c, args ...); return View(*this, View::ComponentMaskPredicate(entity_component_mask_, mask)) - .unpack_to(c1, c2, args...); + .unpack_to(c, args ...); } /** @@ -399,7 +390,7 @@ class EntityManager : boost::noncopyable { * unpack(e, p, d); */ template - void unpack(Entity id, boost::shared_ptr &a, boost::shared_ptr &b, Args & ... args) { + void unpack(Entity id, boost::shared_ptr &a, boost::shared_ptr &b, Args && ... args) { unpack(id, a); unpack(id, b, args ...); } @@ -415,6 +406,16 @@ class EntityManager : boost::noncopyable { return component_mask() | component_mask(); } + template + uint64_t component_mask(const boost::shared_ptr &c) { + return uint64_t(1) << C::family(); + } + + template + uint64_t component_mask(const boost::shared_ptr &c1, const boost::shared_ptr &c2, Components && ... args) { + return component_mask(c1) | component_mask(c2, args...); + } + inline void accomodate_entity(Entity entity) { if (entity_component_mask_.size() <= entity) { entity_component_mask_.resize(entity + 1); diff --git a/entityx/Entity_test.cc b/entityx/Entity_test.cc index aa1b32b..805a3d3 100644 --- a/entityx/Entity_test.cc +++ b/entityx/Entity_test.cc @@ -164,6 +164,7 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) { em.assign(f, 9.0f, 10.0f))); em.assign(g, 5.0f, 6.0f); int i = 0; + shared_ptr position; shared_ptr direction; for (auto unused_entity : em.entities_with_components(position, direction)) { -- cgit v1.2.3