Fix and improve plugin startup / shutdown

This commit is contained in:
Ted John 2022-02-27 15:48:43 +00:00
parent b579d15119
commit e4a10b8eb4
3 changed files with 37 additions and 23 deletions

View File

@ -174,6 +174,10 @@ namespace OpenRCT2
// NOTE: We must shutdown all systems here before Instance is set back to null.
// If objects use GetContext() in their destructor things won't go well.
#ifdef ENABLE_SCRIPTING
_scriptEngine.StopUnloadRegisterAllPlugins();
#endif
GameActions::ClearQueue();
#ifndef DISABLE_NETWORK
_network.Close();
@ -503,6 +507,10 @@ namespace OpenRCT2
_gameState = std::make_unique<GameState>();
_gameState->InitAll(DEFAULT_MAP_SIZE);
#ifdef ENABLE_SCRIPTING
_scriptEngine.Initialise();
#endif
_titleScreen = std::make_unique<TitleScreen>(*_gameState);
_uiContext->Initialise();

View File

@ -386,6 +386,9 @@ ScriptEngine::ScriptEngine(InteractiveConsole& console, IPlatformEnvironment& en
void ScriptEngine::Initialise()
{
if (_initialised)
throw std::runtime_error("Script engine already initialised.");
auto ctx = static_cast<duk_context*>(_context);
ScCheats::Register(ctx);
ScClimate::Register(ctx);
@ -445,11 +448,6 @@ void ScriptEngine::Initialise()
void ScriptEngine::RefreshPlugins()
{
if (!_initialised)
{
Initialise();
}
// Get a list of removed and added plugin files
auto pluginFiles = GetPluginFiles();
std::vector<std::string> plugins;
@ -481,9 +479,6 @@ void ScriptEngine::RefreshPlugins()
{
SetupHotReloading();
}
// Start any new intransient plugins
StartIntransientPlugins();
}
std::vector<std::string> ScriptEngine::GetPluginFiles() const
@ -568,6 +563,8 @@ void ScriptEngine::StartIntransientPlugins()
StartPlugin(plugin);
}
}
_intransientPluginsStarted = true;
}
void ScriptEngine::StopUnloadRegisterAllPlugins()
@ -811,23 +808,32 @@ void ScriptEngine::Tick()
{
PROFILED_FUNCTION();
if (!_initialised)
{
Initialise();
RefreshPlugins();
}
if (_transientPluginsEnabled && !_transientPluginsStarted)
{
StartTransientPlugins();
}
CheckAndStartPlugins();
UpdateIntervals();
UpdateSockets();
ProcessREPL();
DoAutoReloadPluginCheck();
}
void ScriptEngine::CheckAndStartPlugins()
{
auto startIntransient = !_intransientPluginsStarted;
auto startTransient = !_transientPluginsStarted && _transientPluginsEnabled;
if (startIntransient || startTransient)
{
RefreshPlugins();
}
if (startIntransient)
{
StartIntransientPlugins();
}
if (startTransient)
{
StartTransientPlugins();
}
}
void ScriptEngine::ProcessREPL()
{
while (_evalQueue.size() > 0)

View File

@ -148,6 +148,7 @@ namespace OpenRCT2::Scripting
bool _hotReloadingInitialised{};
bool _transientPluginsEnabled{};
bool _transientPluginsStarted{};
bool _intransientPluginsStarted{};
std::queue<std::tuple<std::promise<void>, std::string>> _evalQueue;
std::vector<std::shared_ptr<Plugin>> _plugins;
uint32_t _lastHotReloadCheckTick{};
@ -210,10 +211,10 @@ namespace OpenRCT2::Scripting
std::string GetParkStorageAsJSON();
void SetParkStorageFromJSON(std::string_view value);
void LoadPlugins();
void UnloadPlugins();
void Initialise();
void LoadTransientPlugins();
void UnloadTransientPlugins();
void StopUnloadRegisterAllPlugins();
void Tick();
std::future<void> Eval(const std::string& s);
DukValue ExecutePluginCall(
@ -249,11 +250,11 @@ namespace OpenRCT2::Scripting
# endif
private:
void Initialise();
void RefreshPlugins();
std::vector<std::string> GetPluginFiles() const;
void UnregisterPlugin(std::string_view path);
void RegisterPlugin(std::string_view path);
void CheckAndStartPlugins();
void StartIntransientPlugins();
void StartTransientPlugins();
void LoadPlugin(const std::string& path);
@ -262,7 +263,6 @@ namespace OpenRCT2::Scripting
void StartPlugin(std::shared_ptr<Plugin> plugin);
void StopPlugin(std::shared_ptr<Plugin> plugin);
void ReloadPlugin(std::shared_ptr<Plugin> plugin);
void StopUnloadRegisterAllPlugins();
static bool ShouldLoadScript(std::string_view path);
bool ShouldStartPlugin(const std::shared_ptr<Plugin>& plugin);
void SetupHotReloading();