From 209fbc6de035c457c48ce06267ece9dd16855b5e Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sun, 6 Sep 2020 22:06:45 +1000 Subject: [PATCH] Add and use ReflectionCache classes --- src/BizHawk.Client.Common/ReflectionCache.cs | 14 ++++++++++++++ .../movie/import/MovieImport.cs | 2 +- .../AVOut/IVideoWriter.cs | 2 +- src/BizHawk.Client.EmuHawk/Api/ApiManager.cs | 4 +--- src/BizHawk.Client.EmuHawk/BizBox.cs | 5 +---- .../CoreFeatureAnalysis.cs | 8 ++------ .../DisplayManager/DisplayManager.cs | 8 ++++---- src/BizHawk.Client.EmuHawk/MainForm.cs | 4 +--- .../Properties/Resources.cs | 9 +++------ src/BizHawk.Client.EmuHawk/ReflectionCache.cs | 17 +++++++++++++++++ .../tools/Lua/Win32LuaLibraries.cs | 4 +--- src/BizHawk.Client.EmuHawk/tools/ToolBox.cs | 3 +-- src/BizHawk.Client.EmuHawk/tools/ToolManager.cs | 7 ++----- .../tools/VirtualPads/VirtualpadsTool.cs | 5 +---- src/BizHawk.Emulation.Common/ReflectionCache.cs | 14 ++++++++++++++ .../Atari/2600/Atari2600ControllerDeck.cs | 3 +-- .../Atari/A7800Hawk/A7800HawkControllerDeck.cs | 3 +-- .../Consoles/Coleco/ColecoControllerDeck.cs | 3 +-- .../GCE/Vectrex/VectrexHawkControllerDeck.cs | 3 +-- .../Controllers/IntellivisionControllerDeck.cs | 3 +-- .../Magnavox/Odyssey2/O2HawkControllerDeck.cs | 3 +-- .../Nintendo/GBHawk/GBHawkControllerDeck.cs | 3 +-- .../GBHawkLink/GBHawkLinkControllerDeck.cs | 3 +-- .../GBHawkLink3x/GBHawkLink3xControllerDeck.cs | 3 +-- .../GBHawkLink4x/GBHawkLink4xControllerDeck.cs | 3 +-- .../Consoles/Nintendo/NES/NES.BoardSystem.cs | 2 +- .../Consoles/Nintendo/NES/NESControllers.cs | 12 +++--------- .../Sega/GGHawkLink/GGHawkLinkControllerDeck.cs | 3 +-- src/BizHawk.Emulation.Cores/CoreInventory.cs | 2 +- .../Properties/Resources.cs | 5 +---- src/BizHawk.Emulation.Cores/ReflectionCache.cs | 14 ++++++++++++++ 31 files changed, 95 insertions(+), 79 deletions(-) create mode 100644 src/BizHawk.Client.Common/ReflectionCache.cs create mode 100644 src/BizHawk.Client.EmuHawk/ReflectionCache.cs create mode 100644 src/BizHawk.Emulation.Common/ReflectionCache.cs create mode 100644 src/BizHawk.Emulation.Cores/ReflectionCache.cs diff --git a/src/BizHawk.Client.Common/ReflectionCache.cs b/src/BizHawk.Client.Common/ReflectionCache.cs new file mode 100644 index 0000000000..9d15954685 --- /dev/null +++ b/src/BizHawk.Client.Common/ReflectionCache.cs @@ -0,0 +1,14 @@ +using System; +using System.Reflection; + +namespace BizHawk.Client.Common +{ + public static class ReflectionCache + { + private static readonly Lazy _types = new Lazy(() => Asm.GetTypes()); + + public static readonly Assembly Asm = typeof(ReflectionCache).Assembly; + + public static Type[] Types => _types.Value; + } +} diff --git a/src/BizHawk.Client.Common/movie/import/MovieImport.cs b/src/BizHawk.Client.Common/movie/import/MovieImport.cs index 3cd0d0db96..ae918ef963 100644 --- a/src/BizHawk.Client.Common/movie/import/MovieImport.cs +++ b/src/BizHawk.Client.Common/movie/import/MovieImport.cs @@ -9,7 +9,7 @@ namespace BizHawk.Client.Common { public static class MovieImport { - private static readonly Dictionary Importers = Assembly.GetAssembly(typeof(ImporterForAttribute)).GetTypes() + private static readonly Dictionary Importers = Client.Common.ReflectionCache.Types .Select(t => (t, attr: (ImporterForAttribute) t.GetCustomAttributes(typeof(ImporterForAttribute)).FirstOrDefault())) .Where(tuple => tuple.attr != null) .ToDictionary(tuple => tuple.t, tuple => tuple.attr); diff --git a/src/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs b/src/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs index 473ede0e26..0a59ad7001 100644 --- a/src/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs +++ b/src/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs @@ -145,7 +145,7 @@ namespace BizHawk.Client.EmuHawk static VideoWriterInventory() { - foreach (Type t in typeof(VideoWriterInventory).Assembly.GetTypesWithoutLoadErrors()) + foreach (var t in EmuHawk.ReflectionCache.Types) { if (!t.IsInterface && typeof(IVideoWriter).IsAssignableFrom(t) diff --git a/src/BizHawk.Client.EmuHawk/Api/ApiManager.cs b/src/BizHawk.Client.EmuHawk/Api/ApiManager.cs index dca55bb3c4..7c3582f566 100644 --- a/src/BizHawk.Client.EmuHawk/Api/ApiManager.cs +++ b/src/BizHawk.Client.EmuHawk/Api/ApiManager.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using BizHawk.Client.Common; using BizHawk.Common; @@ -15,8 +14,7 @@ namespace BizHawk.Client.EmuHawk { /// keys are impl., values are interface private static readonly IReadOnlyDictionary _apiTypes - = Assembly.GetAssembly(typeof(IEmuClientApi)).GetTypes() - .Concat(Assembly.GetAssembly(typeof(EmuClientApi)).GetTypesWithoutLoadErrors()) + = Client.Common.ReflectionCache.Types.Concat(EmuHawk.ReflectionCache.Types) .Where(t => /*t.IsClass &&*/t.IsSealed) // small optimisation; api impl. types are all sealed classes .Select(t => (t, t.GetInterfaces().FirstOrDefault(t1 => typeof(IExternalApi).IsAssignableFrom(t1) && t1 != typeof(IExternalApi)))) // grab interface from impl. type... .Where(tuple => tuple.Item2 != null) // ...if we couldn't determine what it's implementing, then it's not an api impl. type diff --git a/src/BizHawk.Client.EmuHawk/BizBox.cs b/src/BizHawk.Client.EmuHawk/BizBox.cs index e8e9852942..a5c4dff9c6 100644 --- a/src/BizHawk.Client.EmuHawk/BizBox.cs +++ b/src/BizHawk.Client.EmuHawk/BizBox.cs @@ -1,7 +1,6 @@ using System; using System.Diagnostics; using System.Linq; -using System.Reflection; using System.Windows.Forms; using BizHawk.Client.EmuHawk.Properties; using BizHawk.Common; @@ -47,9 +46,7 @@ namespace BizHawk.Client.EmuHawk VersionLabel.Text = $"Version {mainVersion}"; DateLabel.Text = VersionInfo.ReleaseDate; - var cores = Assembly - .Load("BizHawk.Emulation.Cores") - .GetTypes() + var cores = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IEmulator).IsAssignableFrom(t)) .Select(t => t.GetCustomAttributes(false).OfType().FirstOrDefault()) .Where(a => a != null) diff --git a/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs b/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs index 98d4f86b70..9083b6ae3e 100644 --- a/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs +++ b/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs @@ -153,8 +153,7 @@ namespace BizHawk.Client.EmuHawk } - var knownServices = Assembly.GetAssembly(typeof(IEmulator)) - .GetTypes() + var knownServices = Emulation.Common.ReflectionCache.Types .Where(t => typeof(IEmulatorService).IsAssignableFrom(t)) .Where(t => t != typeof(IEmulatorService)) .Where(t => t != typeof(ITextStatable)) // Hack for now, eventually we can get rid of this interface in favor of a default implementation @@ -202,10 +201,7 @@ namespace BizHawk.Client.EmuHawk CoreTree.ImageList.Images.Add("Bad", Properties.Resources.ExclamationRed); CoreTree.ImageList.Images.Add("Unknown", Properties.Resources.RetroQuestion); - var possibleCoreTypes = - Assembly - .Load("BizHawk.Emulation.Cores") - .GetTypes() + var possibleCoreTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IEmulator).IsAssignableFrom(t) && !t.IsAbstract) .Select(t => new { diff --git a/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs b/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs index c3c353976d..3b241823ff 100644 --- a/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs +++ b/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs @@ -66,20 +66,20 @@ namespace BizHawk.Client.EmuHawk ShaderChainFrugalizers[i] = new RenderTargetFrugalizer(GL); } - using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt")) + using (var xml = EmuHawk.ReflectionCache.Asm.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt")) { - using var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"); + using var tex = EmuHawk.ReflectionCache.Asm.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"); TheOneFont = new StringRenderer(GL, xml, tex); } using (var gens = - typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.gens.ttf")) + EmuHawk.ReflectionCache.Asm.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.gens.ttf")) { LoadCustomFont(gens); } using (var fceux = - typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.fceux.ttf")) + EmuHawk.ReflectionCache.Asm.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.fceux.ttf")) { LoadCustomFont(fceux); } diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index 0bbc27e7d5..5376e02c31 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -1955,9 +1955,7 @@ namespace BizHawk.Client.EmuHawk } } - private static readonly IList _specializedTools = Assembly - .GetAssembly(typeof(MainForm)) - .GetTypesWithoutLoadErrors() + private static readonly IList _specializedTools = EmuHawk.ReflectionCache.Types .Where(t => typeof(IToolForm).IsAssignableFrom(t) && !t.IsAbstract) .Where(t => t.GetCustomAttribute() != null) .ToList(); diff --git a/src/BizHawk.Client.EmuHawk/Properties/Resources.cs b/src/BizHawk.Client.EmuHawk/Properties/Resources.cs index 50c2932aa9..1debd5beaf 100644 --- a/src/BizHawk.Client.EmuHawk/Properties/Resources.cs +++ b/src/BizHawk.Client.EmuHawk/Properties/Resources.cs @@ -1,23 +1,20 @@ using System; using System.Drawing; -using System.Reflection; using System.Windows.Forms; namespace BizHawk.Client.EmuHawk.Properties { internal static class Resources { - private static readonly Assembly Asm = Assembly.GetExecutingAssembly(); - /// Dir separator is '.'. Path is relative to <NS>. - private static Bitmap ReadEmbeddedBitmapAt(string embedPath) => new Bitmap(Asm.GetManifestResourceStream($"BizHawk.Client.EmuHawk.{embedPath}")); + private static Bitmap ReadEmbeddedBitmapAt(string embedPath) => new Bitmap(EmuHawk.ReflectionCache.Asm.GetManifestResourceStream($"BizHawk.Client.EmuHawk.{embedPath}")); /// Dir separator is '.'. Filename is relative to <NS>/images and omits .png extension. /// For other file extensions or paths use . private static Bitmap ReadEmbeddedBitmap(string filename) => ReadEmbeddedBitmapAt($"images.{filename}.png"); /// Dir separator is '.'. Filename is relative to <NS>/images and omits .ico extension. - private static Icon ReadEmbeddedIcon(string filename) => new Icon(Asm.GetManifestResourceStream($"BizHawk.Client.EmuHawk.images.{filename}.ico")); + private static Icon ReadEmbeddedIcon(string filename) => new Icon(EmuHawk.ReflectionCache.Asm.GetManifestResourceStream($"BizHawk.Client.EmuHawk.images.{filename}.ico")); internal static readonly Lazy A78Joystick = new Lazy(() => ReadEmbeddedBitmap("ControllerImages.A78Joystick")); internal static readonly Lazy AppleIIKeyboard = new Lazy(() => ReadEmbeddedBitmap("ControllerImages.AppleIIKeyboard")); @@ -56,7 +53,7 @@ namespace BizHawk.Client.EmuHawk.Properties internal static readonly Bitmap BackMore = ReadEmbeddedBitmap("BackMore"); internal static readonly Icon BasicBot = ReadEmbeddedIcon("basicbot"); internal static readonly Bitmap Blank = ReadEmbeddedBitmap("Blank"); - internal static readonly Cursor BlankCursor = new Cursor(Asm.GetManifestResourceStream("BizHawk.Client.EmuHawk.images.BlankCursor.cur")); + internal static readonly Cursor BlankCursor = new Cursor(EmuHawk.ReflectionCache.Asm.GetManifestResourceStream("BizHawk.Client.EmuHawk.images.BlankCursor.cur")); internal static readonly Bitmap BlueDown = ReadEmbeddedBitmap("BlueDown"); internal static readonly Bitmap BlueUp = ReadEmbeddedBitmap("BlueUp"); internal static readonly Bitmap Both = ReadEmbeddedBitmap("Both"); diff --git a/src/BizHawk.Client.EmuHawk/ReflectionCache.cs b/src/BizHawk.Client.EmuHawk/ReflectionCache.cs new file mode 100644 index 0000000000..0d6e32059b --- /dev/null +++ b/src/BizHawk.Client.EmuHawk/ReflectionCache.cs @@ -0,0 +1,17 @@ +using System; +using System.Linq; +using System.Reflection; + +using BizHawk.Common; + +namespace BizHawk.Client.EmuHawk +{ + public static class ReflectionCache + { + private static readonly Lazy _types = new Lazy(() => Asm.GetTypesWithoutLoadErrors().ToArray()); + + public static readonly Assembly Asm = typeof(ReflectionCache).Assembly; + + public static Type[] Types => _types.Value; + } +} diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs index 4a0955eb65..5e1f037bf3 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs @@ -2,7 +2,6 @@ using System.ComponentModel; using System.IO; using System.Linq; -using System.Reflection; using System.Threading; using NLua; @@ -45,8 +44,7 @@ namespace BizHawk.Client.EmuHawk Docs.Clear(); // Register lua libraries - foreach (var lib in Assembly.Load("BizHawk.Client.Common").GetTypes() - .Concat(Assembly.GetAssembly(typeof(Win32LuaLibraries)).GetTypesWithoutLoadErrors()) + foreach (var lib in Client.Common.ReflectionCache.Types.Concat(EmuHawk.ReflectionCache.Types) .Where(t => typeof(LuaLibraryBase).IsAssignableFrom(t) && t.IsSealed && ServiceInjector.IsAvailable(serviceProvider, t))) { bool addLibrary = true; diff --git a/src/BizHawk.Client.EmuHawk/tools/ToolBox.cs b/src/BizHawk.Client.EmuHawk/tools/ToolBox.cs index e66578ff0e..a52686b497 100644 --- a/src/BizHawk.Client.EmuHawk/tools/ToolBox.cs +++ b/src/BizHawk.Client.EmuHawk/tools/ToolBox.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; -using System.Reflection; using System.Windows.Forms; using BizHawk.Client.Common; @@ -45,7 +44,7 @@ namespace BizHawk.Client.EmuHawk { ToolBoxStrip.Items.Clear(); - var tools = Assembly.GetAssembly(GetType()).GetTypesWithoutLoadErrors() + var tools = EmuHawk.ReflectionCache.Types .Where(t => typeof(IToolForm).IsAssignableFrom(t)) .Where(t => typeof(Form).IsAssignableFrom(t)) .Where(t => !typeof(ToolBox).IsAssignableFrom(t)) diff --git a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs index 16e6a65d8c..03633dd74d 100644 --- a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -464,9 +464,7 @@ namespace BizHawk.Client.EmuHawk return Load(false); } - public IEnumerable AvailableTools => Assembly - .GetAssembly(typeof(ToolManager)) - .GetTypesWithoutLoadErrors() + public IEnumerable AvailableTools => EmuHawk.ReflectionCache.Types .Where(t => typeof(IToolForm).IsAssignableFrom(t)) .Where(t => !t.IsInterface) .Where(IsAvailable); @@ -701,8 +699,7 @@ namespace BizHawk.Client.EmuHawk } private static readonly Lazy> LazyAsmTypes = new Lazy>(() => - Assembly.GetAssembly(typeof(ToolManager)) // Confining the search to only EmuHawk, for now at least, we may want to broaden for external tools one day - .GetTypesWithoutLoadErrors() + EmuHawk.ReflectionCache.Types // Confining the search to only EmuHawk, for now at least, we may want to broaden for external tools one day .Select(t => t.AssemblyQualifiedName) .ToList()); diff --git a/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs b/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs index becb2fb77e..32b2a2230e 100644 --- a/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs +++ b/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Windows.Forms; using BizHawk.Common; @@ -73,9 +72,7 @@ namespace BizHawk.Client.EmuHawk { ControllerPanel.Controls.Clear(); - var schemaType = Assembly - .GetExecutingAssembly() - .GetTypesWithoutLoadErrors() + var schemaType = EmuHawk.ReflectionCache.Types .Where(t => typeof(IVirtualPadSchema) .IsAssignableFrom(t) && t.GetCustomAttributes(false) .OfType() diff --git a/src/BizHawk.Emulation.Common/ReflectionCache.cs b/src/BizHawk.Emulation.Common/ReflectionCache.cs new file mode 100644 index 0000000000..49f091642e --- /dev/null +++ b/src/BizHawk.Emulation.Common/ReflectionCache.cs @@ -0,0 +1,14 @@ +using System; +using System.Reflection; + +namespace BizHawk.Emulation.Common +{ + public static class ReflectionCache + { + private static readonly Lazy _types = new Lazy(() => Asm.GetTypes()); + + public static readonly Assembly Asm = typeof(ReflectionCache).Assembly; + + public static Type[] Types => _types.Value; + } +} diff --git a/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600ControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600ControllerDeck.cs index d393dfa52f..1b7e2fc35b 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600ControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600ControllerDeck.cs @@ -85,8 +85,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { if (_controllerTypes == null) { - _controllerTypes = typeof(Atari2600ControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs index 96cf583efc..48a1e976a0 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs @@ -121,8 +121,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk { if (_controllerTypes == null) { - _controllerTypes = typeof(A7800HawkControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoControllerDeck.cs index 0ba3671694..7f93f032a5 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoControllerDeck.cs @@ -87,8 +87,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision { if (_controllerTypes == null) { - _controllerTypes = typeof(ColecoVisionControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs index c4d953cd47..6c88c306cc 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawkControllerDeck.cs @@ -76,8 +76,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex { if (_controllerTypes == null) { - _controllerTypes = typeof(VectrexHawkControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Controllers/IntellivisionControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Controllers/IntellivisionControllerDeck.cs index 4b33ade67b..1679a911d8 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Controllers/IntellivisionControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Controllers/IntellivisionControllerDeck.cs @@ -76,8 +76,7 @@ namespace BizHawk.Emulation.Cores.Intellivision { if (_controllerTypes == null) { - _controllerTypes = typeof(IntellivisionControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs index 0e0188efa3..228a7ab695 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2HawkControllerDeck.cs @@ -102,8 +102,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { if (_controllerTypes == null) { - _controllerTypes = typeof(O2HawkControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllerDeck.cs index 990dadd16a..f425a73685 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawkControllerDeck.cs @@ -63,8 +63,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { if (_controllerTypes == null) { - _controllerTypes = typeof(GBHawkControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs index 7f789b0059..38f36ab78d 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs @@ -69,8 +69,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink { if (_controllerTypes == null) { - _controllerTypes = typeof(GBHawkLinkControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs index ea26952ef1..4970acad31 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs @@ -88,8 +88,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x { if (_controllerTypes == null) { - _controllerTypes = typeof(GBHawkLink3xControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs index ae7bd533bf..2092ec5223 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs @@ -106,8 +106,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x { if (_controllerTypes == null) { - _controllerTypes = typeof(GBHawkLink4xControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs index d581592c16..5a3aff80dc 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs @@ -85,7 +85,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES var normalPriority = new List(); //scan types in this assembly to find ones that implement boards to add them to the list - foreach (Type type in typeof(NES).Assembly.GetTypes()) + foreach (var type in Emulation.Cores.ReflectionCache.Types) { var attrs = type.GetCustomAttributes(typeof(NesBoardImplAttribute), true); if (attrs.Length == 0) continue; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs index b88301ff3c..be84108944 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs @@ -1114,15 +1114,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES static readonly Dictionary FamicomExpansions; static readonly Dictionary NesPortDevices; - static Dictionary Implementors() - { - var assy = typeof(NESControlSettings).Assembly; - var types = assy.GetTypes().Where(c => typeof(T).IsAssignableFrom(c) && !c.IsAbstract && !c.IsInterface); - var ret = new Dictionary(); - foreach (Type t in types) - ret[t.Name] = t; - return ret; - } + static Dictionary Implementors() => Emulation.Cores.ReflectionCache.Types + .Where(c => typeof(T).IsAssignableFrom(c) && !c.IsAbstract && !c.IsInterface) + .ToDictionary(t => t.Name, t => t); static NESControlSettings() { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLinkControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLinkControllerDeck.cs index 82cfed4c06..398b3f4fee 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLinkControllerDeck.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLinkControllerDeck.cs @@ -69,8 +69,7 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink { if (_controllerTypes == null) { - _controllerTypes = typeof(GGHawkLinkControllerDeck).Assembly - .GetTypes() + _controllerTypes = Emulation.Cores.ReflectionCache.Types .Where(t => typeof(IPort).IsAssignableFrom(t)) .Where(t => !t.IsAbstract && !t.IsInterface) .ToDictionary(tkey => tkey.DisplayName()); diff --git a/src/BizHawk.Emulation.Cores/CoreInventory.cs b/src/BizHawk.Emulation.Cores/CoreInventory.cs index 523b91b576..3aac68802c 100644 --- a/src/BizHawk.Emulation.Cores/CoreInventory.cs +++ b/src/BizHawk.Emulation.Cores/CoreInventory.cs @@ -168,7 +168,7 @@ namespace BizHawk.Emulation.Cores } } - public static readonly CoreInventory Instance = new CoreInventory(new[] { typeof(CoreInventory).Assembly }); + public static readonly CoreInventory Instance = new CoreInventory(new[] { Emulation.Cores.ReflectionCache.Asm }); } public enum CorePriority diff --git a/src/BizHawk.Emulation.Cores/Properties/Resources.cs b/src/BizHawk.Emulation.Cores/Properties/Resources.cs index caf84ab094..e836350cf9 100644 --- a/src/BizHawk.Emulation.Cores/Properties/Resources.cs +++ b/src/BizHawk.Emulation.Cores/Properties/Resources.cs @@ -1,14 +1,11 @@ using System; -using System.Reflection; using BizHawk.Common.IOExtensions; namespace BizHawk.Emulation.Cores.Properties { internal static class Resources { - private static readonly Assembly Asm = typeof(Resources).Assembly; - /// Dir separator is '.'. Path is relative to <NS>. - private static byte[] ReadEmbeddedByteArray(string embedPath) => Asm.GetManifestResourceStream($"BizHawk.Emulation.Cores.Resources.{embedPath}").ReadAllBytes(); + private static byte[] ReadEmbeddedByteArray(string embedPath) => Emulation.Cores.ReflectionCache.Asm.GetManifestResourceStream($"BizHawk.Emulation.Cores.Resources.{embedPath}").ReadAllBytes(); internal static readonly Lazy CPC_AMSDOS_0_5_ROM = new Lazy(() => ReadEmbeddedByteArray("CPC_AMSDOS_0.5.ROM.gz")); internal static readonly Lazy CPC_BASIC_1_0_ROM = new Lazy(() => ReadEmbeddedByteArray("CPC_BASIC_1.0.ROM.gz")); diff --git a/src/BizHawk.Emulation.Cores/ReflectionCache.cs b/src/BizHawk.Emulation.Cores/ReflectionCache.cs new file mode 100644 index 0000000000..15f8c93486 --- /dev/null +++ b/src/BizHawk.Emulation.Cores/ReflectionCache.cs @@ -0,0 +1,14 @@ +using System; +using System.Reflection; + +namespace BizHawk.Emulation.Cores +{ + public static class ReflectionCache + { + private static readonly Lazy _types = new Lazy(() => Asm.GetTypes()); + + public static readonly Assembly Asm = typeof(ReflectionCache).Assembly; + + public static Type[] Types => _types.Value; + } +}