From 8a6030bf571f5dfbd90dce58e71026b1e09dcc81 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 13:37:14 +0100 Subject: [PATCH] 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. --- include/Engine/Core/System.h | 38 +++++++++++++++++++++------- include/Engine/Core/SystemPipeline.h | 33 +++++++++++++++++------- include/Game/PlayerSystem.h | 6 ++--- include/Game/RaptorCopterSystem.h | 8 +++--- src/Game/PlayerSystem.cpp | 3 +-- 5 files changed, 60 insertions(+), 28 deletions(-) diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index 37719c51..57b0d2cc 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -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 \ No newline at end of file diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index e4b8bb1f..0f32b422 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -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::value) { + PureSystem* pureSystem = static_cast(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::value) { + delete system; + } + } + } + + if (std::is_base_of::value) { + ImpureSystem* impureSystem = static_cast(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> m_Systems; + std::unordered_map> m_PureSystems; + std::vector m_ImpureSystems; }; #endif \ No newline at end of file diff --git a/include/Game/PlayerSystem.h b/include/Game/PlayerSystem.h index 18752ac6..82dee6b8 100644 --- a/include/Game/PlayerSystem.h +++ b/include/Game/PlayerSystem.h @@ -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; diff --git a/include/Game/RaptorCopterSystem.h b/include/Game/RaptorCopterSystem.h index cdd6dd90..913efdb3 100644 --- a/include/Game/RaptorCopterSystem.h +++ b/include/Game/RaptorCopterSystem.h @@ -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"]; diff --git a/src/Game/PlayerSystem.cpp b/src/Game/PlayerSystem.cpp index 736ea105..db5fe067 100644 --- a/src/Game/PlayerSystem.cpp +++ b/src/Game/PlayerSystem.cpp @@ -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;