]> code.bitgloo.com Git - clyne/entityx.git/commitdiff
Removed Manager. Add EntityX class. Largely eradicate use of shared_ptr.
authorAlec Thomas <alec@swapoff.org>
Sun, 2 Mar 2014 04:59:44 +0000 (15:59 +1100)
committerAlec Thomas <alec@swapoff.org>
Sun, 2 Mar 2014 05:22:06 +0000 (16:22 +1100)
21 files changed:
CMakeLists.txt
README.md
entityx/Benchmarks_test.cc
entityx/Entity.cc
entityx/Entity.h
entityx/Entity_test.cc
entityx/Event.h
entityx/Event_test.cc
entityx/Manager.cc [deleted file]
entityx/Manager.h [deleted file]
entityx/System.cc
entityx/System.h
entityx/System_test.cc
entityx/config.h.in
entityx/deps/Dependencies.cc [deleted file]
entityx/deps/Dependencies.h
entityx/deps/Dependencies_test.cc
entityx/entityx.h
entityx/tags/TagsComponent.cc [deleted file]
entityx/tags/TagsComponent.h
entityx/tags/TagsComponent_test.cc

index f996eb94e12bd79bc8cd7629adc51bd01ebee421..1b6efb65429bda7a3537a205a72bdbd04f2bf5bb 100644 (file)
@@ -122,7 +122,7 @@ endif()
 # Things to install
 set(install_libs entityx)
 
-set(sources entityx/tags/TagsComponent.cc entityx/deps/Dependencies.cc entityx/System.cc entityx/Event.cc entityx/Entity.cc entityx/Manager.cc entityx/help/Timer.cc)
+set(sources entityx/System.cc entityx/Event.cc entityx/Entity.cc entityx/help/Timer.cc)
 add_library(entityx STATIC ${sources})
 
 if (ENTITYX_BUILD_SHARED)
index ee1fe5e9f519b8e0c5c73bdae4f1a5b1f24be6b8..3bb45470a2862bde19c7df600c5cf8980c93ec77 100644 (file)
--- a/README.md
+++ b/README.md
@@ -27,6 +27,7 @@ You can also contact me directly via [email](mailto:alec@swapoff.org) or [Twitte
 
 ## Recent Notable Changes
 
+- 2014-03-02 - (1.0.0alpha1) Switch to using cache friendly component storage (big breaking change). Also largely eradicated use of `std::shared_ptr`.
 - 2014-02-13 - Visual C++ support thanks to [Jarrett Chisholm](https://github.com/jarrettchisholm)!
 - 2013-10-29 - Boost has been removed as a primary dependency for builds not using python.
 - 2013-08-21 - Remove dependency on `boost::signal` and switch to embedded [Simple::Signal](http://timj.testbit.eu/2013/cpp11-signal-system-performance/).
@@ -58,10 +59,11 @@ An `entityx::Entity` is a convenience class wrapping an opaque `uint64_t` value
 Creating an entity is as simple as:
 
 ```c++
-entityx::ptr<entityx::EventManager> events(new entityx::EventManager());
-entityx::ptr<entityx::EntityManager> entities(new entityx::EntityManager(event));
+#include <entityx/entityx.h>
 
-entityx::Entity entity = entities->create();
+EntityX entityx;
+
+entityx::Entity entity = entityx.entities.create();
 ```
 
 And destroying an entity is done with:
@@ -75,13 +77,13 @@ entity.destroy();
 - Each `entityx::Entity` is a convenience class wrapping an `entityx::Entity::Id`.
 - An `entityx::Entity` handle can be invalidated with `invalidate()`. This does not affect the underlying entity.
 - When an entity is destroyed the manager adds its ID to a free list and invalidates the `entityx::Entity` handle.
-- When an entity is created IDs are recycled from the free list before allocating new ones.
+- When an entity is created IDs are recycled from the free list first, before allocating new ones.
 - An `entityx::Entity` ID contains an index and a version. When an entity is destroyed, the version associated with the index is incremented, invalidating all previous entities referencing the previous ID.
-- EntityX uses a reference counting smart pointer`entityx::ptr<T>` to manage object lifetimes. As a general rule, passing a pointer to any EntityX method will convert to a smart pointer and take ownership. To maintain your own reference to the pointer you will need to wrap it in `entityx::ptr<T>`.
+- To improve cache coherence, components are constructed in contiguous memory ranges by using `entityx::EntityManager::assign<C>(id, ...)`. A light weight smart pointer (`ComponentPtr<C>`) is used to access the component.
 
 ### Components (entity data)
 
-The general idea with the EntityX interpretation of ECS is to have as little functionality in components as possible. All logic should be contained in Systems.
+The general idea with the EntityX interpretation of ECS is to have as little logic in components as possible. All logic should be contained in Systems.
 
 To that end Components are typically [POD types](http://en.wikipedia.org/wiki/Plain_Old_Data_Structures) consisting of self-contained sets of related data. Implementations are [curiously recurring template pattern](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) (CRTP) subclasses of `entityx::Component<T>`.
 
@@ -112,21 +114,14 @@ To associate a component with a previously created entity call ``entityx::Entity
 entity.assign<Position>(1.0f, 2.0f);
 ```
 
-You can also assign existing instances of components:
-
-```c++
-entityx::ptr<Position> position(new Position(1.0f, 2.0f));
-entity.assign(position);
-```
-
 #### Querying entities and their components
 
 To query all entities with a set of components assigned, use ``entityx::EntityManager::entities_with_components()``. This method will return only those entities that have *all* of the specified components associated with them, assigning each component pointer to the corresponding component instance:
 
 ```c++
-for (auto entity : entities->entities_with_components<Position, Direction>()) {
-  entityx::ptr<Position> position = entity.component<Position>();
-  entityx::ptr<Direction> direction = entity.component<Direction>();
+for (Entity entity : entities.entities_with_components<Position, Direction>()) {
+  ComponentPtr<Position> position = entity.component<Position>();
+  ComponentPtr<Direction> direction = entity.component<Direction>();
 
   // Do things with entity, position and direction.
 }
@@ -135,7 +130,7 @@ for (auto entity : entities->entities_with_components<Position, Direction>()) {
 To retrieve a component associated with an entity use ``entityx::Entity::component<C>()``:
 
 ```c++
-entityx::ptr<Position> position = entity.component<Position>();
+ComponentPtr<Position> position = entity.component<Position>();
 if (position) {
   // Do stuff with position
 }
@@ -166,10 +161,10 @@ A basic movement system might be implemented with something like the following:
 
 ```c++
 struct MovementSystem : public System<MovementSystem> {
-  void update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) override {
-    for (auto entity : es->entities_with_components<Position, Direction>()) {
-      entityx::ptr<Position> position = entity.component<Position>();
-      entityx::ptr<Direction> direction = entity.component<Direction>();
+  void update(entityx::EntityManager &es, entityx::EventManager &events, double dt) override {
+    for (Entity entity : es.entities_with_components<Position, Direction>()) {
+      ComponentPtr<Position> position = entity.component<Position>();
+      ComponentPtr<Direction> direction = entity.component<Direction>();
 
       position->x += direction->x * dt;
       position->y += direction->y * dt;
@@ -204,10 +199,10 @@ Next we implement our collision system, which emits ``Collision`` objects via an
 ```c++
 class CollisionSystem : public System<CollisionSystem> {
  public:
-  void update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) override {
-    entityx::ptr<Position> left_position, right_position;
-    for (auto left_entity : es->entities_with_components<Position>(left_position)) {
-      for (auto right_entity : es->entities_with_components<Position>(right_position)) {
+  void update(entityx::EntityManager &es, entityx::EventManager &events, double dt) override {
+    ComponentPtr<Position> left_position, right_position;
+    for (Entity left_entity : es.entities_with_components<Position>(left_position)) {
+      for (auto right_entity : es.entities_with_components<Position>(right_position)) {
         if (collide(left_position, right_position)) {
           events->emit<Collision>(left_entity, right_entity);
         }
@@ -223,11 +218,11 @@ Objects interested in receiving collision information can subscribe to ``Collisi
 
 ```c++
 struct DebugSystem : public System<DebugSystem>, Receiver<DebugSystem> {
-  void configure(entityx::ptr<entityx::EventManager> event_manager) {
-    event_manager->subscribe<Collision>(*this);
+  void configure(entityx::EventManager &event_manager) {
+    event_manager.subscribe<Collision>(*this);
   }
 
-  void update(ptr<entityx::EntityManager> entities, ptr<entityx::EventManager> events, double dt) {}
+  void update(entityx::EntityManager &entities, entityx::EventManager &events, double dt) {}
 
   void receive(const Collision &collision) {
     LOG(DEBUG) << "entities collided: " << collision.left << " and " << collision.right << endl;
@@ -245,10 +240,10 @@ Several events are emitted by EntityX itself:
   - `entityx::Entity entity` - entityx::Entity about to be destroyed.
 - `ComponentAddedEvent<T>` - emitted when a new component is added to an entity.
   - `entityx::Entity entity` - entityx::Entity that component was added to.
-  - `entityx::ptr<T> component` - The component added.
+  - `ComponentPtr<T> component` - The component added.
 - `ComponentRemovedEvent<T>` - emitted when a component is removed from an entity.
   - `entityx::Entity entity` - entityx::Entity that component was removed from.
-  - `entityx::ptr<T> component` - The component removed.
+  - `ComponentPtr<T> component` - The component removed.
 
 #### Implementation notes
 
index 2790ae0faf78fc8405fad21ea557585494a5caa7..084b7bdb2435df660d05eb8647b247dbadf824fe 100644 (file)
@@ -19,10 +19,10 @@ private:
 
 class BenchmarksTest : public ::testing::Test {
 protected:
-  BenchmarksTest() : ev(EventManager::make()), em(EntityManager::make(ev)) {}
+  BenchmarksTest() : em(ev) {}
 
-  ptr<EventManager> ev;
-  ptr<EntityManager> em;
+  EventManager ev;
+  EntityManager em;
 };
 
 
@@ -33,7 +33,7 @@ TEST_F(BenchmarksTest, TestCreateEntities) {
   cout << "creating " << count << " entities" << endl;
 
   for (uint64_t i = 0; i < count; i++) {
-    em->create();
+    em.create();
   }
 }
 
@@ -42,7 +42,7 @@ TEST_F(BenchmarksTest, TestDestroyEntities) {
   uint64_t count = 10000000L;
   vector<Entity> entities;
   for (uint64_t i = 0; i < count; i++) {
-    entities.push_back(em->create());
+    entities.push_back(em.create());
   }
 
   AutoTimer t;
@@ -60,7 +60,7 @@ struct Listener : public Receiver<Listener> {
 
 TEST_F(BenchmarksTest, TestCreateEntitiesWithListener) {
   Listener listen;
-  ev->subscribe<EntityCreatedEvent>(listen);
+  ev.subscribe<EntityCreatedEvent>(listen);
 
   uint64_t count = 10000000L;
 
@@ -69,18 +69,18 @@ TEST_F(BenchmarksTest, TestCreateEntitiesWithListener) {
 
   vector<Entity> entities;
   for (uint64_t i = 0; i < count; i++) {
-    entities.push_back(em->create());
+    entities.push_back(em.create());
   }
 }
 
 TEST_F(BenchmarksTest, TestDestroyEntitiesWithListener) {
   Listener listen;
-  ev->subscribe<EntityDestroyedEvent>(listen);
+  ev.subscribe<EntityDestroyedEvent>(listen);
 
   uint64_t count = 10000000L;
   vector<Entity> entities;
   for (uint64_t i = 0; i < count; i++) {
-    entities.push_back(em->create());
+    entities.push_back(em.create());
   }
 
   AutoTimer t;
@@ -98,7 +98,7 @@ TEST_F(BenchmarksTest, TestEntityIteration) {
   uint64_t count = 10000000L;
   vector<Entity> entities;
   for (uint64_t i = 0; i < count; i++) {
-    auto e = em->create();
+    auto e = em.create();
     e.assign<Position>();
     entities.push_back(e);
   }
@@ -108,7 +108,7 @@ TEST_F(BenchmarksTest, TestEntityIteration) {
 
   for (int i = 0; i < 10; ++i) {
     ComponentPtr<Position> position;
-    for (auto e : em->entities_with_components<Position>(position)) {
+    for (auto e : em.entities_with_components<Position>(position)) {
     }
   }
 }
index f23e974a089625b066f56dc8fa9276001195d837..ffdfbeeabd1a5062108928fdd11d3983aed39ed3 100644 (file)
@@ -18,20 +18,20 @@ BaseComponent::Family BaseComponent::family_counter_ = 0;
 
 void Entity::invalidate() {
   id_ = INVALID;
-  manager_.reset();
+  manager_ = nullptr;
 }
 
 void Entity::destroy() {
   assert(valid());
-  manager_.lock()->destroy(id_);
+  manager_->destroy(id_);
   invalidate();
 }
 
 std::bitset<entityx::MAX_COMPONENTS> Entity::component_mask() const {
-  return manager_.lock()->component_mask(id_);
+  return manager_->component_mask(id_);
 }
 
-EntityManager::EntityManager(ptr<EventManager> event_manager) : event_manager_(event_manager) {
+EntityManager::EntityManager(EventManager &event_manager) : event_manager_(event_manager) {
 }
 
 EntityManager::~EntityManager() {
index 141f2e6d0fa2aa6ee75a24a80d9814ccdc7a0551..18f04b858913ec15a6d17fb66e87ef2c2278a998 100644 (file)
@@ -19,6 +19,7 @@
 #include <iostream>
 #include <iterator>
 #include <list>
+#include <memory>
 #include <set>
 #include <string>
 #include <utility>
@@ -76,7 +77,7 @@ public:
   static const Id INVALID;
 
   Entity() {}
-  Entity(const ptr<EntityManager> &manager, Entity::Id id) : manager_(manager), id_(id) {}
+  Entity(EntityManager *manager, Entity::Id id) : manager_(manager), id_(id) {}
   Entity(const Entity &other) : manager_(other.manager_), id_(other.id_) {}
 
   Entity &operator = (const Entity &other) {
@@ -142,7 +143,7 @@ public:
   std::bitset<entityx::MAX_COMPONENTS> component_mask() const;
 
  private:
-  weak_ptr<EntityManager> manager_;
+  EntityManager *manager_ = nullptr;
   Entity::Id id_ = INVALID;
 };
 
@@ -221,6 +222,8 @@ private:
   friend class EntityManager;
 
   ComponentPtr(Entity::Id id, EntityManager *manager) : id_(id), manager_(manager) {}
+  ComponentPtr(Entity::Id id, const EntityManager *manager) :
+      id_(id), manager_(const_cast<EntityManager*>(manager)) {}
 
   T *get_component_ptr();
   const T *get_component_ptr() const;
@@ -351,36 +354,16 @@ public:
 /**
  * Manages Entity::Id creation and component assignment.
  */
-class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this<EntityManager> {
+class EntityManager : entityx::help::NonCopyable {
  public:
   typedef std::bitset<entityx::MAX_COMPONENTS> ComponentMask;
 
-  explicit EntityManager(ptr<EventManager> event_manager);
+  explicit EntityManager(EventManager &event_manager);
   virtual ~EntityManager();
 
-  static ptr<EntityManager> make(ptr<EventManager> event_manager) {
-    return ptr<EntityManager>(new EntityManager(event_manager));
-  }
-
   class View {
    public:
-    typedef std::function<bool (const ptr<EntityManager> &, const Entity::Id &)> Predicate;
-
-    /// A predicate that matches valid entities with the given component mask.
-    class ComponentMaskPredicate {
-     public:
-      ComponentMaskPredicate(const std::vector<ComponentMask> &entity_component_masks, ComponentMask mask)
-          : entity_component_masks_(entity_component_masks), mask_(mask) {}
-
-      bool operator()(const ptr<EntityManager> &entities, const Entity::Id &entity) {
-        return entities->entity_version_[entity.index()] == entity.version()
-            && (entity_component_masks_[entity.index()] & mask_) == mask_;
-      }
-
-     private:
-      const std::vector<ComponentMask> &entity_component_masks_;
-      ComponentMask mask_;
-    };
+    typedef std::function<bool (const EntityManager &, const Entity::Id &)> Predicate;
 
     struct BaseUnpacker {
       virtual ~BaseUnpacker() {}
@@ -403,9 +386,9 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
      private:
       friend class View;
 
-      Iterator(ptr<EntityManager> manager,
+      Iterator(EntityManager *manager,
                const std::vector<Predicate> &predicates,
-               const std::vector<ptr<BaseUnpacker>> &unpackers,
+               const std::vector<std::shared_ptr<BaseUnpacker>> &unpackers,
                uint32_t index)
           : manager_(manager), predicates_(predicates), unpackers_(unpackers), i_(index), capacity_(manager_->capacity()) {
         next();
@@ -427,16 +410,16 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
       bool predicate() {
         Entity::Id id = manager_->create_id(i_);
         for (auto &p : predicates_) {
-          if (!p(manager_, id)) {
+          if (!p(*manager_, id)) {
             return false;
           }
         }
         return true;
       }
 
-      ptr<EntityManager> manager_;
+      EntityManager *manager_;
       std::vector<Predicate> predicates_;
-      std::vector<ptr<BaseUnpacker>> unpackers_;
+      std::vector<std::shared_ptr<BaseUnpacker>> unpackers_;
       uint32_t i_;
       size_t capacity_;
     };
@@ -453,7 +436,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
 
     template <typename A>
     View &unpack_to(ComponentPtr<A> &a) {
-      unpackers_.push_back(ptr<Unpacker<A>>(new Unpacker<A>(manager_, a)));
+      unpackers_.push_back(std::shared_ptr<Unpacker<A>>(new Unpacker<A>(manager_, a)));
       return *this;
     }
 
@@ -468,24 +451,24 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
 
     template <typename T>
     struct Unpacker : BaseUnpacker {
-      Unpacker(ptr<EntityManager> manager, ComponentPtr<T> &c) : manager_(manager), c(c) {}
+      Unpacker(EntityManager *manager, ComponentPtr<T> &c) : manager_(manager), c(c) {}
 
       void unpack(const Entity::Id &id) {
         c = manager_->component<T>(id);
       }
 
      private:
-      ptr<EntityManager> manager_;
+      EntityManager *manager_;
       ComponentPtr<T> &c;
     };
 
-    View(ptr<EntityManager> manager, Predicate predicate) : manager_(manager) {
+    View(EntityManager *manager, Predicate predicate) : manager_(manager) {
       predicates_.push_back(predicate);
     }
 
-    ptr<EntityManager> manager_;
+    EntityManager *manager_;
     std::vector<Predicate> predicates_;
-    std::vector<ptr<BaseUnpacker>> unpackers_;
+    std::vector<std::shared_ptr<BaseUnpacker>> unpackers_;
   };
 
   /**
@@ -521,8 +504,8 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
       free_list_.pop_front();
        version = entity_version_[index];
     }
-    Entity entity(shared_from_this(), Entity::Id(index, version));
-    event_manager_->emit<EntityCreatedEvent>(entity);
+    Entity entity(this, Entity::Id(index, version));
+    event_manager_.emit<EntityCreatedEvent>(entity);
     return entity;
   }
 
@@ -534,7 +517,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
   void destroy(Entity::Id entity) {
     assert_valid(entity);
     int index = entity.index();
-    event_manager_->emit<EntityDestroyedEvent>(Entity(shared_from_this(), entity));
+    event_manager_.emit<EntityDestroyedEvent>(Entity(this, entity));
     for (BaseComponentAllocator *allocator : component_allocators_) {
       if (allocator) allocator->destroy(index);
     }
@@ -545,7 +528,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
 
   Entity get(Entity::Id id) {
     assert_valid(id);
-    return Entity(shared_from_this(), id);
+    return Entity(this, id);
   }
 
   /**
@@ -573,7 +556,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
     new(allocator->get(id.index())) C(std::forward<Args>(args) ...);
     entity_component_mask_[id.index()] |= uint64_t(1) << family;
     ComponentPtr<C> component(id, this);
-    event_manager_->emit<ComponentAddedEvent<C>>(Entity(shared_from_this(), id), component);
+    event_manager_.emit<ComponentAddedEvent<C>>(Entity(this, id), component);
     return ComponentPtr<C>(id, this);
   }
 
@@ -591,14 +574,14 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
     assert(allocator);
     entity_component_mask_[id.index()] &= ~(uint64_t(1) << family);
     ComponentPtr<C> component(id, this);
-    event_manager_->emit<ComponentRemovedEvent<C>>(Entity(shared_from_this(), id), component);
+    event_manager_.emit<ComponentRemovedEvent<C>>(Entity(this, id), component);
     allocator->destroy(index);
   }
 
   /**
    * Retrieve a Component assigned to an Entity::Id.
    *
-   * @returns Component instance, or empty ptr<> if the Entity::Id does not have that Component.
+   * @returns Component instance, or empty ComponentPtr<> if the Entity::Id does not have that Component.
    */
   template <typename C>
   ComponentPtr<C> component(Entity::Id id) {
@@ -613,24 +596,59 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
     return ComponentPtr<C>(id, this);
   }
 
+  /**
+   * Retrieve a Component assigned to an Entity::Id.
+   *
+   * @returns Component instance, or empty ComponentPtr<> if the Entity::Id does not have that Component.
+   */
+  template <typename C>
+  ComponentPtr<const C> component(Entity::Id id) const {
+    assert_valid(id);
+    size_t family = C::family();
+    // We don't bother checking the component mask, as we return a nullptr anyway.
+    if (family >= component_allocators_.size())
+      return ComponentPtr<const C>();
+    BaseComponentAllocator *allocator = component_allocators_[family];
+    if (!allocator || !entity_component_mask_[id.index()][family])
+      return ComponentPtr<const C>();
+    return ComponentPtr<const C>(id, this);
+  }
+
   /**
    * Find Entities that have all of the specified Components.
+   *
+   * @code
+   * for (Entity entity : entity_manager.entities_with_components<Position, Direction>()) {
+   *   ComponentPtr<Position> position = entity.component<Position>();
+   *   ComponentPtr<Direction> direction = entity.component<Direction>();
+   *
+   *   ...
+   * }
+   * @endcode
    */
   template <typename C, typename ... Components>
   View entities_with_components() {
     auto mask = component_mask<C, Components ...>();
-    return View(shared_from_this(), View::ComponentMaskPredicate(entity_component_mask_, mask));
+    return View(this, ComponentMaskPredicate(entity_component_mask_, mask));
   }
 
   /**
    * Find Entities that have all of the specified Components and assign them
    * to the given parameters.
+   *
+   * @code
+   * ComponentPtr<Position> position;
+   * ComponentPtr<Direction> direction;
+   * for (Entity entity : entity_manager.entities_with_components(position, direction)) {
+   *   // Use position and component here.
+   * }
+   * @endcode
    */
   template <typename C, typename ... Components>
   View entities_with_components(ComponentPtr<C> &c, ComponentPtr<Components> & ... args) {
     auto mask = component_mask(c, args ...);
     return
-        View(shared_from_this(), View::ComponentMaskPredicate(entity_component_mask_, mask))
+        View(this, ComponentMaskPredicate(entity_component_mask_, mask))
         .unpack_to(c, args ...);
   }
 
@@ -668,6 +686,22 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
   friend class ComponentPtr;
   friend class Entity;
 
+  /// A predicate that matches valid entities with the given component mask.
+  class ComponentMaskPredicate {
+   public:
+    ComponentMaskPredicate(const std::vector<ComponentMask> &entity_component_masks, ComponentMask mask)
+        : entity_component_masks_(entity_component_masks), mask_(mask) {}
+
+    bool operator()(const EntityManager &entities, const Entity::Id &entity) {
+      return entities.entity_version_[entity.index()] == entity.version()
+          && (entity_component_masks_[entity.index()] & mask_) == mask_;
+    }
+
+   private:
+    const std::vector<ComponentMask> &entity_component_masks_;
+    ComponentMask mask_;
+  };
+
   inline void assert_valid(Entity::Id id) const {
     assert(id.index() < entity_component_mask_.size() && "Entity::Id ID outside entity vector range");
     assert(entity_version_[id.index()] == id.version() && "Attempt to access Entity via a stale Entity::Id");
@@ -741,7 +775,7 @@ class EntityManager : entityx::help::NonCopyable, public enable_shared_from_this
 
   uint32_t index_counter_ = 0;
 
-  ptr<EventManager> event_manager_;
+  EventManager &event_manager_;
   // Each element in component_allocators_ corresponds to a Component::family().
   std::vector<BaseComponentAllocator*> component_allocators_;
   // Bitmask of components associated with each entity. Index into the vector is the Entity::Id.
@@ -764,29 +798,29 @@ BaseComponent::Family Component<C>::family() {
 template <typename C, typename ... Args>
 ComponentPtr<C> Entity::assign(Args && ... args) {
   assert(valid());
-  return manager_.lock()->assign<C>(id_, std::forward<Args>(args) ...);
+  return manager_->assign<C>(id_, std::forward<Args>(args) ...);
 }
 
 template <typename C>
 void Entity::remove() {
   assert(valid() && component<C>());
-  manager_.lock()->remove<C>(id_);
+  manager_->remove<C>(id_);
 }
 
 template <typename C>
 ComponentPtr<C> Entity::component() {
   assert(valid());
-  return manager_.lock()->component<C>(id_);
+  return manager_->component<C>(id_);
 }
 
 template <typename A, typename ... Args>
 void Entity::unpack(ComponentPtr<A> &a, ComponentPtr<Args> & ... args) {
   assert(valid());
-  manager_.lock()->unpack(id_, a, args ...);
+  manager_->unpack(id_, a, args ...);
 }
 
 inline bool Entity::valid() const {
-  return !manager_.expired() && manager_.lock()->valid(id_);
+  return manager_ && manager_->valid(id_);
 }
 
 
index 553a15966e29758eebb7c05919689c1770b9c2c1..2caf8f4f2bd7df71953fe0960888827476e43f39 100644 (file)
@@ -77,10 +77,10 @@ ostream &operator << (ostream &out, const Tag &tag) {
 
 class EntityManagerTest : public ::testing::Test {
  protected:
-  EntityManagerTest() : ev(EventManager::make()), em(EntityManager::make(ev)) {}
+  EntityManagerTest() : em(ev) {}
 
-  ptr<EventManager> ev;
-  ptr<EntityManager> em;
+  EventManager ev;
+  EntityManager em;
 
   virtual void SetUp() {
   }
@@ -88,29 +88,29 @@ class EntityManagerTest : public ::testing::Test {
 
 
 TEST_F(EntityManagerTest, TestCreateEntity) {
-  ASSERT_EQ(em->size(), 0UL);
+  ASSERT_EQ(em.size(), 0UL);
 
   Entity e2;
   ASSERT_FALSE(e2.valid());
 
-  Entity e = em->create();
+  Entity e = em.create();
   ASSERT_TRUE(e.valid());
-  ASSERT_EQ(em->size(), 1UL);
+  ASSERT_EQ(em.size(), 1UL);
 
   e2 = e;
   ASSERT_TRUE(e2.valid());
 }
 
 TEST_F(EntityManagerTest, TestEntityAsBoolean) {
-  ASSERT_EQ(em->size(), 0UL);
-  Entity e = em->create();
+  ASSERT_EQ(em.size(), 0UL);
+  Entity e = em.create();
   ASSERT_TRUE(e.valid());
-  ASSERT_EQ(em->size(), 1UL);
+  ASSERT_EQ(em.size(), 1UL);
   ASSERT_FALSE(!e);
 
   e.destroy();
 
-  ASSERT_EQ(em->size(), 0UL);
+  ASSERT_EQ(em.size(), 0UL);
 
   ASSERT_TRUE(!e);
 
@@ -119,7 +119,7 @@ TEST_F(EntityManagerTest, TestEntityAsBoolean) {
 }
 
 TEST_F(EntityManagerTest, TestEntityReuse) {
-  Entity e1 = em->create();
+  Entity e1 = em.create();
   Entity e2 = e1;
   auto id = e1.id();
   ASSERT_TRUE(e1.valid());
@@ -127,7 +127,7 @@ TEST_F(EntityManagerTest, TestEntityReuse) {
   e1.destroy();
   ASSERT_TRUE(!e1.valid());
   ASSERT_TRUE(!e2.valid());
-  Entity e3 = em->create();
+  Entity e3 = em.create();
   // It is assumed that the allocation will reuse the same entity id, though
   // the version will change.
   auto new_id = e3.id();
@@ -136,7 +136,7 @@ TEST_F(EntityManagerTest, TestEntityReuse) {
 }
 
 TEST_F(EntityManagerTest, TestComponentConstruction) {
-  auto e = em->create();
+  auto e = em.create();
   auto p = e.assign<Position>(1, 2);
   auto cp = e.component<Position>();
   ASSERT_EQ(p, cp);
@@ -145,8 +145,8 @@ TEST_F(EntityManagerTest, TestComponentConstruction) {
 }
 
 TEST_F(EntityManagerTest, TestDestroyEntity) {
-  Entity e = em->create();
-  Entity f = em->create();
+  Entity e = em.create();
+  Entity f = em.create();
   e.assign<Position>();
   f.assign<Position>();
   e.assign<Direction>();
@@ -168,37 +168,37 @@ TEST_F(EntityManagerTest, TestDestroyEntity) {
 }
 
 TEST_F(EntityManagerTest, TestGetEntitiesWithComponent) {
-  Entity e = em->create();
-  Entity f = em->create();
-  Entity g = em->create();
+  Entity e = em.create();
+  Entity f = em.create();
+  Entity g = em.create();
   e.assign<Position>();
   e.assign<Direction>();
   f.assign<Position>();
   g.assign<Position>();
-  ASSERT_EQ(3, size(em->entities_with_components<Position>()));
-  ASSERT_EQ(1, size(em->entities_with_components<Direction>()));
+  ASSERT_EQ(3, size(em.entities_with_components<Position>()));
+  ASSERT_EQ(1, size(em.entities_with_components<Direction>()));
 }
 
 TEST_F(EntityManagerTest, TestGetEntitiesWithIntersectionOfComponents) {
   vector<Entity> entities;
   for (int i = 0; i < 150; ++i) {
-    Entity e = em->create();
+    Entity e = em.create();
     entities.push_back(e);
     if (i % 2 == 0)
       e.assign<Position>();
     if (i % 3 == 0)
       e.assign<Direction>();
   }
-  ASSERT_EQ(50, size(em->entities_with_components<Direction>()));
-  ASSERT_EQ(75, size(em->entities_with_components<Position>()));
-  ASSERT_EQ(25, size(em->entities_with_components<Direction, Position>()));
+  ASSERT_EQ(50, size(em.entities_with_components<Direction>()));
+  ASSERT_EQ(75, size(em.entities_with_components<Position>()));
+  ASSERT_EQ(25, size(em.entities_with_components<Direction, Position>()));
 }
 
 TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) {
   vector<Entity::Id> entities;
-  Entity e = em->create();
-  Entity f = em->create();
-  Entity g = em->create();
+  Entity e = em.create();
+  Entity f = em.create();
+  Entity g = em.create();
   std::vector<std::pair<ComponentPtr<Position>, ComponentPtr<Direction>>> position_directions;
   position_directions.push_back(std::make_pair(
           e.assign<Position>(1.0f, 2.0f),
@@ -212,10 +212,10 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) {
 
 
   ComponentPtr<Position> position;
-  ASSERT_EQ(3, size(em->entities_with_components(position)));
+  ASSERT_EQ(3, size(em.entities_with_components(position)));
 
   ComponentPtr<Direction> direction;
-  for (auto unused_entity : em->entities_with_components(position, direction)) {
+  for (auto unused_entity : em.entities_with_components(position, direction)) {
     (void)unused_entity;
     ASSERT_TRUE(static_cast<bool>(position));
     ASSERT_TRUE(static_cast<bool>(direction));
@@ -227,7 +227,7 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) {
   ASSERT_EQ(2, i);
   ComponentPtr<Tag> tag;
   i = 0;
-  for (auto unused_entity : em->entities_with_components(position, direction, tag)) {
+  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));
@@ -242,7 +242,7 @@ TEST_F(EntityManagerTest, TestGetEntitiesWithComponentAndUnpacking) {
 }
 
 TEST_F(EntityManagerTest, TestUnpack) {
-  Entity e = em->create();
+  Entity e = em.create();
   auto p = e.assign<Position>(1.0, 2.0);
   auto d = e.assign<Direction>(3.0, 4.0);
   auto t = e.assign<Tag>("tag");
@@ -264,14 +264,14 @@ TEST_F(EntityManagerTest, TestUnpack) {
 // gcc 4.7.2 does not allow this struct to be declared locally inside the TEST_F.
 
 // TEST_F(EntityManagerTest, TestUnpackNullMissing) {
-//   Entity e = em->create();
+//   Entity e = em.create();
 //   auto p = e.assign<Position>();
 
-//   ptr<Position> up(reinterpret_cast<Position*>(0Xdeadbeef), NullDeleter());
-//   ptr<Direction> ud(reinterpret_cast<Direction*>(0Xdeadbeef), NullDeleter());
+//   std::shared_ptr<Position> up(reinterpret_cast<Position*>(0Xdeadbeef), NullDeleter());
+//   std::shared_ptr<Direction> ud(reinterpret_cast<Direction*>(0Xdeadbeef), NullDeleter());
 //   e.unpack<Position, Direction>(up, ud);
 //   ASSERT_EQ(p, up);
-//   ASSERT_EQ(ptr<Direction>(), ud);
+//   ASSERT_EQ(std::shared_ptr<Direction>(), ud);
 // }
 
 TEST_F(EntityManagerTest, TestComponentIdsDiffer) {
@@ -288,11 +288,11 @@ TEST_F(EntityManagerTest, TestEntityCreatedEvent) {
   };
 
   EntityCreatedEventReceiver receiver;
-  ev->subscribe<EntityCreatedEvent>(receiver);
+  ev.subscribe<EntityCreatedEvent>(receiver);
 
   ASSERT_EQ(0UL, receiver.created.size());
   for (int i = 0; i < 10; ++i) {
-    em->create();
+    em.create();
   }
   ASSERT_EQ(10UL, receiver.created.size());
 }
@@ -307,12 +307,12 @@ TEST_F(EntityManagerTest, TestEntityDestroyedEvent) {
   };
 
   EntityDestroyedEventReceiver receiver;
-  ev->subscribe<EntityDestroyedEvent>(receiver);
+  ev.subscribe<EntityDestroyedEvent>(receiver);
 
   ASSERT_EQ(0UL, receiver.destroyed.size());
   vector<Entity> entities;
   for (int i = 0; i < 10; ++i) {
-    entities.push_back(em->create());
+    entities.push_back(em.create());
   }
   ASSERT_EQ(0UL, receiver.destroyed.size());
   for (auto e : entities) {
@@ -344,8 +344,8 @@ TEST_F(EntityManagerTest, TestComponentAddedEvent) {
   };
 
   ComponentAddedEventReceiver receiver;
-  ev->subscribe<ComponentAddedEvent<Position>>(receiver);
-  ev->subscribe<ComponentAddedEvent<Direction>>(receiver);
+  ev.subscribe<ComponentAddedEvent<Position>>(receiver);
+  ev.subscribe<ComponentAddedEvent<Direction>>(receiver);
 
   ASSERT_NE(ComponentAddedEvent<Position>::family(),
             ComponentAddedEvent<Direction>::family());
@@ -353,7 +353,7 @@ TEST_F(EntityManagerTest, TestComponentAddedEvent) {
   ASSERT_EQ(0, receiver.position_events);
   ASSERT_EQ(0, receiver.direction_events);
   for (int i = 0; i < 10; ++i) {
-    Entity e = em->create();
+    Entity e = em.create();
     e.assign<Position>(static_cast<float>(i), static_cast<float>(i));
     e.assign<Direction>(static_cast<float>(-i), static_cast<float>(-i));
   }
@@ -371,10 +371,10 @@ TEST_F(EntityManagerTest, TestComponentRemovedEvent) {
   };
 
   ComponentRemovedReceiver receiver;
-  ev->subscribe<ComponentRemovedEvent<Direction>>(receiver);
+  ev.subscribe<ComponentRemovedEvent<Direction>>(receiver);
 
   ASSERT_FALSE(receiver.removed);
-  Entity e = em->create();
+  Entity e = em.create();
   auto p = e.assign<Direction>(1.0, 2.0);
   e.remove<Direction>();
   ASSERT_EQ(receiver.removed, p);
@@ -383,7 +383,7 @@ TEST_F(EntityManagerTest, TestComponentRemovedEvent) {
 
 TEST_F(EntityManagerTest, TestEntityAssignment) {
   Entity a, b;
-  a = em->create();
+  a = em.create();
   ASSERT_NE(a, b);
   b = a;
   ASSERT_EQ(a, b);
@@ -392,8 +392,8 @@ TEST_F(EntityManagerTest, TestEntityAssignment) {
 }
 
 TEST_F(EntityManagerTest, TestEntityDestroyAll) {
-  Entity a = em->create(), b = em->create();
-  em->reset();
+  Entity a = em.create(), b = em.create();
+  em.reset();
   ASSERT_FALSE(a.valid());
   ASSERT_FALSE(b.valid());
 }
@@ -403,12 +403,12 @@ TEST_F(EntityManagerTest, TestEntityDestroyHole) {
   std::vector<Entity> entities;
 
   auto count = [this]() -> int {
-    auto e = em->entities_with_components<Position>();
+    auto e = em.entities_with_components<Position>();
     return std::count_if(e.begin(), e.end(), [] (const Entity &) { return true; });
   };
 
   for (int i = 0; i < 5000; i++) {
-    auto e = em->create();
+    auto e = em.create();
     e.assign<Position>();
     entities.push_back(e);
   }
index 8c8a8dc731803c5764106aa0f339fb24296d7e9c..a4b3e5db9947bd2ef4789853913ecedade63f2b3 100644 (file)
 
 #pragma once
 
+#include <unordered_map>
 #include <stdint.h>
 #include <list>
+#include <memory>
 #include <utility>
-#include <unordered_map>
 #include "entityx/config.h"
 #include "entityx/3rdparty/simplesignal.h"
 #include "entityx/help/NonCopyable.h"
@@ -37,8 +38,8 @@ class BaseEvent {
 
 
 typedef Simple::Signal<void (const BaseEvent*)> EventSignal;
-typedef ptr<EventSignal> EventSignalPtr;
-typedef weak_ptr<EventSignal> EventSignalWeakPtr;
+typedef std::shared_ptr<EventSignal> EventSignalPtr;
+typedef std::weak_ptr<EventSignal> EventSignalWeakPtr;
 
 
 /**
@@ -107,10 +108,6 @@ class EventManager : entityx::help::NonCopyable {
   EventManager();
   virtual ~EventManager();
 
-  static ptr<EventManager> make() {
-    return ptr<EventManager>(new EventManager());
-  }
-
   /**
    * Subscribe an object to receive events of type E.
    *
@@ -142,7 +139,7 @@ class EventManager : entityx::help::NonCopyable {
    * Emit an already constructed event.
    */
   template <typename E>
-  void emit(ptr<E> event) {
+  void emit(std::unique_ptr<E> event) {
     auto sig = signal_for(E::family());
     sig->emit(static_cast<BaseEvent*>(event.get()));
   }
@@ -154,7 +151,7 @@ class EventManager : entityx::help::NonCopyable {
    *
    * eg.
    *
-   * ptr<EventManager> em = new EventManager();
+   * std::shared_ptr<EventManager> em = new EventManager();
    * em->emit<Explosion>(10);
    *
    */
index 7986526d28307b419cb670869d3d2ddac8138fc8..362d361c2f09a475e48adc8a86eb20a913723301 100644 (file)
@@ -33,49 +33,49 @@ struct ExplosionSystem : public Receiver<ExplosionSystem> {
 };
 
 TEST(EventManagerTest, TestEmitReceive) {
-  auto em = EventManager::make();
+  EventManager em;
   ExplosionSystem explosion_system;
-  em->subscribe<Explosion>(explosion_system);
+  em.subscribe<Explosion>(explosion_system);
   ASSERT_EQ(0, explosion_system.damage_received);
-  em->emit<Explosion>(10);
+  em.emit<Explosion>(10);
   ASSERT_EQ(10, explosion_system.damage_received);
 }
 
 
 TEST(EventManagerTest, TestUntypedEmitReceive) {
-  auto em = EventManager::make();
+  EventManager em;
   ExplosionSystem explosion_system;
-  em->subscribe<Explosion>(explosion_system);
+  em.subscribe<Explosion>(explosion_system);
   ASSERT_EQ(0, explosion_system.damage_received);
   Explosion explosion(10);
-  em->emit(explosion);
+  em.emit(explosion);
   ASSERT_EQ(10, explosion_system.damage_received);
 }
 
 
 TEST(EventManagerTest, TestReceiverExpired) {
-  auto em = EventManager::make();
+  EventManager em;
   {
     ExplosionSystem explosion_system;
-    em->subscribe<Explosion>(explosion_system);
-    em->emit<Explosion>(10);
+    em.subscribe<Explosion>(explosion_system);
+    em.emit<Explosion>(10);
     ASSERT_EQ(10, explosion_system.damage_received);
     ASSERT_EQ(1, explosion_system.connected_signals());
-    ASSERT_EQ(1, em->connected_receivers());
+    ASSERT_EQ(1, em.connected_receivers());
   }
-  ASSERT_EQ(0, em->connected_receivers());
+  ASSERT_EQ(0, em.connected_receivers());
 }
 
 
 TEST(EventManagerTest, TestSenderExpired) {
   ExplosionSystem explosion_system;
   {
-    auto em = EventManager::make();
-    em->subscribe<Explosion>(explosion_system);
-    em->emit<Explosion>(10);
+    EventManager em;
+    em.subscribe<Explosion>(explosion_system);
+    em.emit<Explosion>(10);
     ASSERT_EQ(10, explosion_system.damage_received);
     ASSERT_EQ(1, explosion_system.connected_signals());
-    ASSERT_EQ(1, em->connected_receivers());
+    ASSERT_EQ(1, em.connected_receivers());
   }
   ASSERT_EQ(0, explosion_system.connected_signals());
 }
diff --git a/entityx/Manager.cc b/entityx/Manager.cc
deleted file mode 100644 (file)
index a86ee56..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 Alec Thomas <alec@swapoff.org>
- * All rights reserved.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.
- *
- * Author: Alec Thomas <alec@swapoff.org>
- */
-
-#include "Manager.h"
-
-namespace entityx {
-
-void Manager::start() {
-  configure();
-  system_manager->configure();
-  initialize();
-}
-
-void Manager::run() {
-  running_ = true;
-  double dt;
-  timer_.restart();
-  while (running_) {
-    dt = timer_.elapsed();
-    timer_.restart();
-    update(dt);
-  }
-}
-
-void Manager::step(double dt) {
-  update(dt);
-}
-
-
-void Manager::stop() {
-  running_ = false;
-}
-
-}  // namespace entityx
diff --git a/entityx/Manager.h b/entityx/Manager.h
deleted file mode 100644 (file)
index 2da482e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 Alec Thomas <alec@swapoff.org>
- * All rights reserved.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.
- *
- * Author: Alec Thomas <alec@swapoff.org>
- */
-
-#pragma once
-
-#include "entityx/Entity.h"
-#include "entityx/Event.h"
-#include "entityx/System.h"
-#include "entityx/help/Timer.h"
-
-namespace entityx {
-
-class Manager {
- public:
-  virtual ~Manager() {}
-
-  /**
-   * Call start() to initialize the Manager.
-   */
-  void start();
-
-
-  /**
-   * Run the main loop. To explicitly manage your own main loop use step(dt);
-   */
-  void run();
-
-  /**
-   * Step the system by dt.
-   * @param dt Delta time since last frame.
-   */
-  void step(double dt);
-
-  /**
-   * Stop the manager.
-   */
-  void stop();
-
- protected:
-  Manager() :
-    event_manager(EventManager::make()),
-    entity_manager(EntityManager::make(event_manager)),
-    system_manager(SystemManager::make(entity_manager, event_manager)) {}
-
-  /**
-   * Configure the world.
-   *
-   * This is called once on Manager initialization. It is typically used to add Systems to the world, load permanent
-   * resources, global configuration, etc.
-   */
-  virtual void configure() = 0;
-
-  /**
-   * Initialize the entities and events in the world.
-   *
-   * Typically used to create initial entities, setup event handlers, and so on.
-   */
-  virtual void initialize() = 0;
-
-  /**
-   * Update the world.
-   *
-   * Typically this is where you would call update() on all Systems in the world.
-   */
-  virtual void update(double dt) = 0;
-
-  ptr<EventManager> event_manager;
-  ptr<EntityManager> entity_manager;
-  ptr<SystemManager> system_manager;
-
- private:
-  help::Timer timer_;
-  bool running_ = false;
-};
-
-}  // namespace entityx
index 44995bc2fa455e20138eb9be6dc0dce6f8837b06..dc83cacdc2f7e30637d1a5b88fe6a8b74448ce91 100644 (file)
@@ -15,10 +15,10 @@ namespace entityx {
 BaseSystem::Family BaseSystem::family_counter_;
 
 void SystemManager::configure() {
-  for (auto pair : systems_) {
+  for (auto &pair : systems_) {
     pair.second->configure(event_manager_);
   }
   initialized_ = true;
 }
 
-}
+}  // namespace entityx
index 9c0b2ecde0398cbbf9e74615632804caf6eccabc..d94c91ab5ec8fa92a9a68cbd9c9b1b4a139c82e3 100644 (file)
@@ -11,9 +11,9 @@
 #pragma once
 
 
+#include <stdint.h>
 #include <unordered_map>
 #include <utility>
-#include <stdint.h>
 #include <cassert>
 #include "entityx/config.h"
 #include "entityx/Entity.h"
 
 namespace entityx {
 
+
+class SystemManager;
+
+
 /**
  * Base System class. Generally should not be directly used, instead see System<Derived>.
  */
@@ -37,14 +41,14 @@ class BaseSystem : entityx::help::NonCopyable {
    *
    * Typically used to set up event handlers.
    */
-  virtual void configure(ptr<EventManager> events) {}
+  virtual void configure(EventManager &events) {}
 
   /**
    * Apply System behavior.
    *
    * Called every game step.
    */
-  virtual void update(ptr<EntityManager> entities, ptr<EventManager> events, double dt) = 0;
+  virtual void update(EntityManager &entities, EventManager &events, double dt) = 0;
 
   static Family family_counter_;
 
@@ -56,7 +60,7 @@ class BaseSystem : entityx::help::NonCopyable {
  * Use this class when implementing Systems.
  *
  * struct MovementSystem : public System<MovementSystem> {
- *   void update(ptr<EntityManager> entities, EventManager &events, double dt) {
+ *   void update(EntityManager &entities, EventManager &events, double dt) {
  *     // Do stuff to/with entities...
  *   }
  * }
@@ -66,6 +70,9 @@ class System : public BaseSystem {
  public:
   virtual ~System() {}
 
+private:
+  friend class SystemManager;
+
   static Family family() {
     static Family family = family_counter_++;
     return family;
@@ -73,29 +80,24 @@ class System : public BaseSystem {
 };
 
 
-class SystemManager : entityx::help::NonCopyable, public enable_shared_from_this<SystemManager> {
+class SystemManager : entityx::help::NonCopyable {
  public:
-  SystemManager(ptr<EntityManager> entity_manager,
-                ptr<EventManager> event_manager) :
+  SystemManager(EntityManager &entity_manager,
+                EventManager &event_manager) :
                 entity_manager_(entity_manager),
                 event_manager_(event_manager) {}
 
-  static ptr<SystemManager> make(ptr<EntityManager> entity_manager,
-                  ptr<EventManager> event_manager) {
-    return ptr<SystemManager>(new SystemManager(entity_manager, event_manager));
-  }
-
   /**
    * Add a System to the SystemManager.
    *
    * Must be called before Systems can be used.
    *
    * eg.
-   * ptr<MovementSystem> movement = entityx::make_shared<MovementSystem>();
+   * std::shared_ptr<MovementSystem> movement = entityx::make_shared<MovementSystem>();
    * system.add(movement);
    */
   template <typename S>
-  void add(ptr<S> system) {
+  void add(std::shared_ptr<S> system) {
     systems_.insert(std::make_pair(S::family(), system));
   }
 
@@ -108,8 +110,8 @@ class SystemManager : entityx::help::NonCopyable, public enable_shared_from_this
    * auto movement = system.add<MovementSystem>();
    */
   template <typename S, typename ... Args>
-  ptr<S> add(Args && ... args) {
-    ptr<S> s(new S(std::forward<Args>(args) ...));
+  std::shared_ptr<S> add(Args && ... args) {
+    std::shared_ptr<S> s(new S(std::forward<Args>(args) ...));
     add(s);
     return s;
   }
@@ -117,17 +119,17 @@ class SystemManager : entityx::help::NonCopyable, public enable_shared_from_this
   /**
    * Retrieve the registered System instance, if any.
    *
-   *   ptr<CollisionSystem> collisions = systems.system<CollisionSystem>();
+   *   std::shared_ptr<CollisionSystem> collisions = systems.system<CollisionSystem>();
    *
-   * @return System instance or empty shared_ptr<S>.
+   * @return System instance or empty shared_std::shared_ptr<S>.
    */
   template <typename S>
-  ptr<S> system() {
+  std::shared_ptr<S> system() {
     auto it = systems_.find(S::family());
     assert(it != systems_.end());
     return it == systems_.end()
-        ? ptr<S>()
-        : ptr<S>(static_pointer_cast<S>(it->second));
+        ? std::shared_ptr<S>()
+        : std::shared_ptr<S>(std::static_pointer_cast<S>(it->second));
   }
 
   /**
@@ -136,7 +138,7 @@ class SystemManager : entityx::help::NonCopyable, public enable_shared_from_this
   template <typename S>
   void update(double dt) {
     assert(initialized_ && "SystemManager::configure() not called");
-    ptr<S> s = system<S>();
+    std::shared_ptr<S> s = system<S>();
     s->update(entity_manager_, event_manager_, dt);
   }
 
@@ -149,9 +151,9 @@ class SystemManager : entityx::help::NonCopyable, public enable_shared_from_this
 
  private:
   bool initialized_ = false;
-  ptr<EntityManager> entity_manager_;
-  ptr<EventManager> event_manager_;
-  std::unordered_map<BaseSystem::Family, ptr<BaseSystem>> systems_;
+  EntityManager &entity_manager_;
+  EventManager &event_manager_;
+  std::unordered_map<BaseSystem::Family, std::shared_ptr<BaseSystem>> systems_;
 };
 
 }  // namespace entityx
index e0d5b6a4961cbdc7b670f5ff7cf80b6590a39fe3..16f7372161683efe5658fed501359f17db4277fa 100644 (file)
@@ -8,11 +8,11 @@
  * Author: Alec Thomas <alec@swapoff.org>
  */
 
+#include <gtest/gtest.h>
 #include <string>
 #include <vector>
-#include <gtest/gtest.h>
-#include "entityx/Manager.h"
 #include "entityx/System.h"
+#include "entityx/quick.h"
 
 
 // using namespace std;
@@ -36,8 +36,8 @@ class MovementSystem : public System<MovementSystem> {
  public:
   explicit MovementSystem(string label = "") : label(label) {}
 
-  void update(ptr<EntityManager> es, ptr<EventManager> events, double) override {
-    EntityManager::View entities = es->entities_with_components<Position, Direction>();
+  void update(EntityManager &es, EventManager &events, double) override {
+    EntityManager::View entities = es.entities_with_components<Position, Direction>();
     ComponentPtr<Position> position;
     ComponentPtr<Direction> direction;
     for (auto entity : entities) {
@@ -51,59 +51,49 @@ class MovementSystem : public System<MovementSystem> {
 };
 
 
-class TestManager : public entityx::Manager {
+class TestContainer : public EntityX {
  public:
-  std::vector<Entity> entities;
-
-  ptr<SystemManager> sm() { return system_manager; }
-  ptr<EntityManager> em() { return entity_manager; }
-
- protected:
-  void configure() override {
-  }
+  std::vector<Entity> created_entities;
 
-  void initialize() override {
+  void initialize() {
     for (int i = 0; i < 150; ++i) {
-      Entity e = entity_manager->create();
-      entities.push_back(e);
+      Entity e = entities.create();
+      created_entities.push_back(e);
       if (i % 2 == 0)
         e.assign<Position>(1, 2);
       if (i % 3 == 0)
         e.assign<Direction>(1, 1);
     }
   }
-
-  void update(double dt) override {
-  }
 };
 
 
 class SystemManagerTest : public ::testing::Test {
  protected:
-  TestManager manager;
+  TestContainer manager;
 
   virtual void SetUp() override {
-    manager.start();
+    manager.initialize();
   }
 };
 
 
 TEST_F(SystemManagerTest, TestConstructSystemWithArgs) {
-  manager.sm()->add<MovementSystem>("movement");
-  manager.sm()->configure();
+  manager.systems.add<MovementSystem>("movement");
+  manager.systems.configure();
 
-  ASSERT_EQ("movement", manager.sm()->system<MovementSystem>()->label);
+  ASSERT_EQ("movement", manager.systems.system<MovementSystem>()->label);
 }
 
 
 TEST_F(SystemManagerTest, TestApplySystem) {
-  manager.sm()->add<MovementSystem>();
-  manager.sm()->configure();
+  manager.systems.add<MovementSystem>();
+  manager.systems.configure();
 
-  manager.sm()->update<MovementSystem>(0.0);
+  manager.systems.update<MovementSystem>(0.0);
   ComponentPtr<Position> position;
   ComponentPtr<Direction> direction;
-  for (auto entity : manager.entities) {
+  for (auto entity : manager.created_entities) {
     entity.unpack<Position, Direction>(position, direction);
     if (position && direction) {
       ASSERT_FLOAT_EQ(2.0, position->x);
index 940d4d18ceb0ddd74d0e1f3c87acb752298da70d..575b34f5f8c5cfe290f693a9ca840fb0323893d0 100644 (file)
@@ -1,55 +1,11 @@
 #pragma once
 
 #cmakedefine ENTITYX_MAX_COMPONENTS @ENTITYX_MAX_COMPONENTS@
-#cmakedefine ENTITYX_HAVE_BOOST_PYTHON 1
-#cmakedefine ENTITYX_INSTALLED_PYTHON_PACKAGE_DIR "@ENTITYX_INSTALLED_PYTHON_PACKAGE_DIR@"
-#cmakedefine ENTITYX_NEED_GET_POINTER_SHARED_PTR_SPECIALIZATION "@ENTITYX_NEED_GET_POINTER_SHARED_PTR_SPECIALIZATION@"
 
 #include <stdint.h>
-#include "entityx/config.h"
 
 namespace entityx {
 
 static const uint64_t MAX_COMPONENTS = ENTITYX_MAX_COMPONENTS;
 
 }  // namespace entityx
-
-
-// Which shared_ptr implementation should we use?
-#include <memory>
-// for std::forward()
-#include <utility>
-
-namespace entityx {
-
-template <typename T>
-using ptr = std::shared_ptr<T>;
-template <typename T>
-using weak_ptr = std::weak_ptr<T>;
-template <typename T, typename U>
-ptr<U> static_pointer_cast(const ptr<T> &ptr) {
-  return std::static_pointer_cast<U>(ptr);
-}
-template <typename T>
-using enable_shared_from_this = std::enable_shared_from_this<T>;
-
-}  // namespace entityx
-
-namespace entityx {
-
-template <typename T, typename... Args>
-ptr<T> make_ptr(Args&&... args) {
-    return ptr<T>(::new T(std::forward<Args>(args)...));
-}
-
-template <typename T>
-bool operator == (const weak_ptr<T> &a, const weak_ptr<T> &b) {
-  return a.lock() == b.lock();
-}
-
-template <typename T>
-int use_count(const ptr<T> &ptr) {
-  return ptr.use_count();
-}
-
-}  // namespace entityx
diff --git a/entityx/deps/Dependencies.cc b/entityx/deps/Dependencies.cc
deleted file mode 100644 (file)
index 9271a2f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (C) 2013 Alec Thomas <alec@swapoff.org>
- * All rights reserved.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.
- *
- * Author: Alec Thomas <alec@swapoff.org>
- */
-
-#include "entityx/deps/Dependencies.h"
index 69e68bb8ca539f1231628fc22a2e930273b00668..83ab4a572dfc36182c138b1188f918a3b6385e02 100644 (file)
@@ -31,11 +31,11 @@ public:
     assign<Deps...>(event.entity);
   }
 
-  virtual void configure(ptr<EventManager> events) override {
-    events->subscribe<ComponentAddedEvent<C>>(*this);
+  virtual void configure(EventManager &events) override {
+    events.subscribe<ComponentAddedEvent<C>>(*this);
   }
 
-  virtual void update(ptr<EntityManager> entities, ptr<EventManager> events, double dt) override {}
+  virtual void update(EntityManager &entities, EventManager &events, double dt) override {}
 
 private:
   template <typename D>
index 8a2f17c7fd774d66e6e5438d1f9a6559f2397772..72d4ae813421a84b805587009465d80fa1b34731 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <gtest/gtest.h>
 #include "entityx/deps/Dependencies.h"
+#include "entityx/quick.h"
 
 
 namespace ex = entityx;
@@ -25,25 +26,15 @@ struct B : public ex::Component<B> {
 struct C : public ex::Component<C> {};
 
 
-class DepsTest : public ::testing::Test {
- protected:
-  DepsTest() : events(ex::EventManager::make()),
-               entities(ex::EntityManager::make(events)),
-               systems(ex::SystemManager::make(entities, events)) {}
-
-  ex::ptr<ex::EventManager> events;
-  ex::ptr<ex::EntityManager> entities;
-  ex::ptr<ex::SystemManager> systems;
-
-  virtual void SetUp() {}
+class DepsTest : public ::testing::Test, public ex::EntityX {
 };
 
 
 TEST_F(DepsTest, TestSingleDependency) {
-  systems->add<deps::Dependency<A, B>>();
-  systems->configure();
+  systems.add<deps::Dependency<A, B>>();
+  systems.configure();
 
-  ex::Entity e = entities->create();
+  ex::Entity e = entities.create();
   ASSERT_FALSE(static_cast<bool>(e.component<A>()));
   ASSERT_FALSE(static_cast<bool>(e.component<B>()));
   e.assign<A>();
@@ -52,10 +43,10 @@ TEST_F(DepsTest, TestSingleDependency) {
 }
 
 TEST_F(DepsTest, TestMultipleDependencies) {
-  systems->add<deps::Dependency<A, B, C>>();
-  systems->configure();
+  systems.add<deps::Dependency<A, B, C>>();
+  systems.configure();
 
-  ex::Entity e = entities->create();
+  ex::Entity e = entities.create();
   ASSERT_FALSE(static_cast<bool>(e.component<A>()));
   ASSERT_FALSE(static_cast<bool>(e.component<B>()));
   ASSERT_FALSE(static_cast<bool>(e.component<C>()));
@@ -66,10 +57,10 @@ TEST_F(DepsTest, TestMultipleDependencies) {
 }
 
 TEST_F(DepsTest, TestDependencyDoesNotRecreateComponent) {
-  systems->add<deps::Dependency<A, B>>();
-  systems->configure();
+  systems.add<deps::Dependency<A, B>>();
+  systems.configure();
 
-  ex::Entity e = entities->create();
+  ex::Entity e = entities.create();
   e.assign<B>(true);
   ASSERT_TRUE(e.component<B>()->b);
   e.assign<A>();
index eb83073cbc2d5a1bed4fb8f67d2ed84c250e7867..72cfa24515dc8f55d3c203c165a212b75366651f 100644 (file)
@@ -5,3 +5,4 @@
 #include "entityx/Entity.h"
 #include "entityx/System.h"
 #include "entityx/Manager.h"
+#include "entityx/quick.h"
diff --git a/entityx/tags/TagsComponent.cc b/entityx/tags/TagsComponent.cc
deleted file mode 100644 (file)
index 509debf..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (C) 2012 Alec Thomas <alec@swapoff.org>
- * All rights reserved.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.
- *
- * Author: Alec Thomas <alec@swapoff.org>
- */
-
-#include "entityx/tags/TagsComponent.h"
index 6fcb937365d5b3ea1f30e3076235e8f4c56e4f8b..f47249ff52b8cc999112421a76ea1bd1cb9e0146 100644 (file)
@@ -10,8 +10,8 @@
 
 #pragma once
 
-#include <string>
 #include <unordered_set>
+#include <string>
 #include "entityx/Entity.h"
 
 namespace entityx {
@@ -19,13 +19,20 @@ namespace tags {
 
 /**
  * Allow entities to be tagged with strings.
+ *
+ * entity.assign<TagsComponent>("tag1", "tag2");
+ *
+ * ComponentPtr<TagsComponent> tags;
+ * for (Entity entity : entity_manager.entities_with_components(tags))
+ * for (Entity entity : TagsComponent::view(entity_manager, "tag1")) {
+ * }
  */
 class TagsComponent : public Component<TagsComponent> {
   struct TagsPredicate {
     explicit TagsPredicate(const std::string &tag) : tag(tag) {}
 
-    bool operator() (ptr<EntityManager> manager, Entity::Id id) {
-      auto tags = manager->component<TagsComponent>(id);
+    bool operator() (const EntityManager &manager, Entity::Id id) {
+      auto tags = manager.component<TagsComponent>(id);
       return tags && tags->tags.find(tag) != tags->tags.end();
     }
 
index 34651b37a44e61fe52f8fc6abb5c8f4c16535767..4674c5a2d5bf413c3f41d07d4d3ea282754070f9 100644 (file)
@@ -8,6 +8,7 @@
  * Author: Alec Thomas <alec@swapoff.org>
  */
 
+#include <string>
 #include <gtest/gtest.h>
 #include "entityx/tags/TagsComponent.h"
 
@@ -39,16 +40,17 @@ TEST(TagsComponentTest, TestVariadicConstruction) {
 }
 
 TEST(TagsComponentTest, TestEntitiesWithTag) {
-  auto en = EntityManager::make(EventManager::make());
-  Entity a = en->create();
+  EventManager ev;
+  EntityManager en(ev);
+  Entity a = en.create();
   a.assign<Position>();
   for (int i = 0; i < 99; ++i) {
-    auto e = en->create();
+    auto e = en.create();
     e.assign<Position>();
     e.assign<TagsComponent>("positionable");
   }
   a.assign<TagsComponent>("player", "indestructible");
-  auto entities = en->entities_with_components<Position>();
+  auto entities = en.entities_with_components<Position>();
   ASSERT_EQ(100, size(entities));
   ASSERT_EQ(1, size(TagsComponent::view(entities, "player")));
 }