See #85.
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++
-Position::Handle position;
-Direction::Handle direction;
+ComponentHandle<Position> position;
+ComponentHandle<Direction> direction;
for (Entity entity : entities.entities_with_components(position, direction)) {
// Do things with entity, position and direction.
}
To retrieve a component associated with an entity use ``entityx::Entity::component<C>()``:
```c++
-Position::Handle position = entity.component<Position>();
+ComponentHandle<Position> position = entity.component<Position>();
if (position) {
// Do stuff with position
}
```c++
struct MovementSystem : public System<MovementSystem> {
void update(entityx::EntityManager &es, entityx::EventManager &events, TimeDelta dt) override {
- Position::Handle position;
- Direction::Handle direction;
+ ComponentHandle<Position> position;
+ ComponentHandle<Direction> direction;
for (Entity entity : es.entities_with_components(position, direction)) {
position->x += direction->x * dt;
position->y += direction->y * dt;
class CollisionSystem : public System<CollisionSystem> {
public:
void update(entityx::EntityManager &es, entityx::EventManager &events, TimeDelta dt) override {
- Position::Handle left_position, right_position;
+ ComponentHandle<Position> left_position, right_position;
for (Entity left_entity : es.entities_with_components(left_position)) {
for (Entity right_entity : es.entities_with_components(right_position)) {
if (collide(left_position, right_position)) {
template <typename C, typename ... Args>
ComponentHandle<C> assign(Entity::Id id, Args && ... args) {
assert_valid(id);
- const BaseComponent::Family family = C::family();
+ const BaseComponent::Family family = Component<C>::family();
assert(!entity_component_mask_[id.index()].test(family));
// Placement new into the component pool.
template <typename C>
void remove(Entity::Id id) {
assert_valid(id);
- const BaseComponent::Family family = C::family();
+ const BaseComponent::Family family = Component<C>::family();
const uint32_t index = id.index();
// Find the pool for this component family.
template <typename C>
bool has_component(Entity::Id id) const {
assert_valid(id);
- size_t family = C::family();
+ size_t family = Component<C>::family();
// We don't bother checking the component mask, as we return a nullptr anyway.
if (family >= component_pools_.size())
return false;
template <typename C>
ComponentHandle<C> component(Entity::Id id) {
assert_valid(id);
- size_t family = C::family();
+ size_t family = Component<C>::family();
// We don't bother checking the component mask, as we return a nullptr anyway.
if (family >= component_pools_.size())
return ComponentHandle<C>();
template <typename C>
const ComponentHandle<const C> component(Entity::Id id) const {
assert_valid(id);
- size_t family = C::family();
+ size_t family = Component<C>::family();
// We don't bother checking the component mask, as we return a nullptr anyway.
if (family >= component_pools_.size())
return ComponentHandle<const C>();
template <typename C>
C *get_component_ptr(Entity::Id id) {
assert(valid(id));
- BasePool *pool = component_pools_[C::family()];
+ BasePool *pool = component_pools_[Component<C>::family()];
assert(pool);
return static_cast<C*>(pool->get(id.index()));
}
template <typename C>
const C *get_component_ptr(Entity::Id id) const {
assert_valid(id);
- BasePool *pool = component_pools_[C::family()];
+ BasePool *pool = component_pools_[Component<C>::family()];
assert(pool);
return static_cast<const C*>(pool->get(id.index()));
}
template <typename C>
ComponentMask component_mask() {
ComponentMask mask;
- mask.set(C::family());
+ mask.set(Component<C>::family());
return mask;
}
}
}
- template <typename T>
- Pool<T> *accomodate_component() {
- BaseComponent::Family family = T::family();
+ template <typename C>
+ Pool<C> *accomodate_component() {
+ BaseComponent::Family family = Component<C>::family();
if (component_pools_.size() <= family) {
component_pools_.resize(family + 1, nullptr);
}
if (!component_pools_[family]) {
- Pool<T> *pool = new Pool<T>();
+ Pool<C> *pool = new Pool<C>();
pool->expand(index_counter_);
component_pools_[family] = pool;
}
- return static_cast<Pool<T>*>(component_pools_[family]);
+ return static_cast<Pool<C>*>(component_pools_[family]);
}
return n;
}
-struct Position : Component<Position> {
+struct Position {
Position(float x = 0.0f, float y = 0.0f) : x(x), y(y) {}
bool operator==(const Position &other) const {
return out;
}
-struct Direction : Component<Direction> {
+struct Direction {
Direction(float x = 0.0f, float y = 0.0f) : x(x), y(y) {}
bool operator==(const Direction &other) const {
Entity e = em.create();
Entity f = em.create();
Entity g = em.create();
- std::vector<std::pair<Position::Handle, Direction::Handle>> position_directions;
+ std::vector<std::pair<ComponentHandle<Position>, ComponentHandle<Direction>>> position_directions;
position_directions.push_back(std::make_pair(
e.assign<Position>(1.0f, 2.0f), e.assign<Direction>(3.0f, 4.0f)));
position_directions.push_back(std::make_pair(
g.assign<Position>(5.0f, 6.0f);
int i = 0;
- Position::Handle position;
+ ComponentHandle<Position> position;
REQUIRE(3 == size(em.entities_with_components(position)));
- Direction::Handle direction;
+ ComponentHandle<Direction> direction;
for (auto unused_entity : em.entities_with_components(position, direction)) {
(void)unused_entity;
REQUIRE(position);
++i;
}
REQUIRE(2 == i);
- Tag::Handle tag;
+ ComponentHandle<Tag> tag;
i = 0;
for (auto unused_entity :
em.entities_with_components(position, direction, tag)) {
auto d = e.assign<Direction>(3.0, 4.0);
auto t = e.assign<Tag>("tag");
- Position::Handle up;
- Direction::Handle ud;
- Tag::Handle ut;
+ ComponentHandle<Position> up;
+ ComponentHandle<Direction> ud;
+ ComponentHandle<Tag> ut;
e.unpack(up);
REQUIRE(p == up);
e.unpack(up, ud);
// }
TEST_CASE_METHOD(EntityManagerFixture, "TestComponentIdsDiffer") {
- REQUIRE(Position::family() != Direction::family());
+ REQUIRE(Component<Position>::family() != Component<Direction>::family());
}
TEST_CASE_METHOD(EntityManagerFixture, "TestEntityCreatedEvent") {
removed = event.component;
}
- Direction::Handle removed;
+ ComponentHandle<Direction> removed;
};
ComponentRemovedReceiver receiver;
REQUIRE(!(receiver.removed));
Entity e = em.create();
- Direction::Handle p = e.assign<Direction>(1.0, 2.0);
+ ComponentHandle<Direction> p = e.assign<Direction>(1.0, 2.0);
e.remove<Direction>();
REQUIRE(receiver.removed == p);
REQUIRE(!(e.component<Direction>()));
TEST_CASE_METHOD(EntityManagerFixture, "TestComponentHandleInvalidatedWhenEntityDestroyed") {
Entity a = em.create();
- Position::Handle position = a.assign<Position>(1, 2);
+ ComponentHandle<Position> position = a.assign<Position>(1, 2);
REQUIRE(position);
REQUIRE(position->x == 1);
REQUIRE(position->y == 2);
TEST_CASE_METHOD(EntityManagerFixture, "TestComponentAssignmentFromCopy") {
Entity a = em.create();
CopyVerifier original;
- CopyVerifier::Handle copy = a.assign_from_copy(original);
+ ComponentHandle<CopyVerifier> copy = a.assign_from_copy(original);
REQUIRE(copy);
REQUIRE(copy->copied == 1);
a.destroy();
TEST_CASE_METHOD(EntityManagerFixture, "TestComponentHandleInvalidatedWhenComponentDestroyed") {
Entity a = em.create();
- Position::Handle position = a.assign<Position>(1, 2);
+ ComponentHandle<Position> position = a.assign<Position>(1, 2);
REQUIRE(position);
REQUIRE(position->x == 1);
REQUIRE(position->y == 2);
e.assign<Position>(1, 2);
e.assign<Direction>(3, 4);
- std::tuple<Position::Handle, Direction::Handle> components = e.components<Position, Direction>();
+ std::tuple<ComponentHandle<Position>, ComponentHandle<Direction>> components = e.components<Position, Direction>();
REQUIRE(std::get<0>(components)->x == 1);
REQUIRE(std::get<0>(components)->y == 2);