Slightly better handling of plugin reloading.
This commit is contained in:
parent
b9f7f20046
commit
4e654704dc
@ -1192,10 +1192,11 @@ void CPlugin::SetRegistered()
|
||||
m_state = PluginState::Registered;
|
||||
}
|
||||
|
||||
void CPlugin::SetWaitingToUnload()
|
||||
void CPlugin::SetWaitingToUnload(bool andReload)
|
||||
{
|
||||
assert(m_state == PluginState::Registered);
|
||||
m_state = PluginState::WaitingToUnload;
|
||||
assert(m_state == PluginState::Registered ||
|
||||
(m_state == PluginState::WaitingToUnload && andReload));
|
||||
m_state = andReload ? PluginState::WaitingToUnloadAndReload : PluginState::WaitingToUnload;
|
||||
}
|
||||
|
||||
void CPluginManager::LoadExtensions(CPlugin *pPlugin)
|
||||
@ -1440,8 +1441,11 @@ bool CPluginManager::UnloadPlugin(IPlugin *plugin)
|
||||
assert(m_plugins.contains(pPlugin));
|
||||
|
||||
// If we're already in the unload queue, just wait.
|
||||
if (pPlugin->State() == PluginState::WaitingToUnload)
|
||||
if (pPlugin->State() == PluginState::WaitingToUnload ||
|
||||
pPlugin->State() == PluginState::WaitingToUnloadAndReload)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// It is not safe to unload any plugin while another is on the callstack.
|
||||
bool any_active = false;
|
||||
@ -2015,14 +2019,23 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
|
||||
else
|
||||
strcpy(name, pl->GetFilename());
|
||||
|
||||
if (ReloadPlugin(pl))
|
||||
if (ReloadPlugin(pl, true))
|
||||
{
|
||||
rootmenu->ConsolePrint("[SM] Plugin %s reloaded successfully.", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pl->State())
|
||||
{
|
||||
//the unload/reload attempt next frame will print a message
|
||||
case PluginState::WaitingToUnload:
|
||||
case PluginState::WaitingToUnloadAndReload:
|
||||
return;
|
||||
|
||||
default:
|
||||
rootmenu->ConsolePrint("[SM] Failed to reload plugin %s.", name);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2041,15 +2054,14 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
|
||||
rootmenu->DrawGenericOption("unload_all", "Unloads all plugins");
|
||||
}
|
||||
|
||||
bool CPluginManager::ReloadPlugin(CPlugin *pl)
|
||||
bool CPluginManager::ReloadPlugin(CPlugin *pl, bool print)
|
||||
{
|
||||
char filename[PLATFORM_MAX_PATH];
|
||||
bool wasloaded;
|
||||
PluginType ptype;
|
||||
IPlugin *newpl;
|
||||
PluginState state = pl->State();
|
||||
if (state == PluginState::WaitingToUnloadAndReload)
|
||||
return false;
|
||||
|
||||
strcpy(filename, pl->GetFilename());
|
||||
ptype = pl->GetType();
|
||||
ke::AString filename(pl->GetFilename());
|
||||
PluginType ptype = pl->GetType();
|
||||
|
||||
int id = 1;
|
||||
for (PluginIter iter(m_plugins); !iter.done(); iter.next(), id++) {
|
||||
@ -2059,13 +2071,34 @@ bool CPluginManager::ReloadPlugin(CPlugin *pl)
|
||||
|
||||
if (!UnloadPlugin(pl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(newpl=LoadPlugin(filename, true, ptype, NULL, 0, &wasloaded)))
|
||||
if (pl->State() == PluginState::WaitingToUnload)
|
||||
{
|
||||
pl->SetWaitingToUnload(true);
|
||||
ScheduleTaskForNextFrame([this, id, filename, ptype, print]() -> void {
|
||||
ReloadPluginImpl(id, filename.chars(), ptype, print);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ReloadPluginImpl(id, filename.chars(), ptype, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPluginManager::ReloadPluginImpl(int id, const char filename[], PluginType ptype, bool print)
|
||||
{
|
||||
char error[128];
|
||||
bool wasloaded;
|
||||
IPlugin *newpl = LoadPlugin(filename, true, ptype, error, sizeof(error), &wasloaded);
|
||||
if (!newpl)
|
||||
{
|
||||
rootmenu->ConsolePrint("[SM] Plugin %s failed to reload: %s.", filename, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (print)
|
||||
rootmenu->ConsolePrint("[SM] Plugin %s reloaded successfully.", filename);
|
||||
|
||||
m_plugins.remove(static_cast<CPlugin *>(newpl));
|
||||
|
||||
PluginIter iter(m_plugins);
|
||||
@ -2073,8 +2106,6 @@ bool CPluginManager::ReloadPlugin(CPlugin *pl)
|
||||
// Empty loop.
|
||||
}
|
||||
m_plugins.insertBefore(iter, static_cast<CPlugin *>(newpl));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPluginManager::RefreshAll()
|
||||
|
@ -88,7 +88,8 @@ enum class PluginState
|
||||
Evicted,
|
||||
|
||||
// The plugin is waiting to be unloaded.
|
||||
WaitingToUnload
|
||||
WaitingToUnload,
|
||||
WaitingToUnloadAndReload,
|
||||
};
|
||||
|
||||
class CPlugin :
|
||||
@ -176,7 +177,7 @@ public:
|
||||
return m_state;
|
||||
}
|
||||
void SetRegistered();
|
||||
void SetWaitingToUnload();
|
||||
void SetWaitingToUnload(bool andReload=false);
|
||||
|
||||
PluginStatus GetDisplayStatus() const {
|
||||
return m_status;
|
||||
@ -426,7 +427,7 @@ public:
|
||||
|
||||
bool LibraryExists(const char *lib);
|
||||
|
||||
bool ReloadPlugin(CPlugin *pl);
|
||||
bool ReloadPlugin(CPlugin *pl, bool print=false);
|
||||
|
||||
void UnloadAll();
|
||||
|
||||
@ -463,6 +464,7 @@ private:
|
||||
bool FindOrRequirePluginDeps(CPlugin *pPlugin);
|
||||
|
||||
void UnloadPluginImpl(CPlugin *plugin);
|
||||
void ReloadPluginImpl(int id, const char filename[], PluginType ptype, bool print);
|
||||
|
||||
void Purge(CPlugin *plugin);
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user