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. // 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. // If objects use GetContext() in their destructor things won't go well.
#ifdef ENABLE_SCRIPTING
_scriptEngine.StopUnloadRegisterAllPlugins();
#endif
GameActions::ClearQueue(); GameActions::ClearQueue();
#ifndef DISABLE_NETWORK #ifndef DISABLE_NETWORK
_network.Close(); _network.Close();
@ -503,6 +507,10 @@ namespace OpenRCT2
_gameState = std::make_unique<GameState>(); _gameState = std::make_unique<GameState>();
_gameState->InitAll(DEFAULT_MAP_SIZE); _gameState->InitAll(DEFAULT_MAP_SIZE);
#ifdef ENABLE_SCRIPTING
_scriptEngine.Initialise();
#endif
_titleScreen = std::make_unique<TitleScreen>(*_gameState); _titleScreen = std::make_unique<TitleScreen>(*_gameState);
_uiContext->Initialise(); _uiContext->Initialise();

View File

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

View File

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