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 class System
{ {
friend class SystemPipeline; protected:
System(EventBroker* eventBroker)
public:
System(EventBroker* eventBroker, std::string componentType)
: m_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; 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 #endif
+24 -9
View File
@@ -14,7 +14,7 @@ public:
{ } { }
~SystemPipeline() ~SystemPipeline()
{ {
for (auto& pair : m_Systems) { for (auto& pair : m_PureSystems) {
for (auto& system : pair.second) { for (auto& system : pair.second) {
delete system; delete system;
} }
@@ -25,17 +25,28 @@ public:
void AddSystem(Arguments... args) void AddSystem(Arguments... args)
{ {
System* system = new T(m_EventBroker, args...); System* system = new T(m_EventBroker, args...);
if (!system->m_ComponentType.empty()) {
m_Systems[system->m_ComponentType].push_back(system); if (std::is_base_of<PureSystem, T>::value) {
} else { PureSystem* pureSystem = static_cast<PureSystem*>(system);
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name()); if (!pureSystem->m_ComponentType.empty()) {
delete system; 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) void Update(World* world, double dt)
{ {
for (auto& pair : m_Systems) { for (auto& pair : m_PureSystems) {
const std::string& componentName = pair.first; const std::string& componentName = pair.first;
auto& systems = pair.second; auto& systems = pair.second;
const ComponentPool* pool = world->GetComponents(componentName); const ComponentPool* pool = world->GetComponents(componentName);
@@ -44,15 +55,19 @@ public:
} }
for (auto& component : *pool) { for (auto& component : *pool) {
for (auto& system : systems) { for (auto& system : systems) {
system->Update(world, component, dt); system->UpdateComponent(world, component, dt);
} }
} }
} }
for (auto& system : m_ImpureSystems) {
system->Update(world, dt);
}
} }
private: private:
EventBroker* m_EventBroker; 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 #endif
+3 -3
View File
@@ -18,17 +18,17 @@ struct KeyInput
bool Right = false; bool Right = false;
}; };
class PlayerSystem : public System class PlayerSystem : public PureSystem
{ {
public: public:
PlayerSystem(EventBroker* eventBroker) PlayerSystem(EventBroker* eventBroker)
: System(eventBroker, "Player") : PureSystem(eventBroker, "Player")
{ {
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown); EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp); 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: private:
float m_Speed = 5; float m_Speed = 5;
+3 -5
View File
@@ -1,16 +1,14 @@
#include "Common.h" #include "Common.h"
#include "Core/System.h" #include "Core/System.h"
class RaptorCopterSystem : public System class RaptorCopterSystem : public PureSystem
{ {
public: public:
RaptorCopterSystem(EventBroker* eventBroker) RaptorCopterSystem(EventBroker* eventBroker)
: System(eventBroker, "RaptorCopter") : PureSystem(eventBroker, "RaptorCopter")
{ } { }
virtual void Initialize() { } virtual void UpdateComponent(World* world, ComponentWrapper& raptorCopter, double dt) override
virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override
{ {
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform"); ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"]; (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" #include "PlayerSystem.h"
void PlayerSystem::UpdateComponent(World * world, ComponentWrapper & player, double dt)
void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt)
{ {
if (input.Forward) { if (input.Forward) {
m_Direction.z = -1; m_Direction.z = -1;