Exemplo n.º 1
0
        /// <summary>
        /// Reloads the specified plugin. Does not initialize it.
        /// </summary>
        /// <param name="pluginFilePath"></param>
        public T ReloadPlugin(string pluginFilePath)
        {
            // If we're trying to reload an active backend plugin, stop
            foreach (var pair in this.pluginRegistry)
            {
                T plugin = pair.Value;
                if (PathOp.ArePathsEqual(plugin.FilePath, pluginFilePath))
                {
                    foreach (Assembly lockedAssembly in this.lockedPlugins)
                    {
                        if (plugin.PluginAssembly == lockedAssembly)
                        {
                            this.pluginLog.WriteError(
                                "Can't reload plugin {0}, because it has been locked by the runtime. " +
                                "This usually happens for plugins that implement a currently active backend.",
                                LogFormat.Assembly(lockedAssembly));
                            return(null);
                        }
                    }
                    break;
                }
            }

            // Load the updated plugin Assembly
            Assembly pluginAssembly = null;

            try
            {
                pluginAssembly = this.assemblyLoader.LoadAssembly(pluginFilePath);
            }
            catch (Exception e)
            {
                this.pluginLog.WriteError("Error loading plugin Assembly: {0}", LogFormat.Exception(e));
                return(null);
            }

            // If we're overwriting an old plugin here, add the old version to the "disposed" blacklist
            string assemblyName = pluginAssembly.GetShortAssemblyName();
            T      oldPlugin;

            if (this.pluginRegistry.TryGetValue(assemblyName, out oldPlugin))
            {
                this.pluginRegistry.Remove(assemblyName);
                this.disposedPlugins.Add(oldPlugin.PluginAssembly);
                this.OnPluginsRemoving(new[] { oldPlugin });
                oldPlugin.Dispose();
            }

            // Load the new plugin from the updated Assembly
            T updatedPlugin = this.LoadPlugin(pluginAssembly, pluginFilePath);

            // Discard temporary plugin-related data (cached Types, etc.)
            this.OnPluginsRemoved(new[] { oldPlugin });

            return(updatedPlugin);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes this DualityApp. Should be called before performing any operations within Duality.
        /// </summary>
        /// <param name="env"></param>
        /// <param name="context">The <see cref="ExecutionContext"/> in which Duality runs.</param>
        /// <param name="plugins"></param>
        /// <param name="launcherArgs">
        /// Command line arguments to run this DualityApp with.
        /// Usually these are just the ones from the host application, passed on.
        /// </param>
        public static void Init(ExecutionEnvironment env, ExecutionContext context, IAssemblyLoader plugins, LauncherArgs launcherArgs)
        {
            if (initialized)
            {
                return;
            }

            // Process command line options
            if (launcherArgs.IsDebugging)
            {
                System.Diagnostics.Debugger.Launch();
            }
            // Run from editor
            if (launcherArgs.IsRunFromEditor)
            {
                runFromEditor = true;
            }

            // If the core was compiled in debug mode and a debugger is attached, log
            // to the Debug channel, so we can put the VS output window to good use.
#if DEBUG
            bool isDebugging = System.Diagnostics.Debugger.IsAttached;
            if (isDebugging)
            {
                // Only add a new Debug output if we don't already have one, and don't
                // log to a Console channel either. VS will automatically redirect Console
                // output to the Output window when debugging a non-Console application,
                // and we don't want to end up with double log entries.
                bool hasDebugOut   = Logs.GlobalOutput.OfType <DebugLogOutput>().Any();
                bool hasConsoleOut = Logs.GlobalOutput.OfType <TextWriterLogOutput>().Any(w => w.GetType().Name.Contains("Console"));
                if (!hasDebugOut && !hasConsoleOut)
                {
                    Logs.AddGlobalOutput(new DebugLogOutput());
                }
            }
                        #endif

            environment = env;
            execContext = context;

            // Initialize the plugin manager
            {
                assemblyLoader = plugins ?? new Duality.Backend.Dummy.DummyAssemblyLoader();
                Logs.Core.Write("Using '{0}' to load plugins.", assemblyLoader.GetType().Name);

                assemblyLoader.Init();

                // Log assembly loading data for diagnostic purposes
                {
                    Logs.Core.Write("Currently Loaded Assemblies:" + Environment.NewLine + "{0}",
                                    assemblyLoader.LoadedAssemblies.ToString(
                                        assembly => "  " + LogFormat.Assembly(assembly),
                                        Environment.NewLine));
                    Logs.Core.Write("Plugin Base Directories:" + Environment.NewLine + "{0}",
                                    assemblyLoader.BaseDirectories.ToString(
                                        path => "  " + path,
                                        Environment.NewLine));
                    Logs.Core.Write("Available Assembly Paths:" + Environment.NewLine + "{0}",
                                    assemblyLoader.AvailableAssemblyPaths.ToString(
                                        path => "  " + path,
                                        Environment.NewLine));
                }

                pluginManager.Init(assemblyLoader);
                pluginManager.PluginsRemoving += pluginManager_PluginsRemoving;
                pluginManager.PluginsRemoved  += pluginManager_PluginsRemoved;
            }

            // Load all plugins. This needs to be done first, so backends and Types can be located.
            pluginManager.LoadPlugins();

            // Initialize the system backend for system info and file system access
            InitBackend(out systemBack);

            // Load application and user data and submit a change event, so all settings are applied
            DualityApp.AppData.Load();
            DualityApp.UserData.Load();

            // Initialize the graphics backend
            InitBackend(out graphicsBack);

            // Initialize the audio backend
            InitBackend(out audioBack);
            sound = new SoundDevice();

            // Initialize all core plugins, this may allocate Resources or establish references between plugins
            pluginManager.InitPlugins();

            initialized = true;

            // Write environment specs as a debug log
            Logs.Core.Write(
                "DualityApp initialized" + Environment.NewLine +
                "Debug Mode: {0}" + Environment.NewLine +
                "Command line arguments: {1}",
                System.Diagnostics.Debugger.IsAttached,
                launcherArgs.ToString());
        }