소스 검색

Lesson 17.5

Godzil 3 년 전
부모
커밋
6a5e4803c0
4개의 변경된 파일91개의 추가작업 그리고 2개의 파일을 삭제
  1. 19 0
      source/include/Event.h
  2. 70 2
      source/include/EventBus.h
  3. 1 0
      source/include/Events/Collision.h
  4. 1 0
      source/include/Game.h

+ 19 - 0
source/include/Event.h

@@ -0,0 +1,19 @@
+/*
+ * 2D Game Engine 
+ * Event.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_EVENT_H
+#define GAMEENGINE_SOURCE_INCLUDE_EVENT_H
+
+class Event
+{
+public:
+    Event() = default;
+};
+
+#endif /* GAMEENGINE_SOURCE_INCLUDE_EVENT_H */

+ 70 - 2
source/include/EventBus.h

@@ -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 */

+ 1 - 0
source/include/Events/Collision.h

@@ -11,6 +11,7 @@
 #define GAMEENGINE_SOURCE_INCLUDE_EVENTS_COLLISION_H
 
 #include <ECS.h>
+#include <Event.h>
 
 class CollisionEvent : public Event
 {

+ 1 - 0
source/include/Game.h

@@ -15,6 +15,7 @@
 
 #include <ECS.h>
 #include <AssetStore.h>
+#include <EventBus.h>
 
 const uint8_t FPS = 60;
 const uint32_t MILLISECS_PER_FRAME = 1000 / FPS;