@@ -129,8 +129,8 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
129129 return ll::makeStringError (" Plugin has already loaded" );
130130 }
131131
132- auto & scriptEngine = * EngineManager::newEngine (manifest.name );
133- auto plugin = std::make_shared<Plugin>(manifest);
132+ auto scriptEngine = EngineManager::newEngine (manifest.name );
133+ auto plugin = std::make_shared<Plugin>(manifest);
134134
135135 try {
136136 script::EngineScope engineScope (scriptEngine);
@@ -139,30 +139,30 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
139139 getEngineOwnData ()->logger = ll::io::LoggerRegistry::getInstance ().getOrCreate (manifest.name );
140140
141141#ifdef LEGACY_SCRIPT_ENGINE_BACKEND_PYTHON
142- scriptEngine. eval (" import sys as _llse_py_sys_module" );
142+ scriptEngine-> eval (" import sys as _llse_py_sys_module" );
143143 std::error_code ec;
144144
145145 // add plugin-own site-packages to sys.path
146146 std::string pluginSitePackageFormatted = ll::string_utils::u8str2str (
147147 std::filesystem::canonical (realPackageInstallDir.make_preferred (), ec).u8string ()
148148 );
149149 if (!ec) {
150- scriptEngine. eval (" _llse_py_sys_module.path.insert(0, r'" + pluginSitePackageFormatted + " ')" );
150+ scriptEngine-> eval (" _llse_py_sys_module.path.insert(0, r'" + pluginSitePackageFormatted + " ')" );
151151 }
152152 // add plugin source dir to sys.path
153153 std::string sourceDirFormatted =
154154 ll::string_utils::u8str2str (std::filesystem::canonical (dirPath.make_preferred ()).u8string ());
155- scriptEngine. eval (" _llse_py_sys_module.path.insert(0, r'" + sourceDirFormatted + " ')" );
155+ scriptEngine-> eval (" _llse_py_sys_module.path.insert(0, r'" + sourceDirFormatted + " ')" );
156156
157157 // set __file__ and __name__
158158 std::string entryPathFormatted = ll::string_utils::u8str2str (
159159 std::filesystem::canonical (std::filesystem::path (entryPath).make_preferred ()).u8string ()
160160 );
161- scriptEngine. set (" __file__" , entryPathFormatted);
161+ scriptEngine-> set (" __file__" , entryPathFormatted);
162162 // engine->set("__name__", String::newString("__main__"));
163163#endif
164164
165- BindAPIs (& scriptEngine);
165+ BindAPIs (scriptEngine);
166166
167167 auto & self = LegacyScriptEngine::getInstance ().getSelf ();
168168#ifndef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS // NodeJs backend load depends code in another place
@@ -172,14 +172,14 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
172172 if (!baseLibContent) {
173173 return ll::makeStringError (" Failed to read BaseLib at {0}" _tr (baseLibPath.string ()));
174174 }
175- scriptEngine. eval (baseLibContent.value ());
175+ scriptEngine-> eval (baseLibContent.value ());
176176#endif
177177 // Load the plugin entry.
178178 auto entryPath = plugin->getModDir () / manifest.entry ;
179179 getEngineOwnData ()->plugin = plugin;
180180#ifdef LEGACY_SCRIPT_ENGINE_BACKEND_PYTHON
181181 if (!PythonHelper::loadPluginCode (
182- & scriptEngine,
182+ scriptEngine,
183183 ll::string_utils::u8str2str (entryPath.u8string ()),
184184 ll::string_utils::u8str2str (dirPath.u8string ())
185185 )) {
@@ -188,7 +188,7 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
188188#endif
189189#ifdef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
190190 if (!NodeJsHelper::loadPluginCode (
191- & scriptEngine,
191+ scriptEngine,
192192 ll::string_utils::u8str2str (entryPath.u8string ()),
193193 ll::string_utils::u8str2str (dirPath.u8string ())
194194 )) {
@@ -198,46 +198,56 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
198198#if (defined LEGACY_SCRIPT_ENGINE_BACKEND_QUICKJS) || (defined LEGACY_SCRIPT_ENGINE_BACKEND_LUA)
199199 // Try loadFile
200200 try {
201- scriptEngine. loadFile (entryPath.u8string ());
201+ scriptEngine-> loadFile (entryPath.u8string ());
202202 } catch (const script::Exception&) {
203203 // loadFile failed, try eval
204204 auto pluginEntryContent = ll::file_utils::readFile (entryPath);
205205 if (!pluginEntryContent) {
206206 return ll::makeStringError (" Failed to read plugin entry at {0}" _tr (entryPath.string ()));
207207 }
208- scriptEngine. eval (pluginEntryContent.value (), entryPath.u8string ());
208+ scriptEngine-> eval (pluginEntryContent.value (), entryPath.u8string ());
209209 }
210210#endif
211211 if (ll::getGamingStatus () == ll::GamingStatus::Running) { // Is hot load
212- LLSECallEventsOnHotLoad (& scriptEngine);
212+ LLSECallEventsOnHotLoad (scriptEngine);
213213 }
214214 ExitEngineScope exit;
215215 plugin->onLoad ([](ll::mod::Mod&) { return true ; });
216216 plugin->onUnload ([](ll::mod::Mod&) { return true ; });
217217
218218 return plugin->onLoad ().transform ([&, this ] { addMod (manifest.name , plugin); });
219219 } catch (const Exception& e) {
220- EngineScope engineScope (scriptEngine);
221- auto error =
222- ll::makeStringError (" Failed to load plugin {0}: {1}\n {2}" _tr (manifest.name , e.message (), e.stacktrace ()));
223- ExitEngineScope exit;
224- LLSERemoveTimeTaskData (&scriptEngine);
225- LLSERemoveAllEventListeners (&scriptEngine);
226- LLSERemoveCmdRegister (&scriptEngine);
227- LLSERemoveCmdCallback (&scriptEngine);
228- LLSERemoveAllExportedFuncs (&scriptEngine);
229-
230- scriptEngine.getData ().reset ();
220+ if (scriptEngine) {
221+ EngineScope engineScope (scriptEngine);
222+ auto error = ll::makeStringError (
223+ " Failed to load plugin {0}: {1}\n {2}" _tr (manifest.name , e.message (), e.stacktrace ())
224+ );
225+ ExitEngineScope exit;
231226
232- EngineManager::unregisterEngine (&scriptEngine);
227+ #ifndef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
228+ LLSERemoveTimeTaskData (scriptEngine);
229+ #endif
230+ LLSERemoveAllEventListeners (scriptEngine);
231+ LLSERemoveCmdRegister (scriptEngine);
232+ LLSERemoveCmdCallback (scriptEngine);
233+ LLSERemoveAllExportedFuncs (scriptEngine);
233234
234- return error;
235+ scriptEngine->getData ().reset ();
236+ EngineManager::unregisterEngine (scriptEngine);
237+ #ifdef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
238+ NodeJsHelper::stopEngine (scriptEngine);
239+ #else
240+ scriptEngine->destroy ();
241+ #endif
242+ return error;
243+ } else {
244+ return ll::makeStringError (" Failed to load plugin {0}: {1}" _tr (manifest.name , " ScriptEngine* is nullptr" ));
245+ }
235246 }
236247}
237248
238249ll::Expected<> PluginManager::unload (std::string_view name) {
239250 try {
240- auto plugin = std::static_pointer_cast<Plugin>(getMod (name));
241251 auto scriptEngine = EngineManager::getEngine (std::string (name));
242252
243253#ifndef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
@@ -249,8 +259,10 @@ ll::Expected<> PluginManager::unload(std::string_view name) {
249259 LLSERemoveCmdCallback (scriptEngine);
250260 LLSERemoveAllExportedFuncs (scriptEngine);
251261
252- scriptEngine->getData ().reset ();
253262 EngineManager::unregisterEngine (scriptEngine);
263+ scriptEngine->getData ().reset ();
264+
265+ eraseMod (name);
254266
255267 ll::coro::keepThis ([scriptEngine]() -> ll::coro::CoroTask<> {
256268 using namespace ll ::chrono_literals;
@@ -260,11 +272,8 @@ ll::Expected<> PluginManager::unload(std::string_view name) {
260272#else
261273 scriptEngine->destroy (); // TODO: use unique_ptr to manage the engine.
262274#endif
263- co_return ;
264275 }).launch (ll::thread::ServerThreadExecutor::getDefault ());
265276
266- eraseMod (name);
267-
268277 return {};
269278 } catch (const std::exception& e) {
270279 return ll::makeStringError (" Failed to unload plugin {0}: {1}" _tr (name, e.what ()));
0 commit comments