private void OnEnable() { EditorApplicationUtility.LockReloadAssemblies(); wrapper?.OnShow(); }
private void OnDisable() { wrapper?.OnClose(); EditorApplicationUtility.UnlockReloadAssemblies(); }
internal static void Initialize() { EditorApplication.delayCall -= initializeCallbackFunction; using (ProfilingUtility.SampleBlock("Plugin Container Initialization")) { initializing = true; pluginTypesById = Codebase.ludiqEditorTypes .Where(t => typeof(Plugin).IsAssignableFrom(t) && t.IsConcrete()) .ToDictionary(GetPluginID); pluginDependencies = new Dictionary <string, HashSet <string> >(); foreach (var pluginTypeById in pluginTypesById) { pluginDependencies.Add(pluginTypeById.Key, pluginTypeById.Value.GetAttributes <PluginDependencyAttribute>().Select(pda => pda.id).ToHashSet()); } var moduleTypes = Codebase.ludiqEditorTypes .Where(t => typeof(IPluginModule).IsAssignableFrom(t) && t.HasAttribute <PluginModuleAttribute>(false)) .OrderByDependencies(t => t.GetAttributes <PluginModuleDependencyAttribute>().Select(pmda => pmda.moduleType)) .ToArray(); pluginsById = new Dictionary <string, Plugin>(); var allModules = new List <IPluginModule>(); foreach (var pluginId in pluginTypesById.Keys.OrderByDependencies(pluginId => pluginDependencies[pluginId])) { var pluginType = pluginTypesById[pluginId]; Plugin plugin; try { using (ProfilingUtility.SampleBlock($"{pluginType.Name} (Instantiation)")) { plugin = (Plugin)pluginType.Instantiate(); } } catch (Exception ex) { throw new TargetInvocationException($"Could not instantiate plugin '{pluginId}' ('{pluginType.CSharpName()}').", ex); } var modules = new List <IPluginModule>(); foreach (var moduleType in moduleTypes) { try { var required = moduleType.GetAttribute <PluginModuleAttribute>(false).required; var moduleProperty = pluginType.GetProperties().FirstOrDefault(p => p.PropertyType.IsAssignableFrom(moduleType)); if (moduleProperty == null) { continue; } IPluginModule module = null; var moduleOverrideType = Codebase.ludiqEditorTypes .FirstOrDefault(t => moduleType.IsAssignableFrom(t) && t.IsConcrete() && t.HasAttribute <PluginAttribute>() && t.GetAttribute <PluginAttribute>().id == pluginId); if (moduleOverrideType != null) { try { using (ProfilingUtility.SampleBlock($"{moduleOverrideType.Name} (Instantiation)")) { module = (IPluginModule)InstantiateLinkedType(moduleOverrideType, plugin); } } catch (Exception ex) { throw new TargetInvocationException($"Failed to instantiate user-defined plugin module '{moduleOverrideType.CSharpName()}' for '{pluginId}'.", ex); } } else if (moduleType.IsConcrete()) { try { using (ProfilingUtility.SampleBlock($"{moduleType.Name} (Instantiation)")) { module = (IPluginModule)InstantiateLinkedType(moduleType, plugin); } } catch (Exception ex) { throw new TargetInvocationException($"Failed to instantiate built-in plugin module '{moduleType.CSharpName()}' for '{pluginId}'.", ex); } } else if (required) { throw new InvalidImplementationException($"Missing implementation of plugin module '{moduleType.CSharpName()}' for '{pluginId}'."); } if (module != null) { moduleProperty.SetValue(plugin, module, null); modules.Add(module); allModules.Add(module); } } catch (Exception ex) { Debug.LogException(ex); } } pluginsById.Add(plugin.id, plugin); foreach (var module in modules) { try { using (ProfilingUtility.SampleBlock($"{module.GetType().Name} (Initialization)")) { module.Initialize(); } } catch (Exception ex) { Debug.LogException(new Exception($"Failed to initialize plugin module '{plugin.id}.{module.GetType().CSharpName()}'.", ex)); } } if (plugin.manifest.versionMismatch) { anyVersionMismatch = true; } } initializing = false; initialized = true; foreach (var module in allModules) { try { using (ProfilingUtility.SampleBlock($"{module.GetType().Name} (Late Initialization)")) { module.LateInitialize(); } } catch (Exception ex) { Debug.LogException(new Exception($"Failed to late initialize plugin module '{module.plugin.id}.{module.GetType().CSharpName()}'.", ex)); } } var afterPluginTypes = Codebase.ludiqEditorTypes .Where(t => t.HasAttribute <InitializeAfterPluginsAttribute>()); using (ProfilingUtility.SampleBlock($"BeforeInitializeAfterPlugins")) { EditorApplicationUtility.BeforeInitializeAfterPlugins(); } foreach (var afterPluginType in afterPluginTypes) { using (ProfilingUtility.SampleBlock($"{afterPluginType.Name} (Static Initializer)")) { RuntimeHelpers.RunClassConstructor(afterPluginType.TypeHandle); } } using (ProfilingUtility.SampleBlock($"AfterInitializeAfterPlugins")) { EditorApplicationUtility.AfterInitializeAfterPlugins(); } using (ProfilingUtility.SampleBlock($"Delayed Calls")) { lock (delayQueue) { while (delayQueue.Count > 0) { delayQueue.Dequeue().Invoke(); } } } InternalEditorUtility.RepaintAllViews(); ProfilingUtility.Clear(); using (ProfilingUtility.SampleBlock($"Product Container Initialization")) { ProductContainer.Initialize(); } using (ProfilingUtility.SampleBlock($"Launch Setup Wizards")) { // Automatically show setup wizards if (!EditorApplication.isPlayingOrWillChangePlaymode) { var productsRequiringSetup = ProductContainer.products.Where(product => product.requiresSetup).ToHashSet(); var productsHandlingAllSetups = productsRequiringSetup.ToHashSet(); // Do not show product setups if another product already // includes all the same plugins or more. For example, // if both Bolt and Ludiq require setup, but Bolt requires // all of the Ludiq plugins, then only the Bolt setup wizard // should be shown. foreach (var product in productsRequiringSetup) { foreach (var otherProduct in productsRequiringSetup) { if (product == otherProduct) { continue; } var productPlugins = product.plugins.ResolveDependencies().ToHashSet(); var otherProductPlugins = otherProduct.plugins.ResolveDependencies().ToHashSet(); if (productPlugins.IsSubsetOf(otherProductPlugins)) { productsHandlingAllSetups.Remove(product); } } } foreach (var product in productsHandlingAllSetups) { // Delay call is used here to avoid showing multiple wizards during an import EditorApplication.delayCall += () => product.setupWizard.Show(); } } } using (ProfilingUtility.SampleBlock($"Launch Update Wizard")) { // Automatically show update wizard if (!EditorApplication.isPlayingOrWillChangePlaymode && plugins.Any(plugin => plugin.manifest.versionMismatch)) { // Delay call seems to be needed here to avoid arcane exceptions... // Too lazy to debug why, it works that way. EditorApplication.delayCall += () => UpdateWizard.global.Show(); } } } }