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:
@@ -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) {}
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user