|
@@ -10,14 +10,82 @@
|
|
|
#ifndef GAMEENGINE_SOURCE_INCLUDE_EVENTBUS_H
|
|
|
#define GAMEENGINE_SOURCE_INCLUDE_EVENTBUS_H
|
|
|
|
|
|
+#include <map>
|
|
|
+#include <typeindex>
|
|
|
+#include <memory>
|
|
|
+#include <list>
|
|
|
+
|
|
|
+#include <Logger.h>
|
|
|
+#include <Event.h>
|
|
|
+
|
|
|
+class IEventCallback
|
|
|
+{
|
|
|
+private:
|
|
|
+ virtual void Call(Event &e) = 0;
|
|
|
+
|
|
|
+public:
|
|
|
+ virtual ~IEventCallback() = default;
|
|
|
+
|
|
|
+ void Execute(Event &e)
|
|
|
+ {
|
|
|
+ this->Call(e);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+template<typename TOwner, typename TEvent> class EventCallback : public IEventCallback
|
|
|
+{
|
|
|
+private:
|
|
|
+ typedef void (TOwner::*CallbackFunction)(TEvent &event);
|
|
|
+ TOwner *ownerInstance;
|
|
|
+ CallbackFunction callbackFunction;
|
|
|
+
|
|
|
+ virtual void Call(Event &e) override
|
|
|
+ {
|
|
|
+ std::invoke(this->callbackFunction, this->ownerInstance, static_cast<TEvent &>(e));
|
|
|
+ }
|
|
|
+
|
|
|
+public:
|
|
|
+ EventCallback(TOwner *ownerInstance, CallbackFunction callbackFunction) : ownerInstance(ownerInstance),
|
|
|
+ callbackFunction(callbackFunction) {};
|
|
|
+ virtual ~EventCallback() override = default;
|
|
|
+};
|
|
|
+
|
|
|
+typedef std::list<std::unique_ptr<IEventCallback>> HandlerList;
|
|
|
+
|
|
|
class EventBus
|
|
|
{
|
|
|
+private:
|
|
|
+ std::map<std::type_index, std::unique_ptr<HandlerList>> subscribers;
|
|
|
+
|
|
|
public:
|
|
|
EventBus() = default;
|
|
|
~EventBus() = default;
|
|
|
|
|
|
- void SubscribeToEvent<T>();
|
|
|
- void EmitEvent<T>();
|
|
|
+ template<typename TEvent, typename TOwner>void SubscribeToEvent(TOwner *ownerInstance, void (TOwner::*callbackFunction)(TEvent &))
|
|
|
+ {
|
|
|
+ auto subscriber = std::make_unique<EventCallback<TOwner, TEvent>>(ownerInstance, callbackFunction);
|
|
|
+
|
|
|
+ if (!this->subscribers[typeid(TEvent)].get())
|
|
|
+ {
|
|
|
+ this->subscribers[typeid(TEvent)] = std::make_unique<HandlerList>();
|
|
|
+ }
|
|
|
+
|
|
|
+ this->subscribers[typeid(TEvent)]->push_back(std::move(subscriber));
|
|
|
+ }
|
|
|
+
|
|
|
+ template<typename T, typename ...TArgs> void EmitEvent(TArgs &&...args)
|
|
|
+ {
|
|
|
+ auto handlers = this->subscribers[typeid(T)].get();
|
|
|
+ if (handlers)
|
|
|
+ {
|
|
|
+ for (auto it = handlers->begin(); it != handlers->end(); it++)
|
|
|
+ {
|
|
|
+ auto handler = it->get();
|
|
|
+ T event(std::forward<TArgs>(args)...);
|
|
|
+ handler->Execute(event);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
#endif /* GAMEENGINE_SOURCE_INCLUDE_EVENTBUS_H */
|