EventBus.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * 2D Game Engine
  3. * EventBus.h:
  4. * Based on pikuma.com 2D game engine in C++ and Lua course
  5. * Copyright (c) 2021 986-Studio. All rights reserved.
  6. *
  7. * Created by Manoël Trapier on 16/02/2021.
  8. */
  9. #ifndef GAMEENGINE_SOURCE_INCLUDE_EVENTBUS_H
  10. #define GAMEENGINE_SOURCE_INCLUDE_EVENTBUS_H
  11. #include <map>
  12. #include <typeindex>
  13. #include <memory>
  14. #include <list>
  15. #include <Logger.h>
  16. #include <Event.h>
  17. class IEventCallback
  18. {
  19. private:
  20. virtual void Call(Event &e) = 0;
  21. public:
  22. virtual ~IEventCallback() = default;
  23. void Execute(Event &e)
  24. {
  25. this->Call(e);
  26. }
  27. };
  28. template<typename TOwner, typename TEvent> class EventCallback : public IEventCallback
  29. {
  30. private:
  31. typedef void (TOwner::*CallbackFunction)(TEvent &event);
  32. TOwner *ownerInstance;
  33. CallbackFunction callbackFunction;
  34. virtual void Call(Event &e) override
  35. {
  36. std::invoke(this->callbackFunction, this->ownerInstance, static_cast<TEvent &>(e));
  37. }
  38. public:
  39. EventCallback(TOwner *ownerInstance, CallbackFunction callbackFunction) : ownerInstance(ownerInstance),
  40. callbackFunction(callbackFunction) {};
  41. virtual ~EventCallback() override = default;
  42. };
  43. typedef std::list<std::unique_ptr<IEventCallback>> HandlerList;
  44. class EventBus
  45. {
  46. private:
  47. std::map<std::type_index, std::unique_ptr<HandlerList>> subscribers;
  48. public:
  49. EventBus() = default;
  50. ~EventBus() = default;
  51. void reset()
  52. {
  53. this->subscribers.clear();
  54. }
  55. template<typename TEvent, typename TOwner>void subscribeToEvent(TOwner *ownerInstance, void (TOwner::*callbackFunction)(TEvent &))
  56. {
  57. auto subscriber = std::make_unique<EventCallback<TOwner, TEvent>>(ownerInstance, callbackFunction);
  58. if (!this->subscribers[typeid(TEvent)].get())
  59. {
  60. this->subscribers[typeid(TEvent)] = std::make_unique<HandlerList>();
  61. }
  62. this->subscribers[typeid(TEvent)]->push_back(std::move(subscriber));
  63. }
  64. template<typename T, typename ...TArgs> void emitEvent(TArgs &&...args)
  65. {
  66. auto handlers = this->subscribers[typeid(T)].get();
  67. if (handlers)
  68. {
  69. for (auto it = handlers->begin(); it != handlers->end(); it++)
  70. {
  71. auto handler = it->get();
  72. T event(std::forward<TArgs>(args)...);
  73. handler->Execute(event);
  74. }
  75. }
  76. }
  77. };
  78. #endif /* GAMEENGINE_SOURCE_INCLUDE_EVENTBUS_H */