diff options
Diffstat (limited to 'yage/entity')
-rw-r--r-- | yage/entity/README.md | 9 | ||||
-rw-r--r-- | yage/entity/component.cpp | 16 | ||||
-rw-r--r-- | yage/entity/component.h | 10 | ||||
-rw-r--r-- | yage/entity/entity.cpp | 11 | ||||
-rw-r--r-- | yage/entity/entity.h | 29 |
5 files changed, 64 insertions, 11 deletions
diff --git a/yage/entity/README.md b/yage/entity/README.md index 6a7704c6..18ac16cf 100644 --- a/yage/entity/README.md +++ b/yage/entity/README.md @@ -1,9 +1,10 @@ # Entity Component System (ECS) -This ECS is heavily inspired from the [Entityx component system](__fix -link__). It is a much simpler and less efficient implementation, as it does not -support dedicated pools for the different components, and only stores them on -the heap and are directed to by pointers. +This ECS is heavily inspired from the [Entityx component +system](https://github.com/alecthomas/entityx). It is a much simpler and less +efficient implementation, as it does not support dedicated pools for the +different components, and only stores them on the heap and are directed to by +pointers. A future improvement would be to store the components in a contiguous area in memory, so that the iteration through them can be more efficient. diff --git a/yage/entity/component.cpp b/yage/entity/component.cpp index eba2ad0a..4c0eae82 100644 --- a/yage/entity/component.cpp +++ b/yage/entity/component.cpp @@ -1,8 +1,24 @@ #include "component.h" +#include <memory> + namespace yage { GroupId BaseComponent::group_id_counter_ = 0; +ComponentGroup &ComponentGroup::add(std::unique_ptr<BaseComponent> &&component) +{ + components_.push_back(std::move(component)); + return *this; +} + +ComponentGroup::Container::iterator ComponentGroup::begin() { + return components_.begin(); +} + +ComponentGroup::Container::iterator ComponentGroup::end() { + return components_.end(); +} + } // namespace yage diff --git a/yage/entity/component.h b/yage/entity/component.h index a21409ff..3f2b3a81 100644 --- a/yage/entity/component.h +++ b/yage/entity/component.h @@ -28,13 +28,21 @@ private: template <typename T> class Component : public BaseComponent { +private: GroupId getGroup() override; }; class ComponentGroup { public: - std::vector<std::unique_ptr<BaseComponent>> components_; + typedef std::vector<std::unique_ptr<BaseComponent>> Container; + + ComponentGroup &add(std::unique_ptr<BaseComponent> &&component); + Container::iterator begin(); + Container::iterator end(); + +private: + Container components_; }; template <typename T> diff --git a/yage/entity/entity.cpp b/yage/entity/entity.cpp index 25e8e2d0..c20d15d6 100644 --- a/yage/entity/entity.cpp +++ b/yage/entity/entity.cpp @@ -3,6 +3,8 @@ #include "component.h" #include <algorithm> +#include <iostream> +#include <memory> namespace yage { @@ -29,12 +31,17 @@ bool EntityManager::is_valid(Entity entity) const return false; } -EntityManager &EntityManager::add_component(Entity entity, - BaseComponent *component) +EntityManager & +EntityManager::add_component(Entity entity, + std::unique_ptr<BaseComponent> &&component) { auto id = component->getGroup(); component_masks_[entity] = component_masks_[entity] | ComponentMask(1 << id); + if (id+1 > component_group_.size()) { + component_group_.resize(id+1); + } + component_group_[id].add(std::move(component)); return *this; } diff --git a/yage/entity/entity.h b/yage/entity/entity.h index 2aa31a66..93bea8fb 100644 --- a/yage/entity/entity.h +++ b/yage/entity/entity.h @@ -1,9 +1,12 @@ #pragma once -#include <vector> - #include "component.h" +#include <functional> +#include <iostream> +#include <memory> +#include <vector> + namespace yage { @@ -24,17 +27,35 @@ public: Entity create_entity(); EntityManager &delete_entity(Entity entity); bool is_valid(Entity entity) const; - EntityManager &add_component(Entity entity, BaseComponent *component); + EntityManager &add_component(Entity entity, + std::unique_ptr<BaseComponent> &&component); + template <typename T> + EntityManager &each(std::function<void(T &)> update); private: Entity update_next_entity(); Entity next_entity_ = 0; -public: std::vector<ComponentGroup> component_group_; std::vector<ComponentMask> component_masks_; std::vector<Entity> deleted_; }; +template <typename T> +EntityManager &EntityManager::each(std::function<void(T &)> update) +{ + T c; + auto id = static_cast<BaseComponent *>(&c)->getGroup(); + for (auto it = component_group_[id].begin(); + it != component_group_[id].end(); ++it) { + auto iteration = it - component_group_[id].begin(); + if (is_valid(iteration) && component_masks_[iteration][id]) { + update(*static_cast<T *>((*it).get())); + } + } + + return *this; +} + } // namespace yage |