44
55// ////////////////// Funcs ////////////////////
66
7+ struct EventListener ;
8+
79void InitBasicEventListeners ();
810void EnableEventListener (int eventId);
9-
10- bool LLSEAddEventListener (ScriptEngine* engine, const std::string& eventName, const Local<Function>& func);
11+ optional_ref<EventListener>
12+ LLSEAddEventListener (ScriptEngine* engine, const std::string& eventName, const Local<Function>& func);
1113bool LLSERemoveAllEventListeners (ScriptEngine* engine);
1214bool LLSECallEventsOnHotLoad (ScriptEngine* engine);
1315bool LLSECallEventsOnUnload (ScriptEngine* engine);
@@ -118,13 +120,36 @@ enum class EVENT_TYPES : int {
118120
119121// ////////////////// Listeners ////////////////////
120122
121- struct ListenerListType {
123+ inline std::set<EVENT_TYPES> dirtyEventTypes{};
124+
125+ struct EventListener {
122126 ScriptEngine* engine;
123127 script::Global<Function> func;
128+ // mark as removed and remove at next tick
129+ using RemovedRef = std::shared_ptr<std::reference_wrapper<bool >>;
130+ EVENT_TYPES type;
131+ bool removed = false ;
132+ RemovedRef removedRef{std::make_shared<RemovedRef::element_type>(std::ref (removed))};
133+
134+ [[nodiscard]] inline auto remover () const {
135+ return [ref{RemovedRef::weak_type{removedRef}}, type{type}]() -> bool {
136+ auto removed = ref.lock ();
137+ if (removed) {
138+ removed->get () = true ;
139+ dirtyEventTypes.emplace (type);
140+ }
141+ return !!removed;
142+ };
143+ }
144+ EventListener (ScriptEngine* engine, script::Global<Function> func, EVENT_TYPES type)
145+ : engine(engine),
146+ func (std::move(func)),
147+ type(type) {};
148+ EventListener (const EventListener&) = delete;
124149};
125150
126151// 监听器表
127- extern std::list<ListenerListType > listenerList[int (EVENT_TYPES::EVENT_COUNT)];
152+ extern std::list<EventListener > listenerList[int (EVENT_TYPES::EVENT_COUNT)];
128153
129154// 监听器历史
130155extern bool hasListened[int (EVENT_TYPES::EVENT_COUNT)];
@@ -134,17 +159,17 @@ inline std::string EventTypeToString(EVENT_TYPES e) { return std::string(magic_e
134159
135160#define CallEvent (type, ...) \
136161 [&]() { \
137- std::list<ListenerListType >& nowList = listenerList[(int )type]; \
138- bool returnValue = true ; \
139- for (auto & listener : nowList) { \
162+ std::list<EventListener >& nowList = listenerList[(int )type]; \
163+ bool returnValue = true ; \
164+ for (auto & listener : nowList | std::views::filter ([]( auto & l) { return !l. removed ; })) { \
140165 EngineScope enter (listener.engine ); \
141166 CallEventImpl (listener, returnValue, type, __VA_ARGS__); \
142167 } \
143168 return returnValue; \
144169 }()
145170
146171template <typename ... T>
147- void CallEventImpl (ListenerListType & listener, bool & returnValue, EVENT_TYPES type, T&&... args) {
172+ void CallEventImpl (EventListener & listener, bool & returnValue, EVENT_TYPES type, T&&... args) {
148173 try {
149174 auto result = listener.func .get ().call ({}, args...);
150175 if (result.isBoolean () && result.asBoolean ().value () == false ) {
@@ -168,14 +193,14 @@ void CallEventImpl(ListenerListType& listener, bool& returnValue, EVENT_TYPES ty
168193}
169194
170195#define FakeCallEvent (engine, type, ...) \
171- std::list<ListenerListType >& nowList = listenerList[(int )type]; \
172- for (auto & listener : nowList) { \
196+ std::list<EventListener >& nowList = listenerList[(int )type]; \
197+ for (auto & listener : nowList | std::views::filter([]( auto & l) { return !l. removed ; })) { \
173198 EngineScope enter (listener.engine ); \
174199 FakeCallEventImpl (listener, engine, type, __VA_ARGS__); \
175200 }
176201
177202template <typename ... T>
178- void FakeCallEventImpl (ListenerListType & listener, ScriptEngine* engine, EVENT_TYPES type, T&&... args) {
203+ void FakeCallEventImpl (EventListener & listener, ScriptEngine* engine, EVENT_TYPES type, T&&... args) {
179204 if (listener.engine == engine) {
180205 try {
181206 listener.func .get ().call ({}, args...);
0 commit comments