123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- /*
- * 2D Game Engine
- * EventBus.h:
- * Based on pikuma.com 2D game engine in C++ and Lua course
- * Copyright (c) 2021 986-Studio. All rights reserved.
- *
- * Created by Manoël Trapier on 16/02/2021.
- */
- #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 reset()
- {
- this->subscribers.clear();
- }
- 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 */
|