mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 03:23:15 +01:00
Implement lifetime logic of transient plugins
This commit is contained in:
@@ -436,10 +436,10 @@ void ScriptEngine::Initialise()
|
||||
dukglue_register_global(ctx, std::make_shared<ScScenario>(), "scenario");
|
||||
|
||||
_initialised = true;
|
||||
_pluginsLoaded = false;
|
||||
_pluginsStarted = false;
|
||||
_transientPluginsEnabled = false;
|
||||
_transientPluginsStarted = false;
|
||||
|
||||
InitSharedStorage();
|
||||
LoadSharedStorage();
|
||||
ClearParkStorage();
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ void ScriptEngine::RefreshPlugins()
|
||||
}
|
||||
|
||||
// Turn on hot reload if not already enabled
|
||||
if (!_hotReloading && gConfigPlugin.enable_hot_reloading && network_get_mode() == NETWORK_MODE_NONE)
|
||||
if (!_hotReloadingInitialised && gConfigPlugin.enable_hot_reloading && network_get_mode() == NETWORK_MODE_NONE)
|
||||
{
|
||||
SetupHotReloading();
|
||||
}
|
||||
@@ -493,8 +493,8 @@ std::vector<std::string> ScriptEngine::GetPluginFiles() const
|
||||
auto base = _env.GetDirectoryPath(DIRBASE::USER, DIRID::PLUGIN);
|
||||
if (Path::DirectoryExists(base))
|
||||
{
|
||||
auto pattern = Path::Combine(base, "*.js");
|
||||
auto scanner = std::unique_ptr<IFileScanner>(Path::ScanDirectory(pattern, true));
|
||||
auto pattern = Path::Combine(base, u8"*.js");
|
||||
auto scanner = Path::ScanDirectory(pattern, true);
|
||||
while (scanner->Next())
|
||||
{
|
||||
auto path = std::string(scanner->GetPath());
|
||||
@@ -558,6 +558,8 @@ void ScriptEngine::RegisterPlugin(std::string_view path)
|
||||
|
||||
void ScriptEngine::StartIntransientPlugins()
|
||||
{
|
||||
LoadSharedStorage();
|
||||
|
||||
for (auto& plugin : _plugins)
|
||||
{
|
||||
if (!plugin->HasStarted() && !plugin->IsTransient())
|
||||
@@ -586,38 +588,9 @@ void ScriptEngine::StopUnloadRegisterAllPlugins()
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::LoadPlugins()
|
||||
void ScriptEngine::LoadTransientPlugins()
|
||||
{
|
||||
if (!_initialised)
|
||||
{
|
||||
Initialise();
|
||||
}
|
||||
if (_pluginsLoaded)
|
||||
{
|
||||
UnloadPlugins();
|
||||
}
|
||||
|
||||
auto base = _env.GetDirectoryPath(DIRBASE::USER, DIRID::PLUGIN);
|
||||
if (Path::DirectoryExists(base))
|
||||
{
|
||||
auto pattern = Path::Combine(base, u8"*.js");
|
||||
auto scanner = Path::ScanDirectory(pattern, true);
|
||||
while (scanner->Next())
|
||||
{
|
||||
auto path = std::string(scanner->GetPath());
|
||||
if (ShouldLoadScript(path))
|
||||
{
|
||||
LoadPlugin(path);
|
||||
}
|
||||
}
|
||||
|
||||
if (gConfigPlugin.enable_hot_reloading && network_get_mode() == NETWORK_MODE_NONE)
|
||||
{
|
||||
SetupHotReloading();
|
||||
}
|
||||
}
|
||||
_pluginsLoaded = true;
|
||||
_pluginsStarted = false;
|
||||
_transientPluginsEnabled = true;
|
||||
}
|
||||
|
||||
void ScriptEngine::LoadPlugin(const std::string& path)
|
||||
@@ -705,7 +678,7 @@ void ScriptEngine::SetupHotReloading()
|
||||
std::lock_guard<std::mutex> guard(_changedPluginFilesMutex);
|
||||
_changedPluginFiles.emplace(path);
|
||||
};
|
||||
_hotReloading = true;
|
||||
_hotReloadingInitialised = true;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
@@ -714,6 +687,19 @@ void ScriptEngine::SetupHotReloading()
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::DoAutoReloadPluginCheck()
|
||||
{
|
||||
if (_hotReloadingInitialised)
|
||||
{
|
||||
auto tick = Platform::GetTicks();
|
||||
if (tick - _lastHotReloadCheckTick > 1000)
|
||||
{
|
||||
AutoReloadPlugins();
|
||||
_lastHotReloadCheckTick = tick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::AutoReloadPlugins()
|
||||
{
|
||||
if (_changedPluginFiles.size() > 0)
|
||||
@@ -746,39 +732,54 @@ void ScriptEngine::AutoReloadPlugins()
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::UnloadPlugins()
|
||||
void ScriptEngine::UnloadTransientPlugins()
|
||||
{
|
||||
StopPlugins();
|
||||
// Stop them all first
|
||||
for (auto& plugin : _plugins)
|
||||
{
|
||||
LogPluginInfo(plugin, "Unloaded");
|
||||
}
|
||||
_plugins.clear();
|
||||
_pluginsLoaded = false;
|
||||
_pluginsStarted = false;
|
||||
}
|
||||
|
||||
void ScriptEngine::StartPlugins()
|
||||
{
|
||||
LoadSharedStorage();
|
||||
|
||||
for (auto& plugin : _plugins)
|
||||
{
|
||||
if (!plugin->HasStarted() && ShouldStartPlugin(plugin))
|
||||
if (plugin->IsTransient())
|
||||
{
|
||||
ScriptExecutionInfo::PluginScope scope(_execInfo, plugin, false);
|
||||
try
|
||||
if (plugin->HasStarted())
|
||||
{
|
||||
LogPluginInfo(plugin, "Started");
|
||||
plugin->Start();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
_console.WriteLineError(e.what());
|
||||
StopPlugin(plugin);
|
||||
LogPluginInfo(plugin, "Stopped");
|
||||
}
|
||||
}
|
||||
}
|
||||
_pluginsStarted = true;
|
||||
|
||||
// Now unload them
|
||||
for (auto& plugin : _plugins)
|
||||
{
|
||||
UnloadPlugin(plugin);
|
||||
}
|
||||
|
||||
_transientPluginsEnabled = false;
|
||||
_transientPluginsStarted = false;
|
||||
}
|
||||
|
||||
void ScriptEngine::StartTransientPlugins()
|
||||
{
|
||||
LoadSharedStorage();
|
||||
|
||||
// Load transient plugins
|
||||
for (auto& plugin : _plugins)
|
||||
{
|
||||
if (plugin->IsTransient() && !plugin->IsLoaded() && ShouldStartPlugin(plugin))
|
||||
{
|
||||
LoadPlugin(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
// Start transient plugins
|
||||
for (auto& plugin : _plugins)
|
||||
{
|
||||
if (plugin->IsTransient() && plugin->IsLoaded() && !plugin->HasStarted())
|
||||
{
|
||||
StartPlugin(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
_transientPluginsStarted = true;
|
||||
}
|
||||
|
||||
bool ScriptEngine::ShouldStartPlugin(const std::shared_ptr<Plugin>& plugin)
|
||||
@@ -797,19 +798,6 @@ bool ScriptEngine::ShouldStartPlugin(const std::shared_ptr<Plugin>& plugin)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptEngine::StopPlugins()
|
||||
{
|
||||
for (auto& plugin : _plugins)
|
||||
{
|
||||
if (plugin->HasStarted())
|
||||
{
|
||||
StopPlugin(plugin);
|
||||
LogPluginInfo(plugin, "Stopped");
|
||||
}
|
||||
}
|
||||
_pluginsStarted = false;
|
||||
}
|
||||
|
||||
void ScriptEngine::Tick()
|
||||
{
|
||||
PROFILED_FUNCTION();
|
||||
@@ -820,26 +808,15 @@ void ScriptEngine::Tick()
|
||||
RefreshPlugins();
|
||||
}
|
||||
|
||||
if (_pluginsLoaded)
|
||||
if (_transientPluginsEnabled && !_transientPluginsStarted)
|
||||
{
|
||||
if (!_pluginsStarted)
|
||||
{
|
||||
StartPlugins();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tick = Platform::GetTicks();
|
||||
if (tick - _lastHotReloadCheckTick > 1000)
|
||||
{
|
||||
AutoReloadPlugins();
|
||||
_lastHotReloadCheckTick = tick;
|
||||
}
|
||||
}
|
||||
StartTransientPlugins();
|
||||
}
|
||||
|
||||
UpdateIntervals();
|
||||
UpdateSockets();
|
||||
ProcessREPL();
|
||||
DoAutoReloadPluginCheck();
|
||||
}
|
||||
|
||||
void ScriptEngine::ProcessREPL()
|
||||
|
||||
Reference in New Issue
Block a user