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
|
namespace PluginManagerImpl
|
||||||
{
|
{
|
||||||
|
bool Initialized = false;
|
||||||
Array<GamePlugin*> GamePlugins;
|
Array<GamePlugin*> GamePlugins;
|
||||||
Array<Plugin*> EditorPlugins;
|
Array<Plugin*> EditorPlugins;
|
||||||
|
|
||||||
void LoadPlugin(MClass* klass, bool isEditor);
|
|
||||||
void OnAssemblyLoaded(MAssembly* assembly);
|
void OnAssemblyLoaded(MAssembly* assembly);
|
||||||
void OnAssemblyUnloading(MAssembly* assembly);
|
void OnAssemblyUnloading(MAssembly* assembly);
|
||||||
void OnBinaryModuleLoaded(BinaryModule* module);
|
void OnBinaryModuleLoaded(BinaryModule* module);
|
||||||
void OnScriptsReloading();
|
void OnScriptsReloading();
|
||||||
|
void InitializePlugins();
|
||||||
|
void DeinitializePlugins();
|
||||||
|
|
||||||
template<typename PluginType = Plugin>
|
template<typename PluginType = Plugin>
|
||||||
Array<PluginType*> SortPlugins(Array<PluginType*> plugins, MClass* pluginLoadOrderAttribute, MField* typeField)
|
Array<PluginType*> SortPlugins(Array<PluginType*> plugins, MClass* pluginLoadOrderAttribute, MField* typeField)
|
||||||
@@ -149,7 +151,7 @@ void PluginManagerService::InvokeInitialize(Plugin* plugin)
|
|||||||
{
|
{
|
||||||
if (plugin->_initialized)
|
if (plugin->_initialized)
|
||||||
return;
|
return;
|
||||||
StringAnsiView typeName = plugin->GetType().GetName();
|
const StringAnsiView typeName = plugin->GetType().GetName();
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
ZoneName(typeName.Get(), typeName.Length());
|
ZoneName(typeName.Get(), typeName.Length());
|
||||||
|
|
||||||
@@ -167,7 +169,7 @@ void PluginManagerService::InvokeDeinitialize(Plugin* plugin)
|
|||||||
{
|
{
|
||||||
if (!plugin->_initialized)
|
if (!plugin->_initialized)
|
||||||
return;
|
return;
|
||||||
StringAnsiView typeName = plugin->GetType().GetName();
|
const StringAnsiView typeName = plugin->GetType().GetName();
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
ZoneName(typeName.Get(), typeName.Length());
|
ZoneName(typeName.Get(), typeName.Length());
|
||||||
|
|
||||||
@@ -181,26 +183,6 @@ void PluginManagerService::InvokeDeinitialize(Plugin* plugin)
|
|||||||
PluginManager::PluginUnloaded(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)
|
void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
|
||||||
{
|
{
|
||||||
PROFILE_CPU_NAMED("Load Assembly Plugins");
|
PROFILE_CPU_NAMED("Load Assembly Plugins");
|
||||||
@@ -221,6 +203,7 @@ void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Process all classes to find plugins
|
// Process all classes to find plugins
|
||||||
|
bool loadedAnyPlugin = false;
|
||||||
auto& classes = assembly->GetClasses();
|
auto& classes = assembly->GetClasses();
|
||||||
for (auto i = classes.Begin(); i.IsNotEnd(); ++i)
|
for (auto i = classes.Begin(); i.IsNotEnd(); ++i)
|
||||||
{
|
{
|
||||||
@@ -230,17 +213,35 @@ void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
|
|||||||
if (mclass->IsGeneric() || mclass->IsStatic() || mclass->IsAbstract())
|
if (mclass->IsGeneric() || mclass->IsStatic() || mclass->IsAbstract())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mclass->IsSubClassOf(gamePluginClass))
|
if (mclass->IsSubClassOf(gamePluginClass)
|
||||||
{
|
|
||||||
LoadPlugin(mclass, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
if (mclass->IsSubClassOf(editorPluginClass))
|
|| mclass->IsSubClassOf(editorPluginClass)
|
||||||
{
|
|
||||||
LoadPlugin(mclass, true);
|
|
||||||
}
|
|
||||||
#endif
|
#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");
|
auto beforeTypeField = pluginLoadOrderAttribute->GetField("DeinitializeBefore");
|
||||||
ASSERT(beforeTypeField);
|
ASSERT(beforeTypeField);
|
||||||
|
|
||||||
|
#if USE_EDITOR
|
||||||
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, beforeTypeField);
|
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, beforeTypeField);
|
||||||
|
|
||||||
for (int32 i = editorPlugins.Count() - 1; i >= 0 && editorPlugins.Count() > 0; i--)
|
for (int32 i = editorPlugins.Count() - 1; i >= 0 && editorPlugins.Count() > 0; i--)
|
||||||
{
|
{
|
||||||
auto plugin = editorPlugins[i];
|
auto plugin = editorPlugins[i];
|
||||||
@@ -265,9 +266,9 @@ void PluginManagerImpl::OnAssemblyUnloading(MAssembly* assembly)
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, beforeTypeField);
|
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, beforeTypeField);
|
||||||
|
|
||||||
for (int32 i = gamePlugins.Count() - 1; i >= 0 && gamePlugins.Count() > 0; i--)
|
for (int32 i = gamePlugins.Count() - 1; i >= 0 && gamePlugins.Count() > 0; i--)
|
||||||
{
|
{
|
||||||
auto plugin = gamePlugins[i];
|
auto plugin = gamePlugins[i];
|
||||||
@@ -309,75 +310,83 @@ void PluginManagerImpl::OnBinaryModuleLoaded(BinaryModule* module)
|
|||||||
void PluginManagerImpl::OnScriptsReloading()
|
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)
|
// 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 engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly;
|
||||||
auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute");
|
auto pluginLoadOrderAttribute = engineAssembly->GetClass("FlaxEngine.PluginLoadOrderAttribute");
|
||||||
auto beforeTypeField = pluginLoadOrderAttribute->GetField("DeinitializeBefore");
|
auto beforeTypeField = pluginLoadOrderAttribute->GetField("DeinitializeBefore");
|
||||||
ASSERT(beforeTypeField);
|
ASSERT(beforeTypeField);
|
||||||
|
|
||||||
|
#if USE_EDITOR
|
||||||
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, beforeTypeField);
|
auto editorPlugins = SortPlugins(EditorPlugins, pluginLoadOrderAttribute, beforeTypeField);
|
||||||
|
|
||||||
for (int32 i = editorPlugins.Count() - 1; i >= 0 && editorPlugins.Count() > 0; i--)
|
for (int32 i = editorPlugins.Count() - 1; i >= 0 && editorPlugins.Count() > 0; i--)
|
||||||
{
|
{
|
||||||
auto plugin = editorPlugins[i];
|
auto plugin = editorPlugins[i];
|
||||||
{
|
PluginManagerService::InvokeDeinitialize(plugin);
|
||||||
PluginManagerService::InvokeDeinitialize(plugin);
|
EditorPlugins.Remove(plugin);
|
||||||
EditorPlugins.Remove(plugin);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, beforeTypeField);
|
auto gamePlugins = SortPlugins(GamePlugins, pluginLoadOrderAttribute, beforeTypeField);
|
||||||
|
|
||||||
for (int32 i = gamePlugins.Count() - 1; i >= 0 && gamePlugins.Count() > 0; i--)
|
for (int32 i = gamePlugins.Count() - 1; i >= 0 && gamePlugins.Count() > 0; i--)
|
||||||
{
|
{
|
||||||
auto plugin = gamePlugins[i];
|
auto plugin = gamePlugins[i];
|
||||||
{
|
PluginManagerService::InvokeDeinitialize(plugin);
|
||||||
PluginManagerService::InvokeDeinitialize(plugin);
|
GamePlugins.Remove(plugin);
|
||||||
GamePlugins.Remove(plugin);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (changed)
|
|
||||||
PluginManager::PluginsChanged();
|
PluginManager::PluginsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginManagerService::Init()
|
bool PluginManagerService::Init()
|
||||||
{
|
{
|
||||||
|
Initialized = false;
|
||||||
|
|
||||||
// Process already loaded modules
|
// Process already loaded modules
|
||||||
for (auto module : BinaryModule::GetModules())
|
for (auto module : BinaryModule::GetModules())
|
||||||
{
|
{
|
||||||
OnBinaryModuleLoaded(module);
|
OnBinaryModuleLoaded(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize plugins
|
// Invoke plugins initialization for all of them
|
||||||
auto engineAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly;
|
InitializePlugins();
|
||||||
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
|
|
||||||
|
|
||||||
// Register for new binary modules load actions
|
// Register for new binary modules load actions
|
||||||
|
Initialized = true;
|
||||||
Scripting::BinaryModuleLoaded.Bind(&OnBinaryModuleLoaded);
|
Scripting::BinaryModuleLoaded.Bind(&OnBinaryModuleLoaded);
|
||||||
Scripting::ScriptsReloading.Bind(&OnScriptsReloading);
|
Scripting::ScriptsReloading.Bind(&OnScriptsReloading);
|
||||||
|
|
||||||
@@ -386,38 +395,13 @@ bool PluginManagerService::Init()
|
|||||||
|
|
||||||
void PluginManagerService::Dispose()
|
void PluginManagerService::Dispose()
|
||||||
{
|
{
|
||||||
|
// Unregister from new modules loading
|
||||||
|
Initialized = false;
|
||||||
Scripting::BinaryModuleLoaded.Unbind(&OnBinaryModuleLoaded);
|
Scripting::BinaryModuleLoaded.Unbind(&OnBinaryModuleLoaded);
|
||||||
Scripting::ScriptsReloading.Unbind(&OnScriptsReloading);
|
Scripting::ScriptsReloading.Unbind(&OnScriptsReloading);
|
||||||
|
|
||||||
// Cleanup all plugins
|
// Cleanup all plugins
|
||||||
PROFILE_CPU_NAMED("Dispose Plugins");
|
DeinitializePlugins();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<GamePlugin*>& PluginManager::GetGamePlugins()
|
const Array<GamePlugin*>& PluginManager::GetGamePlugins()
|
||||||
@@ -432,11 +416,13 @@ const Array<Plugin*>& PluginManager::GetEditorPlugins()
|
|||||||
|
|
||||||
Plugin* PluginManager::GetPlugin(const StringView& name)
|
Plugin* PluginManager::GetPlugin(const StringView& name)
|
||||||
{
|
{
|
||||||
|
#if USE_EDITOR
|
||||||
for (Plugin* p : EditorPlugins)
|
for (Plugin* p : EditorPlugins)
|
||||||
{
|
{
|
||||||
if (p->GetDescription().Name == name)
|
if (p->GetDescription().Name == name)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
for (GamePlugin* gp : GamePlugins)
|
for (GamePlugin* gp : GamePlugins)
|
||||||
{
|
{
|
||||||
if (gp->GetDescription().Name == name)
|
if (gp->GetDescription().Name == name)
|
||||||
@@ -448,11 +434,13 @@ Plugin* PluginManager::GetPlugin(const StringView& name)
|
|||||||
Plugin* PluginManager::GetPlugin(const MClass* type)
|
Plugin* PluginManager::GetPlugin(const MClass* type)
|
||||||
{
|
{
|
||||||
CHECK_RETURN(type, nullptr);
|
CHECK_RETURN(type, nullptr);
|
||||||
|
#if USE_EDITOR
|
||||||
for (Plugin* p : EditorPlugins)
|
for (Plugin* p : EditorPlugins)
|
||||||
{
|
{
|
||||||
if (p->GetClass()->IsSubClassOf(type))
|
if (p->GetClass()->IsSubClassOf(type))
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
for (GamePlugin* gp : GamePlugins)
|
for (GamePlugin* gp : GamePlugins)
|
||||||
{
|
{
|
||||||
if (gp->GetClass()->IsSubClassOf(type))
|
if (gp->GetClass()->IsSubClassOf(type))
|
||||||
@@ -464,11 +452,13 @@ Plugin* PluginManager::GetPlugin(const MClass* type)
|
|||||||
Plugin* PluginManager::GetPlugin(const ScriptingTypeHandle& type)
|
Plugin* PluginManager::GetPlugin(const ScriptingTypeHandle& type)
|
||||||
{
|
{
|
||||||
CHECK_RETURN(type, nullptr);
|
CHECK_RETURN(type, nullptr);
|
||||||
|
#if USE_EDITOR
|
||||||
for (Plugin* p : EditorPlugins)
|
for (Plugin* p : EditorPlugins)
|
||||||
{
|
{
|
||||||
if (p->Is(type))
|
if (p->Is(type))
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
for (GamePlugin* gp : GamePlugins)
|
for (GamePlugin* gp : GamePlugins)
|
||||||
{
|
{
|
||||||
if (gp->Is(type))
|
if (gp->Is(type))
|
||||||
|
|||||||
Reference in New Issue
Block a user