Fix editor plugins init regression from #1779 and compact more code

This commit is contained in:
Wojtek Figat
2023-11-06 18:13:06 +01:00
parent ae85a94261
commit c3d74b690e

View File

@@ -75,14 +75,16 @@ Action PluginManager::PluginsChanged;
namespace PluginManagerImpl
{
bool Initialized = false;
Array<GamePlugin*> GamePlugins;
Array<Plugin*> EditorPlugins;
void LoadPlugin(MClass* klass, bool isEditor);
void OnAssemblyLoaded(MAssembly* assembly);
void OnAssemblyUnloading(MAssembly* assembly);
void OnBinaryModuleLoaded(BinaryModule* module);
void OnScriptsReloading();
void InitializePlugins();
void DeinitializePlugins();
template<typename PluginType = Plugin>
Array<PluginType*> SortPlugins(Array<PluginType*> plugins, MClass* pluginLoadOrderAttribute, MField* typeField)
@@ -149,7 +151,7 @@ void PluginManagerService::InvokeInitialize(Plugin* plugin)
{
if (plugin->_initialized)
return;
StringAnsiView typeName = plugin->GetType().GetName();
const StringAnsiView typeName = plugin->GetType().GetName();
PROFILE_CPU();
ZoneName(typeName.Get(), typeName.Length());
@@ -167,7 +169,7 @@ void PluginManagerService::InvokeDeinitialize(Plugin* plugin)
{
if (!plugin->_initialized)
return;
StringAnsiView typeName = plugin->GetType().GetName();
const StringAnsiView typeName = plugin->GetType().GetName();
PROFILE_CPU();
ZoneName(typeName.Get(), typeName.Length());
@@ -181,26 +183,6 @@ void PluginManagerService::InvokeDeinitialize(Plugin* plugin)
PluginManager::PluginUnloaded(plugin);
}
void PluginManagerImpl::LoadPlugin(MClass* klass, bool isEditor)
{
// Create and check if use it
auto plugin = (Plugin*)Scripting::NewObject(klass);
if (!plugin)
return;
if (!isEditor)
{
GamePlugins.Add((GamePlugin*)plugin);
}
#if USE_EDITOR
else
{
EditorPlugins.Add(plugin);
}
#endif
PluginManager::PluginsChanged();
}
void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
{
PROFILE_CPU_NAMED("Load Assembly Plugins");
@@ -221,6 +203,7 @@ void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
#endif
// Process all classes to find plugins
bool loadedAnyPlugin = false;
auto& classes = assembly->GetClasses();
for (auto i = classes.Begin(); i.IsNotEnd(); ++i)
{
@@ -230,17 +213,35 @@ void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
if (mclass->IsGeneric() || mclass->IsStatic() || mclass->IsAbstract())
continue;
if (mclass->IsSubClassOf(gamePluginClass))
{
LoadPlugin(mclass, false);
}
if (mclass->IsSubClassOf(gamePluginClass)
#if USE_EDITOR
if (mclass->IsSubClassOf(editorPluginClass))
{
LoadPlugin(mclass, true);
}
|| mclass->IsSubClassOf(editorPluginClass)
#endif
)
{
auto plugin = (Plugin*)Scripting::NewObject(mclass);
if (plugin)
{
#if USE_EDITOR
if (mclass->IsSubClassOf(editorPluginClass))
{
EditorPlugins.Add(plugin);
}
else
#endif
{
GamePlugins.Add((GamePlugin*)plugin);
}
loadedAnyPlugin = true;
}
}
}
// Send event and initialize newly added plugins (ignore during startup)
if (loadedAnyPlugin && Initialized)
{
InitializePlugins();
PluginManager::PluginsChanged();
}
}
@@ -253,8 +254,8 @@ void PluginManagerImpl::OnAssemblyUnloading(MAssembly* assembly)
auto beforeTypeField = pluginLoadOrderAttribute->GetField("DeinitializeBefore");
ASSERT(beforeTypeField);
#if USE_EDITOR
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, beforeTypeField);
for (int32 i = editorPlugins.Count() - 1; i >= 0 && editorPlugins.Count() > 0; i--)
{
auto plugin = editorPlugins[i];
@@ -265,9 +266,9 @@ void PluginManagerImpl::OnAssemblyUnloading(MAssembly* assembly)
changed = true;
}
}
#endif
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, beforeTypeField);
for (int32 i = gamePlugins.Count() - 1; i >= 0 && gamePlugins.Count() > 0; i--)
{
auto plugin = gamePlugins[i];
@@ -309,75 +310,83 @@ void PluginManagerImpl::OnBinaryModuleLoaded(BinaryModule* module)
void PluginManagerImpl::OnScriptsReloading()
{
// When scripting is reloading (eg. for hot-reload in Editor) we have to deinitialize plugins (Scripting service destroys C# objects later on)
bool changed = false;
DeinitializePlugins();
}
void PluginManagerImpl::InitializePlugins()
{
if (EditorPlugins.Count() + GamePlugins.Count() == 0)
return;
PROFILE_CPU_NAMED("InitializePlugins");
auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly;
auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute");
auto afterTypeField = pluginLoadOrderAttribute->GetField("InitializeAfter");
ASSERT(afterTypeField);
#if USE_EDITOR
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, afterTypeField);
for (auto plugin : editorPlugins)
{
PluginManagerService::InvokeInitialize(plugin);
}
#else
// Game plugins are managed via InitializeGamePlugins/DeinitializeGamePlugins by Editor for play mode
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, afterTypeField);
for (auto plugin : gamePlugins)
{
PluginManagerService::InvokeInitialize(plugin);
}
#endif
}
void PluginManagerImpl::DeinitializePlugins()
{
if (EditorPlugins.Count() + GamePlugins.Count() == 0)
return;
PROFILE_CPU_NAMED("DeinitializePlugins");
auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly;
auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute");
auto beforeTypeField = pluginLoadOrderAttribute->GetField("DeinitializeBefore");
ASSERT(beforeTypeField);
#if USE_EDITOR
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, beforeTypeField);
for (int32 i = editorPlugins.Count() - 1; i >= 0 && editorPlugins.Count() > 0; i--)
{
auto plugin = editorPlugins[i];
{
PluginManagerService::InvokeDeinitialize(plugin);
EditorPlugins.Remove(plugin);
changed = true;
}
PluginManagerService::InvokeDeinitialize(plugin);
EditorPlugins.Remove(plugin);
}
#endif
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, beforeTypeField);
for (int32 i = gamePlugins.Count() - 1; i >= 0 && gamePlugins.Count() > 0; i--)
{
auto plugin = gamePlugins[i];
{
PluginManagerService::InvokeDeinitialize(plugin);
GamePlugins.Remove(plugin);
changed = true;
}
PluginManagerService::InvokeDeinitialize(plugin);
GamePlugins.Remove(plugin);
}
if (changed)
PluginManager::PluginsChanged();
PluginManager::PluginsChanged();
}
bool PluginManagerService::Init()
{
Initialized = false;
// Process already loaded modules
for (auto module : BinaryModule::GetModules())
{
OnBinaryModuleLoaded(module);
}
// Initialize plugins
auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly;
auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute");
auto afterTypeField = pluginLoadOrderAttribute->GetField("InitializeAfter");
ASSERT(afterTypeField);
#if !USE_EDITOR
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, afterTypeField);
// Initialize game plugins
for (auto plugin : gamePlugins)
{
PluginManagerService::InvokeInitialize(plugin);
}
#endif
#if USE_EDITOR
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, afterTypeField);
// Initialize editor plugins
for (auto plugin : editorPlugins)
{
PluginManagerService::InvokeInitialize(plugin);
}
#endif
// Invoke plugins initialization for all of them
InitializePlugins();
// Register for new binary modules load actions
Initialized = true;
Scripting::BinaryModuleLoaded.Bind(&OnBinaryModuleLoaded);
Scripting::ScriptsReloading.Bind(&OnScriptsReloading);
@@ -386,38 +395,13 @@ bool PluginManagerService::Init()
void PluginManagerService::Dispose()
{
// Unregister from new modules loading
Initialized = false;
Scripting::BinaryModuleLoaded.Unbind(&OnBinaryModuleLoaded);
Scripting::ScriptsReloading.Unbind(&OnScriptsReloading);
// Cleanup all plugins
PROFILE_CPU_NAMED("Dispose Plugins");
const int32 pluginsCount = EditorPlugins.Count() + GamePlugins.Count();
if (pluginsCount == 0)
return;
LOG(Info, "Unloading {0} plugins", pluginsCount);
auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly;
auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute");
auto beforeTypeField = pluginLoadOrderAttribute->GetField("DeinitializeBefore");
ASSERT(beforeTypeField);
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, beforeTypeField);
for (int32 i = editorPlugins.Count() - 1; i >= 0 && editorPlugins.Count() > 0; i--)
{
auto plugin = editorPlugins[i];
InvokeDeinitialize(plugin);
EditorPlugins.Remove(plugin);
}
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, beforeTypeField);
for (int32 i = gamePlugins.Count() - 1; i >= 0 && gamePlugins.Count() > 0; i--)
{
auto plugin = gamePlugins[i];
InvokeDeinitialize(plugin);
GamePlugins.Remove(plugin);
}
PluginManager::PluginsChanged();
DeinitializePlugins();
}
const Array<GamePlugin*>& PluginManager::GetGamePlugins()
@@ -432,11 +416,13 @@ const Array<Plugin*>& PluginManager::GetEditorPlugins()
Plugin* PluginManager::GetPlugin(const StringView& name)
{
#if USE_EDITOR
for (Plugin* p : EditorPlugins)
{
if (p->GetDescription().Name == name)
return p;
}
#endif
for (GamePlugin* gp : GamePlugins)
{
if (gp->GetDescription().Name == name)
@@ -448,11 +434,13 @@ Plugin* PluginManager::GetPlugin(const StringView& name)
Plugin* PluginManager::GetPlugin(const MClass* type)
{
CHECK_RETURN(type, nullptr);
#if USE_EDITOR
for (Plugin* p : EditorPlugins)
{
if (p->GetClass()->IsSubClassOf(type))
return p;
}
#endif
for (GamePlugin* gp : GamePlugins)
{
if (gp->GetClass()->IsSubClassOf(type))
@@ -464,11 +452,13 @@ Plugin* PluginManager::GetPlugin(const MClass* type)
Plugin* PluginManager::GetPlugin(const ScriptingTypeHandle& type)
{
CHECK_RETURN(type, nullptr);
#if USE_EDITOR
for (Plugin* p : EditorPlugins)
{
if (p->Is(type))
return p;
}
#endif
for (GamePlugin* gp : GamePlugins)
{
if (gp->Is(type))