aboutsummaryrefslogtreecommitdiffstats
path: root/yage/entity
diff options
context:
space:
mode:
Diffstat (limited to 'yage/entity')
-rw-r--r--yage/entity/README.md9
-rw-r--r--yage/entity/component.cpp16
-rw-r--r--yage/entity/component.h10
-rw-r--r--yage/entity/entity.cpp11
-rw-r--r--yage/entity/entity.h29
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