Add ecs ComponentListener

- Add ecs ComponentListener which listens to Component addition and
  removal
- Add RefCounter class used to keep track of moves and copies
This commit is contained in:
Thraix
2023-05-29 17:49:37 +02:00
parent 5a615ecc4e
commit 3ec9bcd152
24 changed files with 351 additions and 70 deletions
@@ -0,0 +1,19 @@
#pragma once
#include "copium/ecs/ECSManager.h"
namespace Copium
{
template <typename Component>
class ComponentListener
{
public:
using component_type = Component;
friend class ECSManager;
protected:
ECSManager* manager;
public:
virtual void Added(EntityId entityId, Component& component) {}
virtual void Removed(EntityId entityId, Component& component) {}
};
}
+31 -9
View File
@@ -3,6 +3,7 @@
#include "copium/ecs/Config.h"
#include "copium/ecs/EntitySet.h"
#include "copium/ecs/ComponentPoolBase.h"
#include "copium/ecs/ComponentListener.h"
#include <vector>
@@ -14,8 +15,18 @@ namespace Copium
using Iterator = typename std::vector<Component>::iterator;
private:
std::vector<Component> components;
ComponentListener<Component>* listener = nullptr;
public:
ComponentPool()
{}
~ComponentPool() override
{
if(listener)
delete listener;
}
ComponentPool(EntityId entity, const Component& component)
{
Emplace(entity, component);
@@ -25,21 +36,27 @@ namespace Copium
{
components.push_back(component);
entities.Emplace(entity);
if(listener)
listener->Added(entity, components.back());
return components.back();
}
void Pop()
{
components.pop_back();
entities.Pop();
}
bool Erase(EntityId entity)
bool Erase(EntityId entity) override
{
size_t index = entities.Find(entity);
if (!entities.Erase(entity))
return false;
components.erase(components.begin() + index);
if (listener)
{
auto it = components.begin() + index;
Component component = *it;
components.erase(it);
listener->Removed(entity, component);
}
else
{
components.erase(components.begin() + index);
}
return true;
}
@@ -61,13 +78,18 @@ namespace Copium
return nullptr;
}
void SetComponentListener(ComponentListener<Component>* listener)
{
ComponentPool::listener = listener;
}
Component& operator[](size_t index)
{
CP_ASSERT(index < components.size(), "Index Out of Bound Exception");
return components[index];
}
size_t Size()
size_t Size() override
{
return components.size();
}
@@ -15,7 +15,6 @@ namespace Copium
virtual ~ComponentPoolBase() = default;
virtual size_t Size() = 0;
virtual void Pop() = 0;
virtual bool Erase(EntityId entity) = 0;
std::vector<EntityId>& GetEntities();
const std::vector<EntityId>& GetEntities() const;
+19
View File
@@ -48,6 +48,25 @@ namespace Copium
bool ValidEntity(EntityId entity);
void Each(std::function<void(EntityId)> function);
template <typename Listener, typename... Args>
void SetComponentListener(const Args&... args)
{
using Component = typename Listener::component_type;
auto pool = GetComponentPool<Component>();
Listener* listener = new Listener{args...};
listener->manager = this;
if (pool)
{
pool->SetComponentListener(listener);
}
else
{
ComponentPool<Component>* pool{new ComponentPool<Component>{}};
componentPool.emplace(GetComponentId<Component>(), pool);
pool->SetComponentListener(listener);
}
}
template <typename... Components>
std::tuple<Components&...> AddComponents(EntityId entity, Components&&... components)
{