@@ -78,11 +78,15 @@ bool hasListened[int(EVENT_TYPES::EVENT_COUNT)] = {false};
78
78
79
79
// ////////////////// APIs ////////////////////
80
80
81
+ Local<Value> listenCancellable (ScriptEngine* engine, const string& eventName, const Local<Function>& func);
81
82
Local<Value> McClass::listen (const Arguments& args) {
82
83
CHECK_ARGS_COUNT (args, 2 );
83
84
CHECK_ARG_TYPE (args[0 ], ValueKind::kString );
84
85
CHECK_ARG_TYPE (args[1 ], ValueKind::kFunction );
85
86
87
+ if (args.size () >= 3 && args[2 ].isBoolean () && args[2 ].asBoolean ().value ()) {
88
+ return listenCancellable (EngineScope::currentEngine (), args[0 ].asString ().toString (), args[1 ].asFunction ());
89
+ }
86
90
try {
87
91
return Boolean::newBoolean (
88
92
LLSEAddEventListener (EngineScope::currentEngine (), args[0 ].asString ().toString (), args[1 ].asFunction ())
@@ -91,6 +95,29 @@ Local<Value> McClass::listen(const Arguments& args) {
91
95
CATCH (" Fail to Bind Listener!" );
92
96
}
93
97
98
+ Local<Value> listenCancellable (ScriptEngine* engine, const string& eventName, const Local<Function>& func) {
99
+ try {
100
+ auto event_enum = magic_enum::enum_cast<EVENT_TYPES>(eventName);
101
+ auto eventId = int (event_enum.value ());
102
+ auto event =
103
+ listenerList[eventId].insert (listenerList[eventId].end (), {engine, script::Global<Function>(func)});
104
+ if (!hasListened[eventId]) {
105
+ hasListened[eventId] = true ;
106
+ EnableEventListener (eventId);
107
+ }
108
+ return Function::newFunction ([eventId{eventId}, event{event}](const Arguments&) -> Local<Value> {
109
+ listenerList[eventId].erase (event);
110
+ return Local<Value>();
111
+ });
112
+ } catch (...) {
113
+ lse::LegacyScriptEngine::getInstance ().getSelf ().getLogger ().error (" Event {} not found!" _tr (eventName));
114
+ lse::LegacyScriptEngine::getInstance ().getSelf ().getLogger ().error (
115
+ " In Plugin: " + getEngineData (engine)->pluginName
116
+ );
117
+ return Local<Value>();
118
+ }
119
+ }
120
+
94
121
// ////////////////// Funcs ////////////////////
95
122
96
123
bool LLSEAddEventListener (ScriptEngine* engine, const string& eventName, const Local<Function>& func) {
@@ -135,14 +162,13 @@ bool LLSECallEventsOnHotLoad(ScriptEngine* engine) {
135
162
}
136
163
137
164
bool LLSECallEventsOnUnload (ScriptEngine* engine) {
138
- if ( ll::getGamingStatus () == ll::GamingStatus::Running) {
139
- ll::service::getLevel ()->forEachPlayer ([&](Player& pl) -> bool {
140
- FakeCallEvent (engine, EVENT_TYPES::onLeft, PlayerClass::newPlayer (&pl));
141
- return true ;
142
- });
143
- }
165
+ // Players may be online when the server is stopping
166
+ ll::service::getLevel ()->forEachPlayer ([&](Player& pl) -> bool {
167
+ FakeCallEvent (engine, EVENT_TYPES::onLeft, PlayerClass::newPlayer (&pl));
168
+ return true ;
169
+ });
170
+ EngineScope scope (engine);
144
171
for (auto & [index, cb] : getEngineData (engine)->unloadCallbacks ) {
145
- EngineScope scope (engine);
146
172
try {
147
173
cb (engine);
148
174
}
0 commit comments