/* * 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 #include #include #include #include #include class IEventCallback { private: virtual void Call(Event &e) = 0; public: virtual ~IEventCallback() = default; void Execute(Event &e) { this->Call(e); } }; template 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(e)); } public: EventCallback(TOwner *ownerInstance, CallbackFunction callbackFunction) : ownerInstance(ownerInstance), callbackFunction(callbackFunction) {}; virtual ~EventCallback() override = default; }; typedef std::list> HandlerList; class EventBus { private: std::map> subscribers; public: EventBus() = default; ~EventBus() = default; void reset() { this->subscribers.clear(); } templatevoid subscribeToEvent(TOwner *ownerInstance, void (TOwner::*callbackFunction)(TEvent &)) { auto subscriber = std::make_unique>(ownerInstance, callbackFunction); if (!this->subscribers[typeid(TEvent)].get()) { this->subscribers[typeid(TEvent)] = std::make_unique(); } this->subscribers[typeid(TEvent)]->push_back(std::move(subscriber)); } template 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(args)...); handler->Execute(event); } } } }; #endif /* GAMEENGINE_SOURCE_INCLUDE_EVENTBUS_H */