/// <summary> /// Returns a string that can be used for representing a <see cref="System.Reflection.Assembly"/> in log entries. /// </summary> /// <param name="asm"></param> /// <returns></returns> public static string Assembly(Assembly asm) { if (asm == null) return "null"; string shortName = asm.GetShortAssemblyName(); try { Version version = asm.GetName().Version; return string.Format("{0} {1}", shortName, version); } catch (Exception) { return string.Format("{0} {1}", shortName, "[Error retrieving Version]"); } }
/// <summary> /// Returns a string that can be used for representing a <see cref="System.Reflection.Assembly"/> in log entries. /// </summary> /// <param name="asm"></param> /// <returns></returns> public static string Assembly(Assembly asm) { return asm.GetShortAssemblyName(); }
private static void RemovePlugin(Assembly pluginAssembly) { CorePlugin plugin; if (plugins.TryGetValue(pluginAssembly.GetShortAssemblyName(), out plugin)) { RemovePlugin(plugin); } }
/// <summary> /// Adds an already loaded plugin Assembly to the internal Duality CorePlugin registry. /// You shouldn't need to call this method in general, since Duality manages its plugins /// automatically. /// </summary> /// <remarks> /// This method can be useful in certain cases when it is necessary to treat an Assembly as a /// Duality plugin, even though it isn't located in the Plugins folder, or is not available /// as a file at all. A typical case for this is Unit Testing where the testing Assembly may /// specify additional Duality types such as Components, Resources, etc. /// </remarks> /// <param name="pluginAssembly"></param> /// <param name="pluginFilePath"></param> /// <returns></returns> public static CorePlugin LoadPlugin(Assembly pluginAssembly, string pluginFilePath) { disposedPlugins.Remove(pluginAssembly); string asmName = pluginAssembly.GetShortAssemblyName(); CorePlugin plugin = plugins.Values.FirstOrDefault(p => p.AssemblyName == asmName); if (plugin != null) return plugin; Type pluginType = pluginAssembly.GetExportedTypes().FirstOrDefault(t => typeof(CorePlugin).IsAssignableFrom(t)); if (pluginType == null) { Log.Core.WriteWarning("Can't find CorePlugin class. Discarding plugin..."); disposedPlugins.Add(pluginAssembly); } else { try { plugin = (CorePlugin)pluginType.CreateInstanceOf(); plugin.FilePath = pluginFilePath; plugin.LoadPlugin(); plugins.Add(plugin.AssemblyName, plugin); } catch (Exception e) { Log.Core.WriteError("Error loading plugin: {0}", Log.Exception(e)); disposedPlugins.Add(pluginAssembly); plugin = null; } } return plugin; }
private static void CleanInputSources(Assembly invalidAssembly) { string warningText = string.Format( "Found leaked input source '{1}' defined in invalid Assembly '{0}'. " + "This is a common problem when registering input sources from within a CorePlugin " + "without properly unregistering them later. Please make sure that all sources are " + "unregistered in CorePlugin::OnDisposePlugin().", invalidAssembly.GetShortAssemblyName(), "{0}"); if (mouse.Source != null && mouse.Source.GetType().Assembly == invalidAssembly) { mouse.Source = null; Log.Core.WriteWarning(warningText, Log.Type(mouse.Source.GetType())); } if (keyboard.Source != null && keyboard.Source.GetType().Assembly == invalidAssembly) { keyboard.Source = null; Log.Core.WriteWarning(warningText, Log.Type(keyboard.Source.GetType())); } foreach (JoystickInput joystick in joysticks.ToArray()) { if (joystick.Source != null && joystick.Source.GetType().Assembly == invalidAssembly) { joysticks.RemoveSource(joystick.Source); Log.Core.WriteWarning(warningText, Log.Type(joystick.Source.GetType())); } } foreach (GamepadInput gamepad in gamepads.ToArray()) { if (gamepad.Source != null && gamepad.Source.GetType().Assembly == invalidAssembly) { gamepads.RemoveSource(gamepad.Source); Log.Core.WriteWarning(warningText, Log.Type(gamepad.Source.GetType())); } } }
private static void CleanEventBindings(Assembly invalidAssembly) { // Note that this method is only a countermeasure against common mistakes. It doesn't guarantee // full error safety in all cases. Event bindings inbetween different plugins aren't checked, // for example. string warningText = string.Format( "Found leaked event bindings to invalid Assembly '{0}' from {1}. " + "This is a common problem when registering global events from within a CorePlugin " + "without properly unregistering them later. Please make sure that all events are " + "unregistered in CorePlugin::OnDisposePlugin().", invalidAssembly.GetShortAssemblyName(), "{0}"); if (ReflectionHelper.CleanEventBindings(typeof(DualityApp), invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(DualityApp))); if (ReflectionHelper.CleanEventBindings(typeof(Scene), invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(Scene))); if (ReflectionHelper.CleanEventBindings(typeof(Resource), invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(Resource))); if (ReflectionHelper.CleanEventBindings(typeof(ContentProvider), invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(ContentProvider))); if (ReflectionHelper.CleanEventBindings(Log.LogData, invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(Log)) + ".LogData"); if (ReflectionHelper.CleanEventBindings(keyboard, invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(DualityApp)) + ".Keyboard"); if (ReflectionHelper.CleanEventBindings(mouse, invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(DualityApp)) + ".Mouse"); foreach (JoystickInput joystick in joysticks) { if (ReflectionHelper.CleanEventBindings(joystick, invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(DualityApp)) + ".Joysticks"); } foreach (GamepadInput gamepad in gamepads) { if (ReflectionHelper.CleanEventBindings(gamepad, invalidAssembly)) Log.Core.WriteWarning(warningText, Log.Type(typeof(DualityApp)) + ".Gamepads"); } }
/// <summary> /// Adds an already loaded plugin Assembly to the internal Duality CorePlugin registry. /// You shouldn't need to call this method in general, since Duality manages its plugins /// automatically. /// </summary> /// <remarks> /// This method can be useful in certain cases when it is necessary to treat an Assembly as a /// Duality plugin, even though it isn't located in the Plugins folder, or is not available /// as a file at all. A typical case for this is Unit Testing where the testing Assembly may /// specify additional Duality types such as Components, Resources, etc. /// </remarks> /// <param name="pluginAssembly"></param> /// <param name="pluginFilePath"></param> /// <returns></returns> public static CorePlugin AddPlugin(Assembly pluginAssembly, string pluginFilePath) { if (disposedPlugins.Contains(pluginAssembly)) return null; string asmName = pluginAssembly.GetShortAssemblyName(); CorePlugin plugin = plugins.Values.FirstOrDefault(p => p.AssemblyName == asmName); if (plugin != null) return plugin; Type pluginType = pluginAssembly.GetExportedTypes().FirstOrDefault(t => typeof(CorePlugin).IsAssignableFrom(t)); if (pluginType == null) { disposedPlugins.Add(pluginAssembly); } else { plugin = (CorePlugin)pluginType.CreateInstanceOf(); plugin.FilePath = pluginFilePath; plugins.Add(plugin.AssemblyName, plugin); } return plugin; }