Fix editor plugins init regression from #1779 and compact more code
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user