2 Commits

Author SHA1 Message Date
Jace e48df894cf Better events 2014-05-23 23:41:34 +02:00
Jace 4102756e33 Beautifully broken 2014-05-22 22:04:54 +02:00
14 changed files with 142 additions and 44 deletions
+1
View File
@@ -38,6 +38,7 @@ public:
m_InputManager->Update(dt); m_InputManager->Update(dt);
m_World->Update(dt); m_World->Update(dt);
m_Renderer->Draw(dt); m_Renderer->Draw(dt);
m_EventBroker->Clear();
glfwPollEvents(); glfwPollEvents();
} }
+42 -3
View File
@@ -1,5 +1,6 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "EventBroker.h" #include "EventBroker.h"
#include "Events/BindKey.h"
BaseEventRelay::~BaseEventRelay() BaseEventRelay::~BaseEventRelay()
{ {
@@ -11,12 +12,18 @@ BaseEventRelay::~BaseEventRelay()
void EventBroker::Unsubscribe(BaseEventRelay &relay) // ? 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) for (auto it = itpair.first; it != itpair.second; ++it)
{ {
if (it->second == &relay) if (it->second == &relay)
{ {
m_Subscribers.erase(it); eventRelays.erase(it);
break; break;
} }
} }
@@ -25,5 +32,37 @@ void EventBroker::Unsubscribe(BaseEventRelay &relay) // ?
void EventBroker::Subscribe(BaseEventRelay &relay) void EventBroker::Subscribe(BaseEventRelay &relay)
{ {
relay.m_Broker = this; relay.m_Broker = this;
m_Subscribers.insert(std::make_pair(relay.m_TypeName, &relay)); 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> 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();
} }
+69 -16
View File
@@ -3,6 +3,7 @@
#include <typeinfo> #include <typeinfo>
#include <functional> #include <functional>
#include <map>
#include <unordered_map> #include <unordered_map>
#include <list> #include <list>
@@ -23,19 +24,22 @@ class BaseEventRelay
friend class EventBroker; friend class EventBroker;
protected: protected:
BaseEventRelay(std::string typeName) BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_TypeName(typeName), m_Broker(nullptr) { } : m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr) { }
~BaseEventRelay(); ~BaseEventRelay();
public: public:
virtual bool Receive(const Event &event) = 0; virtual bool Receive(const std::shared_ptr<Event> event) = 0;
protected: protected:
std::string m_TypeName; std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker; EventBroker* m_Broker;
}; };
template <typename EventType> template <typename ContextType, typename EventType>
class EventRelay : public BaseEventRelay class EventRelay : public BaseEventRelay
{ {
public: public:
@@ -43,24 +47,24 @@ public:
EventRelay() EventRelay()
: m_Callback(nullptr) : m_Callback(nullptr)
, BaseEventRelay(typeid(EventType).name()) { } , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) { }
EventRelay(CallbackType callback) EventRelay(CallbackType callback)
: m_Callback(callback) : m_Callback(callback)
, BaseEventRelay(typeid(EventType).name()) { } , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) { }
protected: protected:
bool Receive(const Event &event) override; bool Receive(const std::shared_ptr<Event> event) override;
private: private:
CallbackType m_Callback; CallbackType m_Callback;
}; };
template <typename EventType> template <typename ContextType, typename EventType>
bool EventRelay<EventType>::Receive(const Event &event) bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
{ {
if (m_Callback != nullptr) if (m_Callback != nullptr)
{ {
return m_Callback(static_cast<const EventType&>(event)); return m_Callback(*static_cast<const EventType*>(event.get()));
} }
else else
{ {
@@ -70,26 +74,75 @@ bool EventRelay<EventType>::Receive(const Event &event)
class EventBroker class EventBroker
{ {
template <typename EventType> friend class EventRelay; template <typename ContextType, typename EventType> friend class EventRelay;
public: public:
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
void Subscribe(BaseEventRelay &relay);
template <typename EventType> template <typename EventType>
void Publish(const EventType &event); 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 <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Clear();
void Unsubscribe(BaseEventRelay &relay); void Unsubscribe(BaseEventRelay &relay);
template <typename ContextType>
void UnsubscribeAll();
private: private:
std::unordered_multimap<std::string, BaseEventRelay*> m_Subscribers; typedef std::string ContextTypeName_t; // typeid(ContextType).name()
}; typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
};
template <typename EventType> template <typename EventType>
void EventBroker::Publish(const EventType &event) 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) for (auto it = itpair.first; it != itpair.second; ++it)
{ {
it->second->Receive(event); it->second->Receive(event);
}*/
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
}
template <typename ContextType>
int EventBroker::Process()
{
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
}
template <typename ContextType>
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);
} }
} }
+3 -2
View File
@@ -7,6 +7,7 @@
#include "Events/InputCommand.h" #include "Events/InputCommand.h"
#include "Events/MouseMove.h" #include "Events/MouseMove.h"
template <typename EventContext>
class InputController class InputController
{ {
public: public:
@@ -26,8 +27,8 @@ protected:
std::shared_ptr<::EventBroker> EventBroker; std::shared_ptr<::EventBroker> EventBroker;
private: private:
EventRelay<Events::InputCommand> m_EInputCommand; EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
EventRelay<Events::MouseMove> m_EMouseMove; EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
}; };
#endif // InputController_h__ #endif // InputController_h__
+2
View File
@@ -13,6 +13,8 @@ void InputManager::Initialize()
void InputManager::Update(double dt) void InputManager::Update(double dt)
{ {
EventBroker->Process<InputManager>();
m_LastKeyState = m_CurrentKeyState; m_LastKeyState = m_CurrentKeyState;
m_LastMouseState = m_CurrentMouseState; m_LastMouseState = m_CurrentMouseState;
m_LastMouseX = m_CurrentMouseX; m_LastMouseX = m_CurrentMouseX;
+2 -2
View File
@@ -39,9 +39,9 @@ private:
GLFWwindow* m_GLFWWindow; GLFWwindow* m_GLFWWindow;
std::shared_ptr<::EventBroker> EventBroker; std::shared_ptr<::EventBroker> EventBroker;
EventRelay<Events::LockMouse> m_ELockMouse; EventRelay<InputManager, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse &event); bool OnLockMouse(const Events::LockMouse &event);
EventRelay<Events::UnlockMouse> m_EUnlockMouse; EventRelay<InputManager, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse &event); bool OnUnlockMouse(const Events::UnlockMouse &event);
std::array<int, GLFW_KEY_LAST+1> m_CurrentKeyState; std::array<int, GLFW_KEY_LAST+1> m_CurrentKeyState;
+1 -1
View File
@@ -19,7 +19,7 @@ public:
void Update(double dt) override; void Update(double dt) override;
EventRelay<Events::KeyDown> m_EKeyDown; EventRelay<DebugSystem, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown &event); bool OnKeyDown(const Events::KeyDown &event);
//void UpdateEntity(double dt, EntityID entity, EntityID parent) override; //void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
+1 -1
View File
@@ -27,7 +27,7 @@ private:
std::unique_ptr<FreeSteeringInputController> m_InputController; std::unique_ptr<FreeSteeringInputController> m_InputController;
}; };
class FreeSteeringSystem::FreeSteeringInputController : InputController class FreeSteeringSystem::FreeSteeringInputController : InputController<FreeSteeringSystem>
{ {
public: public:
FreeSteeringInputController(std::shared_ptr<::EventBroker> eventBroker) FreeSteeringInputController(std::shared_ptr<::EventBroker> eventBroker)
+1 -1
View File
@@ -27,7 +27,7 @@ private:
std::map<EntityID, double> m_TimeSinceLastShot; std::map<EntityID, double> m_TimeSinceLastShot;
}; };
class HelicopterSteeringSystem::HelicopterSteeringInputController : InputController class HelicopterSteeringSystem::HelicopterSteeringInputController : InputController<HelicopterSteeringSystem>
{ {
public: public:
HelicopterSteeringInputController(std::shared_ptr<::EventBroker> eventBroker) HelicopterSteeringInputController(std::shared_ptr<::EventBroker> eventBroker)
+11 -11
View File
@@ -45,28 +45,28 @@ private:
std::unordered_map<Gamepad::Button, std::tuple<std::string, float>> m_GamepadButtonBindings; // Gamepad::Button -> command string std::unordered_map<Gamepad::Button, std::tuple<std::string, float>> m_GamepadButtonBindings; // Gamepad::Button -> command string
// Input events // Input events
EventRelay<Events::KeyDown> m_EKeyDown; EventRelay<InputSystem, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown &event); bool OnKeyDown(const Events::KeyDown &event);
EventRelay<Events::KeyUp> m_EKeyUp; EventRelay<InputSystem, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp &event); bool OnKeyUp(const Events::KeyUp &event);
EventRelay<Events::MousePress> m_EMousePress; EventRelay<InputSystem, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress &event); bool OnMousePress(const Events::MousePress &event);
EventRelay<Events::MouseRelease> m_EMouseRelease; EventRelay<InputSystem, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease &event); bool OnMouseRelease(const Events::MouseRelease &event);
EventRelay<Events::GamepadAxis> m_EGamepadAxis; EventRelay<InputSystem, Events::GamepadAxis> m_EGamepadAxis;
bool OnGamepadAxis(const Events::GamepadAxis &event); bool OnGamepadAxis(const Events::GamepadAxis &event);
EventRelay<Events::GamepadButtonDown> m_EGamepadButtonDown; EventRelay<InputSystem, Events::GamepadButtonDown> m_EGamepadButtonDown;
bool OnGamepadButtonDown(const Events::GamepadButtonDown &event); bool OnGamepadButtonDown(const Events::GamepadButtonDown &event);
EventRelay<Events::GamepadButtonUp> m_EGamepadButtonUp; EventRelay<InputSystem, Events::GamepadButtonUp> m_EGamepadButtonUp;
bool OnGamepadButtonUp(const Events::GamepadButtonUp &event); bool OnGamepadButtonUp(const Events::GamepadButtonUp &event);
// Input binding events // Input binding events
EventRelay<Events::BindKey> m_EBindKey; EventRelay<InputSystem, Events::BindKey> m_EBindKey;
bool OnBindKey(const Events::BindKey &event); bool OnBindKey(const Events::BindKey &event);
EventRelay<Events::BindMouseButton> m_EBindMouseButton; EventRelay<InputSystem, Events::BindMouseButton> m_EBindMouseButton;
bool OnBindMouseButton(const Events::BindMouseButton &event); bool OnBindMouseButton(const Events::BindMouseButton &event);
EventRelay<Events::BindGamepadAxis> m_EBindGamepadAxis; EventRelay<InputSystem, Events::BindGamepadAxis> m_EBindGamepadAxis;
bool OnBindGamepadAxis(const Events::BindGamepadAxis &event); bool OnBindGamepadAxis(const Events::BindGamepadAxis &event);
EventRelay<Events::BindGamepadButton> m_EBindGamepadButton; EventRelay<InputSystem, Events::BindGamepadButton> m_EBindGamepadButton;
bool OnBindGamepadButton(const Events::BindGamepadButton &event); bool OnBindGamepadButton(const Events::BindGamepadButton &event);
float GetCommandTotalValue(std::string command); float GetCommandTotalValue(std::string command);
+4 -4
View File
@@ -113,13 +113,13 @@ private:
hkpWorld* m_PhysicsWorld; hkpWorld* m_PhysicsWorld;
// Events // Events
EventRelay<Events::TankSteer> m_ETankSteer; EventRelay<PhysicsSystem, Events::TankSteer> m_ETankSteer;
bool OnTankSteer(const Events::TankSteer &event); bool OnTankSteer(const Events::TankSteer &event);
EventRelay<Events::SetVelocity> m_ESetVelocity; EventRelay<PhysicsSystem, Events::SetVelocity> m_ESetVelocity;
bool OnSetVelocity(const Events::SetVelocity &event); bool OnSetVelocity(const Events::SetVelocity &event);
EventRelay<Events::ApplyForce> m_EApplyForce; EventRelay<PhysicsSystem, Events::ApplyForce> m_EApplyForce;
bool OnApplyForce(const Events::ApplyForce &event); bool OnApplyForce(const Events::ApplyForce &event);
EventRelay<Events::ApplyPointImpulse> m_EApplyPointImpulse; EventRelay<PhysicsSystem, Events::ApplyPointImpulse> m_EApplyPointImpulse;
bool OnApplyPointImpulse(const Events::ApplyPointImpulse &event); bool OnApplyPointImpulse(const Events::ApplyPointImpulse &event);
void SetUpPhysicsState(EntityID entity, EntityID parent); void SetUpPhysicsState(EntityID entity, EntityID parent);
+1 -1
View File
@@ -44,7 +44,7 @@ private:
//unsigned long dataSize; //unsigned long dataSize;
// Events // Events
EventRelay<Events::PlaySound> m_EPlaySound; EventRelay<SoundSystem, Events::PlaySound> m_EPlaySound;
bool OnPlaySound(const Events::PlaySound &event); bool OnPlaySound(const Events::PlaySound &event);
std::map<Component*, ALuint> m_Sources; std::map<Component*, ALuint> m_Sources;
+1 -1
View File
@@ -37,7 +37,7 @@ namespace Systems
std::map<EntityID, double> m_TimeSinceLastShot; std::map<EntityID, double> m_TimeSinceLastShot;
}; };
class TankSteeringSystem::TankSteeringInputController : InputController class TankSteeringSystem::TankSteeringInputController : InputController<TankSteeringSystem>
{ {
public: public:
TankSteeringInputController(std::shared_ptr<::EventBroker> eventBroker, int playerID) TankSteeringInputController(std::shared_ptr<::EventBroker> eventBroker, int playerID)
+2
View File
@@ -36,7 +36,9 @@ void World::Update(double dt)
{ {
for (auto pair : m_Systems) for (auto pair : m_Systems)
{ {
const std::string &type = pair.first;
auto system = pair.second; auto system = pair.second;
m_EventBroker->Process(type);
system->Update(dt); system->Update(dt);
RecursiveUpdate(system, dt, 0); RecursiveUpdate(system, dt, 0);
} }