Esempio n. 1
0
        /// <summary>
        /// Loads a plugin required by another.
        /// </summary>
        /// <param name="targetPlugin">The plugin to load</param>
        /// <param name="dependantPlugin">The plugin requesting the load</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="targetPlugin"/> or <paramref name="dependantPlugin"/> is null.</exception>
        public virtual void LoadRequiredPlugin(SkyEditorPlugin pluginToLoad, SkyEditorPlugin dependantPlugin)
        {
            if (pluginToLoad == null)
            {
                throw new ArgumentNullException(nameof(pluginToLoad));
            }

            if (dependantPlugin == null)
            {
                throw new ArgumentNullException(nameof(dependantPlugin));
            }

            // - Create the dependant plugin list if it doesn't exist
            if (!DependantPlugins.ContainsKey(pluginToLoad))
            {
                DependantPlugins.Add(pluginToLoad, new List <SkyEditorPlugin>());
            }

            // - Add the plugin to the dependant plugin list
            if (!DependantPlugins[pluginToLoad].Contains(dependantPlugin))
            {
                DependantPlugins[pluginToLoad].Add(dependantPlugin);
            }

            // Mark this plugin as a dependant, will be loaded by plugin engine later
            // Because loading takes place in a For Each loop iterating through Plugins, we cannot load plugins here, because that would change the collection.
            DependantPluginLoadingQueue.Enqueue(pluginToLoad);
        }
Esempio n. 2
0
        /// <summary>
        /// Loads the given Core plugin and any other available plugins, if supported by the environment.
        /// </summary>
        /// <param name="core">The core plugin that controls the environment.</param>
        /// <remarks>
        /// Misc things this function does:
        /// - Delete files scheduled for deletion
        /// - Install pending extensions
        /// </remarks>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="core"/> is null.</exception>
        public virtual async Task LoadCore(CoreSkyEditorPlugin core)
        {
            if (core == null)
            {
                throw new ArgumentNullException(nameof(core));
            }

            // Load providers
            CurrentFileSystem       = core.GetFileSystem();
            CurrentSettingsProvider = core.GetSettingsProvider(this);
            CurrentConsoleProvider  = core.GetConsoleProvider();

            // Delete files and directories scheduled for deletion
            await DeleteScheduledFiles(CurrentSettingsProvider, CurrentFileSystem);

            // Install pending extensions
            ExtensionDirectory = core.GetExtensionDirectory();
            await ExtensionHelper.InstallPendingExtensions(ExtensionDirectory, this);

            // Load the provided core
            CorePluginAssembly = core.GetType().GetTypeInfo().Assembly;
            Plugins.Add(core);
            core.Load(this);

            // Load plugins, if enabled
            if (core.IsPluginLoadingEnabled())
            {
                // Get the paths of all plugins to be loaded
                var supportedPlugins = GetPluginPaths();

                // Load the plugin assemblies
                foreach (var item in supportedPlugins)
                {
                    try
                    {
                        var assemblyActual = core.LoadAssembly(item);
                        if (assemblyActual != null)
                        {
                            PluginAssemblies.Add(assemblyActual);
                            foreach (var plg in assemblyActual.DefinedTypes.Where((x) => ReflectionHelpers.IsOfType(x, typeof(SkyEditorPlugin).GetTypeInfo()) && this.CanCreateInstance(x)))
                            {
                                Plugins.Add(this.CreateInstance(plg) as SkyEditorPlugin);
                            }
                        }
                    }
                    catch (FileLoadException)
                    {
                        // The assembly is a bad assembly.  We can continue loading plugins, but not with this
                        FailedPluginLoads.Add(item);
                    }
                    catch (BadImageFormatException)
                    {
                        // The assembly is a bad assembly.  We can continue loading plugins, but not with this
                        FailedPluginLoads.Add(item);
                    }
                    catch (NotSupportedException)
                    {
                        // The current environment does not support loading assemblies this way.
                        // Abort dynamic assembly loading
                        break;
                    }
                }
            }

            // Load logical plugins
            PluginsLoading?.Invoke(this, new EventArgs());

            var coreType = core.GetType();

            foreach (var item in Plugins.Where(p => p.GetType() != core.GetType()))
            {
                item.Load(this);
            }

            // Load dependant plugins
            while (DependantPluginLoadingQueue.Count > 0)
            {
                var item       = DependantPluginLoadingQueue.Dequeue();
                var pluginType = item.GetType();

                // Determine if it has already been loaded
                if (!Plugins.Where((x) => x.GetType() == pluginType).Any())
                {
                    // Add the plugin
                    Plugins.Add(item);

                    // Add the assembly if it hasn't been added already
                    var pluginAssembly = pluginType.GetTypeInfo().Assembly;
                    if (!PluginAssemblies.Contains(pluginAssembly))
                    {
                        PluginAssemblies.Add(pluginAssembly);
                    }

                    // Load the plugin
                    item.Load(this);
                }
            }

            // Use reflection to fill the type registry
            if (core.IsCorePluginAssemblyDynamicTypeLoadEnabled())
            {
                LoadTypes(CorePluginAssembly);
            }
            if (core.IsExtraPluginAssemblyDynamicTypeLoadEnabled())
            {
                foreach (var item in PluginAssemblies)
                {
                    LoadTypes(item);
                }
            }

            PluginLoadComplete?.Invoke(this, new EventArgs());
        }