Added support for "Impure" systems, which only update once per frame and contain their own logic for manipulating the world, instead of relying on a single list of components.

This commit is contained in:
2015-12-13 13:37:14 +01:00
parent 2e321e15a5
commit 8a6030bf57
5 changed files with 60 additions and 28 deletions
+29 -9
View File
@@ -7,19 +7,39 @@
class System
{
friend class SystemPipeline;
public:
System(EventBroker* eventBroker, std::string componentType)
protected:
System(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
, m_ComponentType(componentType)
{ }
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
protected:
std::string m_ComponentType;
EventBroker* m_EventBroker;
};
class PureSystem : public System
{
friend class SystemPipeline;
protected:
PureSystem(EventBroker* eventBroker, std::string componentType)
: System(eventBroker)
, m_ComponentType(componentType)
{ }
const std::string m_ComponentType;
virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0;
};
class ImpureSystem : public System
{
friend class SystemPipeline;
protected:
ImpureSystem(EventBroker* eventBroker)
: System(eventBroker)
{ }
virtual void Update(World* world, double dt) = 0;
};
#endif
+24 -9
View File
@@ -14,7 +14,7 @@ public:
{ }
~SystemPipeline()
{
for (auto& pair : m_Systems) {
for (auto& pair : m_PureSystems) {
for (auto& system : pair.second) {
delete system;
}
@@ -25,17 +25,28 @@ public:
void AddSystem(Arguments... args)
{
System* system = new T(m_EventBroker, args...);
if (!system->m_ComponentType.empty()) {
m_Systems[system->m_ComponentType].push_back(system);
} else {
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name());
delete system;
if (std::is_base_of<PureSystem, T>::value) {
PureSystem* pureSystem = static_cast<PureSystem*>(system);
if (!pureSystem->m_ComponentType.empty()) {
m_PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
} else {
LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name());
if (std::is_base_of<ImpureSystem, T>::value) {
delete system;
}
}
}
if (std::is_base_of<ImpureSystem, T>::value) {
ImpureSystem* impureSystem = static_cast<ImpureSystem*>(system);
m_ImpureSystems.push_back(impureSystem);
}
}
void Update(World* world, double dt)
{
for (auto& pair : m_Systems) {
for (auto& pair : m_PureSystems) {
const std::string& componentName = pair.first;
auto& systems = pair.second;
const ComponentPool* pool = world->GetComponents(componentName);
@@ -44,15 +55,19 @@ public:
}
for (auto& component : *pool) {
for (auto& system : systems) {
system->Update(world, component, dt);
system->UpdateComponent(world, component, dt);
}
}
}
for (auto& system : m_ImpureSystems) {
system->Update(world, dt);
}
}
private:
EventBroker* m_EventBroker;
std::unordered_map<std::string, std::vector<System*>> m_Systems;
std::unordered_map<std::string, std::vector<PureSystem*>> m_PureSystems;
std::vector<ImpureSystem*> m_ImpureSystems;
};
#endif
+3 -3
View File
@@ -18,17 +18,17 @@ struct KeyInput
bool Right = false;
};
class PlayerSystem : public System
class PlayerSystem : public PureSystem
{
public:
PlayerSystem(EventBroker* eventBroker)
: System(eventBroker, "Player")
: PureSystem(eventBroker, "Player")
{
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp);
}
virtual void Update(World* world, ComponentWrapper& player, double dt) override;
virtual void UpdateComponent(World* world, ComponentWrapper& player, double dt) override;
private:
float m_Speed = 5;
+3 -5
View File
@@ -1,16 +1,14 @@
#include "Common.h"
#include "Core/System.h"
class RaptorCopterSystem : public System
class RaptorCopterSystem : public PureSystem
{
public:
RaptorCopterSystem(EventBroker* eventBroker)
: System(eventBroker, "RaptorCopter")
: PureSystem(eventBroker, "RaptorCopter")
{ }
virtual void Initialize() { }
virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override
virtual void UpdateComponent(World* world, ComponentWrapper& raptorCopter, double dt) override
{
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
+1 -2
View File
@@ -1,7 +1,6 @@
#include "PlayerSystem.h"
void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt)
void PlayerSystem::UpdateComponent(World * world, ComponentWrapper & player, double dt)
{
if (input.Forward) {
m_Direction.z = -1;