diff --git a/src/Engine.h b/src/Engine.h index c063960..2d8215c 100755 --- a/src/Engine.h +++ b/src/Engine.h @@ -38,6 +38,7 @@ public: m_InputManager->Update(dt); m_World->Update(dt); m_Renderer->Draw(dt); + m_EventBroker->Clear(); glfwPollEvents(); } diff --git a/src/EventBroker.cpp b/src/EventBroker.cpp index 68354c9..118eddf 100644 --- a/src/EventBroker.cpp +++ b/src/EventBroker.cpp @@ -1,5 +1,6 @@ #include "PrecompiledHeader.h" #include "EventBroker.h" +#include "Events/BindKey.h" BaseEventRelay::~BaseEventRelay() { @@ -11,12 +12,18 @@ BaseEventRelay::~BaseEventRelay() void EventBroker::Unsubscribe(BaseEventRelay &relay) // ? { - auto itpair = m_Subscribers.equal_range(relay.m_TypeName); + auto contextIt = m_ContextRelays.find(relay.m_ContextTypeName); + if (contextIt == m_ContextRelays.end()) + return; + + auto eventRelays = contextIt->second; + + auto itpair = eventRelays.equal_range(relay.m_EventTypeName); for (auto it = itpair.first; it != itpair.second; ++it) { if (it->second == &relay) { - m_Subscribers.erase(it); + eventRelays.erase(it); break; } } @@ -25,5 +32,37 @@ void EventBroker::Unsubscribe(BaseEventRelay &relay) // ? void EventBroker::Subscribe(BaseEventRelay &relay) { relay.m_Broker = this; - m_Subscribers.insert(std::make_pair(relay.m_TypeName, &relay)); -} \ No newline at end of file + m_ContextRelays[relay.m_ContextTypeName].insert(std::make_pair(relay.m_EventTypeName, &relay)); +} + +int EventBroker::Process(std::string contextTypeName) +{ + auto it = m_ContextRelays.find(contextTypeName); + if (it == m_ContextRelays.end()) + return 0; + + EventRelays_t &relays = it->second; + + int eventsProcessed = 0; + for (auto &pair : *m_EventQueueRead) + { + 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) + { + auto relay = it2->second; + relay->Receive(event); + eventsProcessed++; + } + } + + return eventsProcessed; +} + +void EventBroker::Clear() +{ + std::swap(m_EventQueueRead, m_EventQueueWrite); + m_EventQueueWrite->clear(); +} diff --git a/src/EventBroker.h b/src/EventBroker.h index f8877e8..e29437a 100644 --- a/src/EventBroker.h +++ b/src/EventBroker.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -23,19 +24,22 @@ class BaseEventRelay friend class EventBroker; protected: - BaseEventRelay(std::string typeName) - : m_TypeName(typeName), m_Broker(nullptr) { } + BaseEventRelay(std::string contextTypeName, std::string eventTypeName) + : m_ContextTypeName(contextTypeName) + , m_EventTypeName(eventTypeName) + , m_Broker(nullptr) { } ~BaseEventRelay(); public: - virtual bool Receive(const Event &event) = 0; + virtual bool Receive(const std::shared_ptr event) = 0; protected: - std::string m_TypeName; + std::string m_ContextTypeName; + std::string m_EventTypeName; EventBroker* m_Broker; }; -template +template class EventRelay : public BaseEventRelay { public: @@ -43,24 +47,24 @@ public: EventRelay() : m_Callback(nullptr) - , BaseEventRelay(typeid(EventType).name()) { } + , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) { } EventRelay(CallbackType callback) : m_Callback(callback) - , BaseEventRelay(typeid(EventType).name()) { } + , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) { } protected: - bool Receive(const Event &event) override; + bool Receive(const std::shared_ptr event) override; private: CallbackType m_Callback; }; -template -bool EventRelay::Receive(const Event &event) +template +bool EventRelay::Receive(const std::shared_ptr event) { if (m_Callback != nullptr) { - return m_Callback(static_cast(event)); + return m_Callback(*static_cast(event.get())); } else { @@ -70,26 +74,75 @@ bool EventRelay::Receive(const Event &event) class EventBroker { -template friend class EventRelay; +template friend class EventRelay; public: + EventBroker() + { + m_EventQueueRead = std::make_shared(); + m_EventQueueWrite = std::make_shared(); + } + + void Subscribe(BaseEventRelay &relay); template void Publish(const EventType &event); - void Subscribe(BaseEventRelay &relay); + // Process all events no matter the context. + /*void Process() + { + + }*/ + /* + Process all events in a given context. + Returns: Number of events processed + */ + template + int Process(); + int Process(std::string contextTypeName); + void Clear(); void Unsubscribe(BaseEventRelay &relay); + template + void UnsubscribeAll(); private: - std::unordered_multimap m_Subscribers; -}; + typedef std::string ContextTypeName_t; // typeid(ContextType).name() + typedef std::string EventTypeName_t; // typeid(EventType).name() + typedef std::unordered_multimap EventRelays_t; + typedef std::unordered_map ContextRelays_t; + ContextRelays_t m_ContextRelays; + + typedef std::list>> EventQueue_t; + std::shared_ptr m_EventQueueRead; + std::shared_ptr m_EventQueueWrite; +}; template void EventBroker::Publish(const EventType &event) { - auto itpair = m_Subscribers.equal_range(typeid(EventType).name()); + /*auto itpair = m_Subscribers.equal_range(typeid(EventType).name()); for (auto it = itpair.first; it != itpair.second; ++it) { it->second->Receive(event); + }*/ + + m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr(new EventType(event)))); +} + +template +int EventBroker::Process() +{ + const std::string contextTypeName = typeid(ContextType).name(); + return Process(contextTypeName); +} + +template +void EventBroker::UnsubscribeAll() +{ + const std::string contextTypeName = typeid(ContextType).name(); + auto contextIt = m_ContextRelays.find(contextTypeName); + if (contextIt != m_ContextRelays.end()) + { + m_ContextRelays.erase(contextIt); } } diff --git a/src/InputController.h b/src/InputController.h index 7afd5d5..39c26b1 100644 --- a/src/InputController.h +++ b/src/InputController.h @@ -7,6 +7,7 @@ #include "Events/InputCommand.h" #include "Events/MouseMove.h" +template class InputController { public: @@ -26,8 +27,8 @@ protected: std::shared_ptr<::EventBroker> EventBroker; private: - EventRelay m_EInputCommand; - EventRelay m_EMouseMove; + EventRelay m_EInputCommand; + EventRelay m_EMouseMove; }; #endif // InputController_h__ diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 8c15fea..b20e072 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -13,6 +13,8 @@ void InputManager::Initialize() void InputManager::Update(double dt) { + EventBroker->Process(); + m_LastKeyState = m_CurrentKeyState; m_LastMouseState = m_CurrentMouseState; m_LastMouseX = m_CurrentMouseX; diff --git a/src/InputManager.h b/src/InputManager.h index 6b56c92..69827ba 100644 --- a/src/InputManager.h +++ b/src/InputManager.h @@ -39,9 +39,9 @@ private: GLFWwindow* m_GLFWWindow; std::shared_ptr<::EventBroker> EventBroker; - EventRelay m_ELockMouse; + EventRelay m_ELockMouse; bool OnLockMouse(const Events::LockMouse &event); - EventRelay m_EUnlockMouse; + EventRelay m_EUnlockMouse; bool OnUnlockMouse(const Events::UnlockMouse &event); std::array m_CurrentKeyState; diff --git a/src/Systems/DebugSystem.h b/src/Systems/DebugSystem.h index 9db4de6..bbf7cd5 100644 --- a/src/Systems/DebugSystem.h +++ b/src/Systems/DebugSystem.h @@ -19,7 +19,7 @@ public: void Update(double dt) override; - EventRelay m_EKeyDown; + EventRelay m_EKeyDown; bool OnKeyDown(const Events::KeyDown &event); //void UpdateEntity(double dt, EntityID entity, EntityID parent) override; diff --git a/src/Systems/FreeSteeringSystem.h b/src/Systems/FreeSteeringSystem.h index b94466b..61a453d 100755 --- a/src/Systems/FreeSteeringSystem.h +++ b/src/Systems/FreeSteeringSystem.h @@ -27,7 +27,7 @@ private: std::unique_ptr m_InputController; }; -class FreeSteeringSystem::FreeSteeringInputController : InputController +class FreeSteeringSystem::FreeSteeringInputController : InputController { public: FreeSteeringInputController(std::shared_ptr<::EventBroker> eventBroker) diff --git a/src/Systems/HelicopterSteeringSystem.h b/src/Systems/HelicopterSteeringSystem.h index ed91096..742ce70 100644 --- a/src/Systems/HelicopterSteeringSystem.h +++ b/src/Systems/HelicopterSteeringSystem.h @@ -27,7 +27,7 @@ private: std::map m_TimeSinceLastShot; }; -class HelicopterSteeringSystem::HelicopterSteeringInputController : InputController +class HelicopterSteeringSystem::HelicopterSteeringInputController : InputController { public: HelicopterSteeringInputController(std::shared_ptr<::EventBroker> eventBroker) diff --git a/src/Systems/InputSystem.h b/src/Systems/InputSystem.h index d13c249..9d51d2a 100755 --- a/src/Systems/InputSystem.h +++ b/src/Systems/InputSystem.h @@ -45,28 +45,28 @@ private: std::unordered_map> m_GamepadButtonBindings; // Gamepad::Button -> command string // Input events - EventRelay m_EKeyDown; + EventRelay m_EKeyDown; bool OnKeyDown(const Events::KeyDown &event); - EventRelay m_EKeyUp; + EventRelay m_EKeyUp; bool OnKeyUp(const Events::KeyUp &event); - EventRelay m_EMousePress; + EventRelay m_EMousePress; bool OnMousePress(const Events::MousePress &event); - EventRelay m_EMouseRelease; + EventRelay m_EMouseRelease; bool OnMouseRelease(const Events::MouseRelease &event); - EventRelay m_EGamepadAxis; + EventRelay m_EGamepadAxis; bool OnGamepadAxis(const Events::GamepadAxis &event); - EventRelay m_EGamepadButtonDown; + EventRelay m_EGamepadButtonDown; bool OnGamepadButtonDown(const Events::GamepadButtonDown &event); - EventRelay m_EGamepadButtonUp; + EventRelay m_EGamepadButtonUp; bool OnGamepadButtonUp(const Events::GamepadButtonUp &event); // Input binding events - EventRelay m_EBindKey; + EventRelay m_EBindKey; bool OnBindKey(const Events::BindKey &event); - EventRelay m_EBindMouseButton; + EventRelay m_EBindMouseButton; bool OnBindMouseButton(const Events::BindMouseButton &event); - EventRelay m_EBindGamepadAxis; + EventRelay m_EBindGamepadAxis; bool OnBindGamepadAxis(const Events::BindGamepadAxis &event); - EventRelay m_EBindGamepadButton; + EventRelay m_EBindGamepadButton; bool OnBindGamepadButton(const Events::BindGamepadButton &event); float GetCommandTotalValue(std::string command); diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h index 1e173db..d58be0f 100644 --- a/src/Systems/PhysicsSystem.h +++ b/src/Systems/PhysicsSystem.h @@ -158,13 +158,13 @@ private: hkpGroupFilter* m_CollisionFilter; // Events - EventRelay m_ETankSteer; + EventRelay m_ETankSteer; bool OnTankSteer(const Events::TankSteer &event); - EventRelay m_ESetVelocity; + EventRelay m_ESetVelocity; bool OnSetVelocity(const Events::SetVelocity &event); - EventRelay m_EApplyForce; + EventRelay m_EApplyForce; bool OnApplyForce(const Events::ApplyForce &event); - EventRelay m_EApplyPointImpulse; + EventRelay m_EApplyPointImpulse; bool OnApplyPointImpulse(const Events::ApplyPointImpulse &event); EventRelay m_EEnableCollisions; diff --git a/src/Systems/SoundSystem.h b/src/Systems/SoundSystem.h index 7fbc5aa..00ae091 100755 --- a/src/Systems/SoundSystem.h +++ b/src/Systems/SoundSystem.h @@ -44,7 +44,7 @@ private: //unsigned long dataSize; // Events - EventRelay m_EPlaySound; + EventRelay m_EPlaySound; bool OnPlaySound(const Events::PlaySound &event); std::map m_Sources; diff --git a/src/Systems/TankSteeringSystem.h b/src/Systems/TankSteeringSystem.h index a3bcb61..f348b02 100644 --- a/src/Systems/TankSteeringSystem.h +++ b/src/Systems/TankSteeringSystem.h @@ -49,7 +49,7 @@ namespace Systems std::map m_TimeSinceLastShot; }; - class TankSteeringSystem::TankSteeringInputController : InputController + class TankSteeringSystem::TankSteeringInputController : InputController { public: TankSteeringInputController(std::shared_ptr<::EventBroker> eventBroker, int playerID) diff --git a/src/World.cpp b/src/World.cpp index d0c3817..699811e 100755 --- a/src/World.cpp +++ b/src/World.cpp @@ -36,7 +36,9 @@ void World::Update(double dt) { for (auto pair : m_Systems) { + const std::string &type = pair.first; auto system = pair.second; + m_EventBroker->Process(type); system->Update(dt); RecursiveUpdate(system, dt, 0); }