ShitEngine
基于 C++20 与 SDL3 的轻量级 2D 游戏引擎
载入中...
搜索中...
未找到
EventBus.h
浏览该文件的文档.
1#pragma once
2#include "Event.h"
3#include <functional>
4#include <typeindex>
5#include <unordered_map>
6#include <vector>
7#include <memory>
8#include <queue>
9#include <mutex>
10
11namespace Shit {
12
31public:
32 using HandlerID = uint64_t;
33
34 template<typename EventType>
35 static HandlerID Subscribe(std::function<void(const EventType&)> callback) {
36 static_assert(std::is_base_of_v<Event, EventType>, "EventType must inherit from Event");
37 return GetInstance().subscribe<EventType>(std::move(callback));
38 }
39
40 template<typename EventType>
41 static void Unsubscribe(HandlerID id) {
42 GetInstance().unsubscribe<EventType>(id);
43 }
44
45 template<typename EventType>
46 static void Emit(const EventType& event) {
47 GetInstance().emitEvent<EventType>(event);
48 }
49
50 static void ProcessEvents() {
51 GetInstance().processEvents();
52 }
53
54 template<typename EventType>
55 static void Clear() {
56 GetInstance().clear<EventType>();
57 }
58
59 static void ClearAll() {
60 GetInstance().clearAll();
61 }
62
64
65 EventBus(const EventBus&) = delete;
66 EventBus& operator=(const EventBus&) = delete;
67 EventBus(EventBus&&) = delete;
69
70private:
71 friend class EngineContext;
72 EventBus() = default;
73 ~EventBus() = default;
74
75 struct ListenerEntry {
76 HandlerID id;
77 std::function<void(const Event&)> callback;
78 };
79
80 template<typename EventType>
81 HandlerID subscribe(std::function<void(const EventType&)> callback) {
82 std::lock_guard<std::mutex> lock(m_mutex);
83 HandlerID id = m_nextID++;
84 m_listeners[std::type_index(typeid(EventType))].push_back({
85 id,
86 [cb = std::move(callback)](const Event& e) {
87 cb(static_cast<const EventType&>(e));
88 }
89 });
90 return id;
91 }
92
93 template<typename EventType>
94 void unsubscribe(HandlerID id) {
95 std::lock_guard<std::mutex> lock(m_mutex);
96 auto it = m_listeners.find(std::type_index(typeid(EventType)));
97 if (it == m_listeners.end()) return;
98 auto& vec = it->second;
99 vec.erase(std::remove_if(vec.begin(), vec.end(),
100 [id](const ListenerEntry& entry) { return entry.id == id; }),
101 vec.end());
102 }
103
104 template<typename EventType>
105 // 注:方法名用 emitEvent 而非 emit —— Qt 将 emit 定义为空宏,同名成员在含 Qt 的 TU 会展开成非法语法
106 void emitEvent(const EventType& event) {
107 std::lock_guard<std::mutex> lock(m_mutex);
108 m_eventQueue.push(std::make_shared<EventType>(event));
109 }
110
111 void processEvents();
112
113 template<typename EventType>
114 void clear() {
115 std::lock_guard<std::mutex> lock(m_mutex);
116 m_listeners.erase(std::type_index(typeid(EventType)));
117 }
118
119 void clearAll();
120
121 std::unordered_map<std::type_index, std::vector<ListenerEntry>> m_listeners;
122 std::queue<std::shared_ptr<Event>> m_eventQueue;
123 std::mutex m_mutex;
124 HandlerID m_nextID = 0;
125};
126
127} // namespace Shit
#define SHIT_API
定义 Core.h:14
static EventBus & GetInstance()
static void Clear()
定义 EventBus.h:55
static void Unsubscribe(HandlerID id)
定义 EventBus.h:41
EventBus & operator=(EventBus &&)=delete
uint64_t HandlerID
定义 EventBus.h:32
EventBus(EventBus &&)=delete
friend class EngineContext
定义 EventBus.h:71
static HandlerID Subscribe(std::function< void(const EventType &)> callback)
定义 EventBus.h:35
EventBus & operator=(const EventBus &)=delete
static void Emit(const EventType &event)
定义 EventBus.h:46
static void ProcessEvents()
定义 EventBus.h:50
EventBus(const EventBus &)=delete
static void ClearAll()
定义 EventBus.h:59
定义 AudioPlayer.h:10
事件基类,所有自定义事件须继承此结构体
定义 Event.h:9