/// <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); }
/// <summary> /// Initializes this CoheeApp. Should be called before performing any operations within Cohee. /// </summary> /// <param name="context">The <see cref="ExecutionContext"/> in which Duality runs.</param> /// <param name="commandLineArgs"> /// Command line arguments to run this CoheeApp with. /// Usually these are just the ones from the host application, passed on. /// </param> public static void Init(ExecutionEnvironment env, ExecutionContext context, IAssemblyLoader assemLoader, string[] commandLineArgs) { if (initialized) { return; } // Process command line options if (commandLineArgs != null) { // Enter debug mode if (commandLineArgs.Contains(CmdArgDebug)) { System.Diagnostics.Debugger.Launch(); } // Run from editor if (commandLineArgs.Contains(CmdArgEditor)) { 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 = assemLoader ?? new Cohee.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)); } corePluginManager.Init(assemblyLoader); corePluginManager.PluginsRemoving += pluginManager_PluginsRemoving; corePluginManager.PluginsRemoved += pluginManager_PluginsRemoved; } // Load all plugins. This needs to be done first, so backends and Types can be located. corePluginManager.LoadPlugins(); // Initialize the system backend for system info and file system access InitBackend(out systemBackend); // Load application and user data and submit a change event, so all settings are applied LoadAppData(); LoadUserData(); OnAppDataChanged(); OnUserDataChanged(); // Initialize the graphics backend InitBackend(out graphicsBackend); // Initialize the audio backend InitBackend(out audioBackend); //sound = new SoundDevice(); // Initialize all core plugins, this may allocate Resources or establish references between plugins corePluginManager.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, commandLineArgs != null ? commandLineArgs.ToString(", ") : "null"); }