aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlec Thomas <alec@swapoff.org>2013-03-09 12:35:09 -0500
committerAlec Thomas <alec@swapoff.org>2013-03-09 12:47:37 -0500
commit3068ee5a693d8191fc7aaa4fb0fc3b1220a004d2 (patch)
treeaf61af97fdf5a7bd7cbf875b05cb72d9f23f154a
parentbc739894324638f6743a88c213ec53118df510e3 (diff)
Allow Entity objects to be copied around.
Note that this doesn't use shared_ptr, but this is little different from the previous implementation using a reference.
-rw-r--r--entityx/Entity.cc8
-rw-r--r--entityx/Entity.h77
-rw-r--r--entityx/Entity_test.cc10
3 files changed, 70 insertions, 25 deletions
diff --git a/entityx/Entity.cc b/entityx/Entity.cc
index 6c43a06..41fbb4c 100644
--- a/entityx/Entity.cc
+++ b/entityx/Entity.cc
@@ -4,7 +4,7 @@
*
* 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>
*/
@@ -16,7 +16,11 @@ namespace entityx {
BaseComponent::Family BaseComponent::family_counter_ = 0;
bool Entity::exists() const {
- return entities_.exists(id_);
+ return entities_ != nullptr && entities_->exists(id_);
+}
+
+void Entity::detach() {
+ entities_ = nullptr;
}
}
diff --git a/entityx/Entity.h b/entityx/Entity.h
index ae28443..0116a22 100644
--- a/entityx/Entity.h
+++ b/entityx/Entity.h
@@ -15,6 +15,7 @@
#include <algorithm>
#include <bitset>
#include <cassert>
+#include <iostream>
#include <iterator>
#include <set>
#include <string>
@@ -38,6 +39,28 @@ class Entity {
public:
typedef uint64_t Id;
+ Entity(): entities_(nullptr) {}
+
+ /**
+ * Alias for exists().
+ */
+ bool operator ! () const {
+ return exists();
+ }
+
+ bool operator == (const Entity &other) const {
+ return other.entities_ == entities_ && other.id_ == id_;
+ }
+
+ bool operator != (const Entity &other) const {
+ return other.entities_ != entities_ || other.id_ != id_;
+ }
+
+ /**
+ * Detach entity from the EntityManager.
+ */
+ void detach();
+
Id id() const { return id_; }
operator Id () { return id_; }
@@ -60,13 +83,19 @@ class Entity {
private:
friend class EntityManager;
- Entity(EntityManager &entities, Entity::Id id) : entities_(entities), id_(id) {}
+ Entity(EntityManager *entities, Entity::Id id) : entities_(entities), id_(id) {}
- EntityManager &entities_;
+ EntityManager *entities_;
Entity::Id id_;
};
+inline std::ostream &operator << (std::ostream &out, const Entity &entity) {
+ out << "Entity(" << entity.id() << ")";
+ return out;
+}
+
+
/**
* Base component class, only used for insertion into collections.
*
@@ -201,17 +230,19 @@ class EntityManager : boost::noncopyable {
private:
friend class View;
- Iterator(EntityManager &manager, const std::vector<Predicate> &predicates,
+ Iterator() : manager_(nullptr) {}
+
+ Iterator(EntityManager *manager, const std::vector<Predicate> &predicates,
const std::vector<boost::function<void (Entity::Id)>> &unpackers, Entity::Id entity)
: manager_(manager), predicates_(predicates), unpackers_(unpackers), i_(entity) {
next();
}
void next() {
- while (i_ < manager_.size() && !predicate()) {
+ while (i_ < manager_->size() && !predicate()) {
++i_;
}
- if (i_ < manager_.size() && !unpackers_.empty()) {
+ if (i_ < manager_->size() && !unpackers_.empty()) {
for (auto unpacker : unpackers_) {
unpacker(i_);
}
@@ -220,14 +251,14 @@ class EntityManager : boost::noncopyable {
bool predicate() {
for (auto &p : predicates_) {
- if (!p(manager_, i_)) {
+ if (!p(*manager_, i_)) {
return false;
}
}
return true;
}
- EntityManager &manager_;
+ EntityManager *manager_;
const std::vector<Predicate> predicates_;
std::vector<boost::function<void (Entity::Id)>> unpackers_;
Entity::Id i_;
@@ -239,9 +270,9 @@ class EntityManager : boost::noncopyable {
}
Iterator begin() { return Iterator(manager_, predicates_, unpackers_, 0); }
- Iterator end() { return Iterator(manager_, predicates_, unpackers_, manager_.size()); }
+ Iterator end() { return Iterator(manager_, predicates_, unpackers_, manager_->size()); }
const Iterator begin() const { return Iterator(manager_, predicates_, unpackers_, 0); }
- const Iterator end() const { return Iterator(manager_, predicates_, unpackers_, manager_.size()); }
+ const Iterator end() const { return Iterator(manager_, predicates_, unpackers_, manager_->size()); }
template <typename A>
View &unpack_to(boost::shared_ptr<A> &a) {
@@ -263,22 +294,22 @@ class EntityManager : boost::noncopyable {
template <typename T>
struct Unpacker {
- Unpacker(EntityManager &manager, boost::shared_ptr<T> &c) : manager(manager), c(c) {}
+ Unpacker(EntityManager *manager, boost::shared_ptr<T> &c) : manager_(manager), c(c) {}
void operator () (Entity::Id id) {
- c = manager.component<T>(id);
+ c = manager_->component<T>(id);
}
private:
- EntityManager &manager;
+ EntityManager *manager_;
boost::shared_ptr<T> &c;
};
- View(EntityManager &manager, Predicate predicate) : manager_(manager) {
+ View(EntityManager *manager, Predicate predicate) : manager_(manager) {
predicates_.push_back(predicate);
}
- EntityManager &manager_;
+ EntityManager *manager_;
std::vector<Predicate> predicates_;
std::vector<boost::function<void (Entity::Id)>> unpackers_;
};
@@ -304,7 +335,7 @@ class EntityManager : boost::noncopyable {
free_list_.erase(it);
}
event_manager_.emit<EntityCreatedEvent>(*this, id);
- return Entity(*this, id);
+ return Entity(this, id);
}
/**
@@ -333,7 +364,7 @@ class EntityManager : boost::noncopyable {
}
Entity get(Entity::Id id) {
- return Entity(*this, id);
+ return Entity(this, id);
}
/**
@@ -385,7 +416,7 @@ class EntityManager : boost::noncopyable {
template <typename C, typename ... Components>
View entities_with_components() {
uint64_t mask = component_mask<C, Components ...>();
- return View(*this, View::ComponentMaskPredicate(entity_component_mask_, mask));
+ return View(this, View::ComponentMaskPredicate(entity_component_mask_, mask));
}
/**
@@ -395,7 +426,7 @@ class EntityManager : boost::noncopyable {
View entities_with_components(boost::shared_ptr<C> &c, Components && ... args) {
uint64_t mask = component_mask(c, args ...);
return
- View(*this, View::ComponentMaskPredicate(entity_component_mask_, mask))
+ View(this, View::ComponentMaskPredicate(entity_component_mask_, mask))
.unpack_to(c, args ...);
}
@@ -484,27 +515,27 @@ class EntityManager : boost::noncopyable {
template <typename C>
boost::shared_ptr<C> Entity::assign(boost::shared_ptr<C> component) {
- return entities_.assign<C>(id_, component);
+ return entities_->assign<C>(id_, component);
}
template <typename C, typename ... Args>
boost::shared_ptr<C> Entity::assign(Args && ... args) {
- return entities_.assign<C>(id_, args ...);
+ return entities_->assign<C>(id_, args ...);
}
template <typename C>
boost::shared_ptr<C> Entity::component() {
- return entities_.component<C>(id_);
+ return entities_->component<C>(id_);
}
template <typename A>
void Entity::unpack(boost::shared_ptr<A> &a) {
- entities_.unpack(id_, a);
+ entities_->unpack(id_, a);
}
template <typename A, typename B, typename ... Args>
void Entity::unpack(boost::shared_ptr<A> &a, boost::shared_ptr<B> &b, Args && ... args) {
- entities_.unpack(id_, a, b, args ...);
+ entities_->unpack(id_, a, b, args ...);
}
}
diff --git a/entityx/Entity_test.cc b/entityx/Entity_test.cc
index d042b4b..cc3d11f 100644
--- a/entityx/Entity_test.cc
+++ b/entityx/Entity_test.cc
@@ -306,3 +306,13 @@ TEST_F(EntityManagerTest, TestComponentAddedEvent) {
ASSERT_EQ(10, receiver.position_events);
ASSERT_EQ(10, receiver.direction_events);
}
+
+TEST_F(EntityManagerTest, TestEntityAssignment) {
+ Entity a, b;
+ a = em.create();
+ ASSERT_NE(a, b);
+ b = a;
+ ASSERT_EQ(a, b);
+ a.detach();
+ ASSERT_NE(a, b);
+}