diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index 4aaa5163..d6a6b371 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -14,21 +14,28 @@ public: { } ~SystemPipeline() { - for (auto& pair : m_Systems) { - delete pair.second; + for (UnorderedSystems& group : m_OrderedSystemGroups) { + for (auto& pair : group.Systems) { + delete pair.second; + } } } template - void AddSystem(Arguments... args) + //All systems with orderlevel 0 will be updated first, then 1, 2, etc. + void AddSystem(int updateOrderLevel, Arguments... args) { + if (updateOrderLevel + 1 > m_OrderedSystemGroups.size()) { + m_OrderedSystemGroups.resize(updateOrderLevel + 1); + } + UnorderedSystems& group = m_OrderedSystemGroups[updateOrderLevel]; System* system = new T(m_EventBroker, args...); - m_Systems[typeid(T).name()] = system; + group.Systems[typeid(T).name()] = 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); + group.PureSystems[pureSystem->m_ComponentType].push_back(pureSystem); } else { LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name()); } @@ -36,41 +43,47 @@ public: if (std::is_base_of::value) { ImpureSystem* impureSystem = static_cast(system); - m_ImpureSystems.push_back(impureSystem); + group.ImpureSystems.push_back(impureSystem); } } void Update(World* world, double dt) { - // Process events - for (auto& pair : m_Systems) { - m_EventBroker->Process(pair.first); - } - - // Update - for (auto& pair : m_PureSystems) { - const std::string& componentName = pair.first; - auto& systems = pair.second; - const ComponentPool* pool = world->GetComponents(componentName); - if (pool == nullptr) { - continue; + for (UnorderedSystems& group : m_OrderedSystemGroups) { + // Process events + for (auto& pair : group.Systems) { + m_EventBroker->Process(pair.first); } - for (auto& component : *pool) { - for (auto& system : systems) { - system->UpdateComponent(world, component, dt); + + // Update + for (auto& pair : group.PureSystems) { + const std::string& componentName = pair.first; + auto& systems = pair.second; + const ComponentPool* pool = world->GetComponents(componentName); + if (pool == nullptr) { + continue; + } + for (auto& component : *pool) { + for (auto& system : systems) { + system->UpdateComponent(world, component, dt); + } } } - } - for (auto& system : m_ImpureSystems) { - system->Update(world, dt); + for (auto& system : group.ImpureSystems) { + system->Update(world, dt); + } } } private: EventBroker* m_EventBroker; - std::map m_Systems; - std::map> m_PureSystems; - std::vector m_ImpureSystems; + struct UnorderedSystems + { + std::map Systems; + std::map> PureSystems; + std::vector ImpureSystems; + }; + std::vector m_OrderedSystemGroups; }; #endif \ No newline at end of file diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index dec33a20..69929c6d 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -4,8 +4,6 @@ void CollisionSystem::UpdateComponent(World * world, ComponentWrapper & cAABB, double dt) { - //TODO: Update CollisionSystem system after PlayerSystem. - //Right now, cAABB is a component attached to any entity that should be collideable. AABB thisBox; if (!Collision::GetEntityBox(world, cAABB, thisBox)) { diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 18a533d0..7d294355 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -53,12 +53,18 @@ Game::Game(int argc, char* argv[]) // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); - m_SystemPipeline->AddSystem(); - m_SystemPipeline->AddSystem(); - m_SystemPipeline->AddSystem(m_Renderer); - m_SystemPipeline->AddSystem(); - m_SystemPipeline->AddSystem(); - m_SystemPipeline->AddSystem(); + + //All systems with orderlevel 0 will be updated first. + unsigned int updateOrderLevel = 0; + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); + m_SystemPipeline->AddSystem(updateOrderLevel); + + //Collision and TriggerSystem should update after player. + ++updateOrderLevel; + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Invoke network if (m_Config->Get("Networking.StartNetwork", false)) { diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index 7ba2b89d..84d6199d 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -47,8 +47,8 @@ GameHealthSystemTest::GameHealthSystemTest() // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); - m_SystemPipeline->AddSystem(); - m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(0); + m_SystemPipeline->AddSystem(0); //The Test //create entity which has transorm,player,model,health in it. i.e. is a player diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp index 05aa35d4..10d4d6a5 100644 --- a/src/Tests/OctTreeTestGameClass.cpp +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -45,7 +45,7 @@ Game::Game(int argc, char* argv[]) : someOctTree(AABB(-0.5f*worldSize, 0.5f*worl m_World = new HardcodedTestWorld(); m_SystemPipeline = new SystemPipeline(m_EventBroker); - m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(0); m_LastTime = glfwGetTime(); }