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