Add Scene with systems
- Add Scene class which populates the engine with Systems which handles all logic in the game - Add Systems to ecs
This commit is contained in:
@@ -4,6 +4,10 @@
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
ECSManager::ECSManager()
|
||||
: systemPool{std::make_unique<SystemPool>(this)}
|
||||
{}
|
||||
|
||||
ECSManager::~ECSManager()
|
||||
{
|
||||
for (auto&& components : componentPool)
|
||||
@@ -13,6 +17,11 @@ namespace Copium
|
||||
componentPool.clear();
|
||||
}
|
||||
|
||||
void ECSManager::UpdateSystems()
|
||||
{
|
||||
systemPool->Update();
|
||||
}
|
||||
|
||||
size_t ECSManager::GetEntityCount() const
|
||||
{
|
||||
return entities.size();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "copium/ecs/ComponentPool.h"
|
||||
#include "copium/ecs/Config.h"
|
||||
#include "copium/ecs/SystemPool.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <functional>
|
||||
@@ -18,10 +19,21 @@ namespace Copium
|
||||
private:
|
||||
std::unordered_set<EntityID> entities;
|
||||
std::map<std::type_index, ComponentPoolBase*> componentPool;
|
||||
|
||||
std::unique_ptr<SystemPool> systemPool;
|
||||
int currentEntityId = 1;
|
||||
public:
|
||||
ECSManager();
|
||||
~ECSManager();
|
||||
|
||||
template <typename SystemClass, typename... Args>
|
||||
SystemOrderer AddSystem(const Args&... args)
|
||||
{
|
||||
return systemPool->AddSystem(typeid(SystemClass), new SystemClass{args...});
|
||||
}
|
||||
|
||||
void UpdateSystems();
|
||||
|
||||
EntityID CreateEntity();
|
||||
void DestroyEntity(EntityID entity);
|
||||
size_t GetEntityCount() const;
|
||||
@@ -37,7 +49,7 @@ namespace Copium
|
||||
template <typename Component, typename... Args>
|
||||
Component& AddComponent(EntityID entity, Args&&... args)
|
||||
{
|
||||
return AddComponent(entity, Component(args...));
|
||||
return AddComponent(entity, Component{args...});
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
@@ -76,7 +88,7 @@ namespace Copium
|
||||
{
|
||||
auto pool = GetComponentPoolAssure<Component>();
|
||||
Component* component = pool->FindComponent(entity);
|
||||
ASSERT(component, "Entity did not contain component (entity=%u, Component=%s)", entity, typeid(Component).name());
|
||||
CP_ASSERT(component, "Entity did not contain component (entity=%u, Component=%s)", entity, typeid(Component).name());
|
||||
return *component;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/ecs/ECSManager.h"
|
||||
#include "copium/ecs/SystemBase.h"
|
||||
#include "copium/ecs/Entity.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
template <typename... Components>
|
||||
class System : public SystemBase
|
||||
{
|
||||
public:
|
||||
void Run() override
|
||||
{
|
||||
manager->Each<Components...>([&](EntityID entityId, Components&... components) { RunEntity(Entity{manager, entityId}, components...); });
|
||||
}
|
||||
|
||||
virtual void RunEntity(Entity entity, Components&... components) = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class ECSManager;
|
||||
|
||||
class SystemBase
|
||||
{
|
||||
friend class SystemPool;
|
||||
protected:
|
||||
ECSManager* manager;
|
||||
|
||||
public:
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "copium/ecs/SystemOrderer.h"
|
||||
|
||||
#include "copium/ecs/SystemPool.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
SystemOrderer::SystemOrderer(std::type_index systemId, SystemPool* systemPool)
|
||||
: systemId{systemId},
|
||||
systemPool{systemPool}
|
||||
{}
|
||||
|
||||
void SystemOrderer::Before(const std::type_index& otherSystemId)
|
||||
{
|
||||
systemPool->MoveSystemBefore(systemId, otherSystemId);
|
||||
}
|
||||
|
||||
void SystemOrderer::After(const std::type_index& otherSystemId)
|
||||
{
|
||||
systemPool->MoveSystemAfter(systemId, otherSystemId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <typeindex>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class SystemPool;
|
||||
|
||||
class SystemOrderer
|
||||
{
|
||||
private:
|
||||
std::type_index systemId;
|
||||
SystemPool* systemPool = nullptr;
|
||||
public:
|
||||
SystemOrderer(std::type_index systemId, SystemPool* systemPool);
|
||||
|
||||
template <typename Other>
|
||||
void Before()
|
||||
{
|
||||
Before(typeid(Other));
|
||||
}
|
||||
|
||||
template <typename Other>
|
||||
void After()
|
||||
{
|
||||
After(typeid(Other));
|
||||
}
|
||||
|
||||
private:
|
||||
void Before(const std::type_index& otherSystemId);
|
||||
void After(const std::type_index& otherSystemId);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "copium/ecs/SystemPool.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
SystemPool::SystemPool(ECSManager* manager)
|
||||
: manager{manager}
|
||||
{}
|
||||
|
||||
SystemPool::~SystemPool()
|
||||
{
|
||||
for (auto& system : systemOrder)
|
||||
{
|
||||
delete system;
|
||||
}
|
||||
systemOrder.clear();
|
||||
systems.clear();
|
||||
}
|
||||
|
||||
SystemOrderer SystemPool::AddSystem(const std::type_index& systemId, SystemBase* system)
|
||||
{
|
||||
system->manager = manager;
|
||||
systems.emplace(systemId, system);
|
||||
systemOrder.emplace_back(system);
|
||||
return SystemOrderer{systemId, this};
|
||||
}
|
||||
|
||||
void SystemPool::Update()
|
||||
{
|
||||
for (auto& system : systemOrder)
|
||||
{
|
||||
system->Run();
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPool::MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId)
|
||||
{
|
||||
auto it1 = systems.find(systemId);
|
||||
CP_ASSERT(it1 != systems.end(), "System does not exist in SystemPool");
|
||||
auto it2 = systems.find(afterSystemId);
|
||||
CP_ASSERT(it2 != systems.end(), "System does not exist in SystemPool");
|
||||
|
||||
auto itSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it1->second);
|
||||
auto itAfterSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it2->second);
|
||||
std::rotate(itSystemId, itSystemId + 1, itAfterSystemId);
|
||||
}
|
||||
|
||||
void SystemPool::MoveSystemBefore(const std::type_index& systemId, const std::type_index& beforeSystemId)
|
||||
{
|
||||
auto it1 = systems.find(systemId);
|
||||
CP_ASSERT(it1 != systems.end(), "System does not exist in SystemPool");
|
||||
auto it2 = systems.find(beforeSystemId);
|
||||
CP_ASSERT(it2 != systems.end(), "System does not exist in SystemPool");
|
||||
|
||||
auto itSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it1->second);
|
||||
auto itBeforeSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it2->second);
|
||||
|
||||
std::rotate(itSystemId, itSystemId + 1, itBeforeSystemId + 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/ecs/SystemBase.h"
|
||||
#include "copium/ecs/SystemOrderer.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <typeindex>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class ECSManager;
|
||||
|
||||
class SystemPool final
|
||||
{
|
||||
CP_DELETE_COPY_AND_MOVE_CTOR(SystemPool);
|
||||
private:
|
||||
ECSManager* manager;
|
||||
std::map<std::type_index, SystemBase*> systems;
|
||||
std::vector<SystemBase*> systemOrder;
|
||||
|
||||
public:
|
||||
SystemPool(ECSManager* manager);
|
||||
~SystemPool();
|
||||
SystemOrderer AddSystem(const std::type_index& systemId, SystemBase* system);
|
||||
void Update();
|
||||
|
||||
void MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId);
|
||||
void MoveSystemBefore(const std::type_index& systemId, const std::type_index& beforeSystemId);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user