From 34cbbb3eb1b214b372b3962bc2d6a80ca1c183b9 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 6 Jan 2016 11:20:16 +0100 Subject: [PATCH 1/2] Fixed exit crash(es) --- include/Engine/Core/System.h | 5 +++ include/Engine/Core/SystemPipeline.h | 6 ++-- include/Engine/Rendering/Renderer.h | 3 ++ src/Engine/Rendering/Renderer.cpp | 10 +++--- src/Game/Game.cpp | 46 +++++----------------------- 5 files changed, 21 insertions(+), 49 deletions(-) diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index 57b0d2cc..75bd3882 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -7,10 +7,13 @@ class System { + friend class SystemPipeline; + protected: System(EventBroker* eventBroker) : m_EventBroker(eventBroker) { } + virtual ~System() = default; EventBroker* m_EventBroker; }; @@ -24,6 +27,7 @@ protected: : System(eventBroker) , m_ComponentType(componentType) { } + virtual ~PureSystem() = default; const std::string m_ComponentType; @@ -38,6 +42,7 @@ protected: ImpureSystem(EventBroker* eventBroker) : System(eventBroker) { } + virtual ~ImpureSystem() = default; virtual void Update(World* world, double dt) = 0; }; diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index 78ebc966..4aaa5163 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -14,10 +14,8 @@ public: { } ~SystemPipeline() { - for (auto& pair : m_PureSystems) { - for (auto& system : pair.second) { - delete system; - } + for (auto& pair : m_Systems) { + delete pair.second; } } diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b4aae346..19b48e1a 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -12,6 +12,7 @@ #include "../Core/World.h" #include "PickingPass.h" #include "DrawScenePass.h" +#include "DebugCameraInputController.h" #define TILE_SIZE 16 @@ -45,6 +46,8 @@ private: //----------------------Variables----------------------// EventBroker* m_EventBroker; + std::shared_ptr> m_DebugCameraInputController; + Texture* m_ErrorTexture; Texture* m_WhiteTexture; float m_CameraMoveSpeed; diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 21ff6c5a..208f339b 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -1,5 +1,4 @@ #include "Rendering/Renderer.h" -#include "Rendering/DebugCameraInputController.h" void Renderer::Initialize() { @@ -10,6 +9,7 @@ void Renderer::Initialize() if (m_Camera == nullptr) { m_Camera = m_DefaultCamera; } + m_DebugCameraInputController = std::make_shared>(m_EventBroker, -1); TEMPCreateLights(); InitializeRenderPasses(); @@ -89,8 +89,6 @@ void Renderer::InitializeShaders() void Renderer::InputUpdate(double dt) { - static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); - glm::vec3 m_Position = m_Camera->Position(); if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS) { @@ -120,9 +118,9 @@ void Renderer::InputUpdate(double dt) m_CameraMoveSpeed = 0.5f; } - firstPersonInputController.Update(dt); - m_Camera->SetOrientation(firstPersonInputController.Orientation()); - m_Camera->SetPosition(firstPersonInputController.Position()); + m_DebugCameraInputController->Update(dt); + m_Camera->SetOrientation(m_DebugCameraInputController->Orientation()); + m_Camera->SetPosition(m_DebugCameraInputController->Position()); } void Renderer::Update(double dt) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index f1582d5d..033db642 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -27,7 +27,7 @@ Game::Game(int argc, char* argv[]) 0, m_Config->Get("Video.Width", 1280), m_Config->Get("Video.Height", 720) - )); + )); m_Renderer->Initialize(); m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get("Video.FOV", 90.f))); @@ -64,17 +64,17 @@ Game::Game(int argc, char* argv[]) networkFunction(); } m_LastTime = glfwGetTime(); - - debugInitialize(); } Game::~Game() { - // Call before to ensure that thread closes correctly. - //if (m_IsClientOrServer) - // m_ClientOrServer.Close(); - + delete m_SystemPipeline; + delete m_World; delete m_FrameStack; + delete m_InputProxy; + delete m_InputManager; + delete m_Renderer; + delete m_RenderQueueFactory; delete m_EventBroker; } @@ -103,7 +103,6 @@ void Game::Tick() // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); - debugTick(dt); m_Renderer->Update(dt); m_EventBroker->Process(); @@ -115,37 +114,6 @@ void Game::Tick() m_EventBroker->Clear(); } - -bool Game::debugOnInputCommand(const Events::InputCommand& e) -{ - if (e.Command == "DebugReload" && e.Value == 1) { - std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); - if (!mapToLoad.empty()) { - delete m_World; - m_World = new World(); - ResourceManager::Release("EntityXMLFile", mapToLoad); - ResourceManager::Load(mapToLoad)->PopulateWorld(m_World); - } - } - if (e.Command == "SwitchToServer" && e.Value > 0) { - m_ClientOrServer = new Server(); - LOG_INFO("Switching to server"); - m_ClientOrServer->Start(m_World, m_EventBroker); - } - if (e.Command == "SwitchToClient" && e.Value > 0) { - m_ClientOrServer = new Client(m_Config); - m_ClientOrServer->Start(m_World, m_EventBroker); - LOG_INFO("Switching to client"); - } - - return false; -} - -void Game::debugInitialize() -{ - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); -} - void Game::debugTick(double dt) { m_EventBroker->Process(); From 49884d7e600da087d3268aa543b5f679cbdc2006 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 6 Jan 2016 13:47:02 +0100 Subject: [PATCH 2/2] Fix for crash when unsubscription during event processing (untested) --- include/Engine/Core/EventBroker.h | 8 ++++-- src/Engine/Core/EventBroker.cpp | 47 ++++++++++++++++++------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/include/Engine/Core/EventBroker.h b/include/Engine/Core/EventBroker.h index f04c7715..dde5242a 100644 --- a/include/Engine/Core/EventBroker.h +++ b/include/Engine/Core/EventBroker.h @@ -13,6 +13,8 @@ relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \ m_EventBroker->Subscribe(relay); +typedef unsigned int EventID; + class EventBroker; class BaseEventRelay @@ -31,6 +33,7 @@ public: virtual bool Receive(const std::shared_ptr event) = 0; protected: + EventID m_EventID; std::string m_ContextTypeName; std::string m_EventTypeName; EventBroker* m_Broker; @@ -95,6 +98,7 @@ public: private: bool m_IsProcessing = false; + EventID m_NextEventID = 0; typedef std::string ContextTypeName_t; // typeid(ContextType).name() typedef std::string EventTypeName_t; // typeid(EventType).name() @@ -103,14 +107,14 @@ private: typedef std::unordered_map ContextRelays_t; ContextRelays_t m_ContextRelays; std::vector m_RelaysToSubscribe; - std::vector m_RelaysToUnsubscribe; + std::vector> m_RelaysToUnsubscribe; typedef std::list>> EventQueue_t; std::shared_ptr m_EventQueueRead; std::shared_ptr m_EventQueueWrite; void subscribeImmediate(BaseEventRelay& relay); - void unsubscribeImmediate(BaseEventRelay& relay); + void unsubscribeImmediate(std::tuple identifier); }; template diff --git a/src/Engine/Core/EventBroker.cpp b/src/Engine/Core/EventBroker.cpp index 76c243e8..6767878f 100644 --- a/src/Engine/Core/EventBroker.cpp +++ b/src/Engine/Core/EventBroker.cpp @@ -2,21 +2,24 @@ BaseEventRelay::~BaseEventRelay() { - if (m_Broker != nullptr) { - m_Broker->Unsubscribe(*this); - } + if (m_Broker != nullptr) { + m_Broker->Unsubscribe(*this); + } } -void EventBroker::Unsubscribe(BaseEventRelay &relay) // ? +void EventBroker::Unsubscribe(BaseEventRelay& relay) // ? { - if (m_IsProcessing) { - m_RelaysToUnsubscribe.push_back(&relay); - } else { - unsubscribeImmediate(relay); - } + auto identifier = std::make_tuple(relay.m_EventID, relay.m_ContextTypeName, relay.m_EventTypeName); + + relay.m_Broker = nullptr; + if (m_IsProcessing) { + m_RelaysToUnsubscribe.push_back(identifier); + } else { + unsubscribeImmediate(identifier); + } } -void EventBroker::Subscribe(BaseEventRelay &relay) +void EventBroker::Subscribe(BaseEventRelay& relay) { if (m_IsProcessing) { m_RelaysToSubscribe.push_back(&relay); @@ -38,12 +41,11 @@ int EventBroker::Process(std::string contextTypeName) int eventsProcessed = 0; for (auto &pair : *m_EventQueueRead) { - std::string &eventTypeName = pair.first; + std::string& eventTypeName = pair.first; std::shared_ptr event = pair.second; auto itpair = relays.equal_range(eventTypeName); - for (auto it2 = itpair.first; it2 != itpair.second; it2++) - { + for (auto it2 = itpair.first; it2 != itpair.second; it2++) { std::string name = it2->first; BaseEventRelay* relay = it2->second; relay->Receive(event); @@ -60,8 +62,8 @@ int EventBroker::Process(std::string contextTypeName) m_RelaysToSubscribe.clear(); // Process pending unsubscriptions - for (auto& r : m_RelaysToUnsubscribe) { - unsubscribeImmediate(*r); + for (auto& identifier : m_RelaysToUnsubscribe) { + unsubscribeImmediate(identifier); } m_RelaysToUnsubscribe.clear(); @@ -81,21 +83,26 @@ void EventBroker::Clear() void EventBroker::subscribeImmediate(BaseEventRelay& relay) { relay.m_Broker = this; + relay.m_EventID = m_NextEventID++; m_ContextRelays[relay.m_ContextTypeName].insert(std::make_pair(relay.m_EventTypeName, &relay)); } -void EventBroker::unsubscribeImmediate(BaseEventRelay& relay) +void EventBroker::unsubscribeImmediate(std::tuple identifier) { - auto contextIt = m_ContextRelays.find(relay.m_ContextTypeName); + EventID eventID; + ContextTypeName_t contextTypeName; + EventTypeName_t eventTypeName; + std::tie(eventID, contextTypeName, eventTypeName) = identifier; + + auto contextIt = m_ContextRelays.find(contextTypeName); if (contextIt == m_ContextRelays.end()) { return; } auto eventRelays = contextIt->second; - auto itpair = eventRelays.equal_range(relay.m_EventTypeName); + auto itpair = eventRelays.equal_range(eventTypeName); for (auto it = itpair.first; it != itpair.second; ++it) { - if (it->second == &relay) { - relay.m_Broker = nullptr; + if (it->second->m_EventID == eventID) { eventRelays.erase(it); break; }