From eb0301f964396439dea901f24da60cb9ea41720b Mon Sep 17 00:00:00 2001 From: Adam <893184+NotAdam@users.noreply.github.com> Date: Sun, 21 Feb 2021 17:38:19 +1100 Subject: [PATCH] enable nullability checks, wip service locator --- Penumbra/API/ModsController.cs | 7 +++- Penumbra/Mods/ModManager.cs | 4 +- Penumbra/Penumbra.csproj | 1 + Penumbra/Plugin.cs | 12 +++--- Penumbra/ResourceLoader.cs | 40 +++++++++++-------- Penumbra/Service.cs | 60 +++++++++++++++++++++++++++++ Penumbra/UI/SettingsInterface.cs | 4 +- Penumbra/UI/TabEffective.cs | 3 +- Penumbra/UI/TabInstalled.cs | 3 +- Penumbra/UI/TabInstalledDetails.cs | 6 ++- Penumbra/UI/TabInstalledModPanel.cs | 8 ++-- Penumbra/UI/TabInstalledSelector.cs | 8 ++-- 12 files changed, 115 insertions(+), 41 deletions(-) create mode 100644 Penumbra/Service.cs diff --git a/Penumbra/API/ModsController.cs b/Penumbra/API/ModsController.cs index 93e939e8..3c9b953e 100644 --- a/Penumbra/API/ModsController.cs +++ b/Penumbra/API/ModsController.cs @@ -2,6 +2,7 @@ using System.Linq; using EmbedIO; using EmbedIO.Routing; using EmbedIO.WebApi; +using Penumbra.Mods; namespace Penumbra.API { @@ -14,7 +15,8 @@ namespace Penumbra.API [Route( HttpVerbs.Get, "/mods" )] public object GetMods() { - return _plugin.ModManager.Mods.ModSettings.Select( x => new + var modManager = Service< ModManager >.Get(); + return modManager.Mods.ModSettings.Select( x => new { x.Enabled, x.Priority, @@ -28,7 +30,8 @@ namespace Penumbra.API [Route( HttpVerbs.Get, "/files" )] public object CreateMod() { - return _plugin.ModManager.ResolvedFiles.ToDictionary( + var modManager = Service< ModManager >.Get(); + return modManager.ResolvedFiles.ToDictionary( o => o.Key, o => o.Value.FullName ); diff --git a/Penumbra/Mods/ModManager.cs b/Penumbra/Mods/ModManager.cs index 20f739c8..f2dd88d4 100644 --- a/Penumbra/Mods/ModManager.cs +++ b/Penumbra/Mods/ModManager.cs @@ -112,7 +112,7 @@ namespace Penumbra.Mods if( settings.Conf == null ) { settings.Conf = new Dictionary< string, int >(); - _plugin.ModManager.Mods.Save(); + Mods.Save(); } ProcessModFiles( registeredFiles, mod, settings ); @@ -162,7 +162,7 @@ namespace Penumbra.Mods && settings.Conf[ group.GroupName ] >= group.Options.Count ) { settings.Conf[ group.GroupName ] = 0; - _plugin.ModManager.Mods.Save(); + Mods.Save(); setting = 0; } diff --git a/Penumbra/Penumbra.csproj b/Penumbra/Penumbra.csproj index e07c8d05..ede71eb8 100644 --- a/Penumbra/Penumbra.csproj +++ b/Penumbra/Penumbra.csproj @@ -10,6 +10,7 @@ 1.0.0.0 bin\$(Configuration)\ true + enable diff --git a/Penumbra/Plugin.cs b/Penumbra/Plugin.cs index 3215cbb6..626faf25 100644 --- a/Penumbra/Plugin.cs +++ b/Penumbra/Plugin.cs @@ -22,8 +22,6 @@ namespace Penumbra public ResourceLoader ResourceLoader { get; set; } - public ModManager ModManager { get; set; } - public SettingsInterface SettingsInterface { get; set; } public GameUtils GameUtils { get; set; } @@ -41,8 +39,8 @@ namespace Penumbra GameUtils = new GameUtils( PluginInterface ); - ModManager = new ModManager( this ); - ModManager.DiscoverMods( Configuration.CurrentCollection ); + var modManager = Service< ModManager >.Set( this ); + modManager.DiscoverMods( Configuration.CurrentCollection ); ResourceLoader = new ResourceLoader( this ); @@ -94,7 +92,7 @@ namespace Penumbra public void Dispose() { - ModManager?.Dispose(); + // ModManager?.Dispose(); PluginInterface.UiBuilder.OnBuildUi -= SettingsInterface.Draw; @@ -115,9 +113,9 @@ namespace Penumbra { case "reload": { - ModManager.DiscoverMods(); + Service< ModManager >.Get().DiscoverMods(); PluginInterface.Framework.Gui.Chat.Print( - $"Reloaded Penumbra mods. You have {ModManager.Mods.ModSettings.Count} mods, {ModManager.Mods.EnabledMods.Length} of which are enabled." + $"Reloaded Penumbra mods. You have {Service< ModManager >.Get().Mods.ModSettings.Count} mods, {Service< ModManager >.Get().Mods.EnabledMods.Length} of which are enabled." ); break; } diff --git a/Penumbra/ResourceLoader.cs b/Penumbra/ResourceLoader.cs index 1fa7c5b5..60ab97f3 100644 --- a/Penumbra/ResourceLoader.cs +++ b/Penumbra/ResourceLoader.cs @@ -1,8 +1,10 @@ using System; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Text; using Dalamud.Plugin; +using Penumbra.Mods; using Penumbra.Structs; using Penumbra.Util; using Reloaded.Hooks; @@ -129,31 +131,35 @@ namespace Penumbra PluginLog.Log( "[GetResourceHandler] {0}", gameFsPath ); } - if( Plugin.Configuration.IsEnabled ) + var modManager = Service< ModManager >.Get(); + + if( !Plugin.Configuration.IsEnabled || modManager == null ) { - var replacementPath = Plugin.ModManager.ResolveSwappedOrReplacementFilePath( gameFsPath ); + return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown ); + } - // path must be < 260 because statically defined array length :( - if( replacementPath == null || replacementPath.Length >= 260 ) - { - return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown ); - } + var replacementPath = modManager.ResolveSwappedOrReplacementFilePath( gameFsPath ); - var cleanPath = replacementPath.Replace( '\\', '/' ); - var path = Encoding.ASCII.GetBytes( cleanPath ); + // path must be < 260 because statically defined array length :( + if( replacementPath == null || replacementPath.Length >= 260 ) + { + return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown ); + } - var bPath = stackalloc byte[path.Length + 1]; - Marshal.Copy( path, 0, new IntPtr( bPath ), path.Length ); - pPath = ( char* )bPath; + var cleanPath = replacementPath.Replace( '\\', '/' ); + var path = Encoding.ASCII.GetBytes( cleanPath ); - Crc32.Init(); - Crc32.Update( path ); - *pResourceHash = Crc32.Checksum; + var bPath = stackalloc byte[path.Length + 1]; + Marshal.Copy( path, 0, new IntPtr( bPath ), path.Length ); + pPath = ( char* )bPath; + + Crc32.Init(); + Crc32.Update( path ); + *pResourceHash = Crc32.Checksum; #if DEBUG - PluginLog.Log( "[GetResourceHandler] resolved {GamePath} to {NewPath}", gameFsPath, replacementPath ); + PluginLog.Log( "[GetResourceHandler] resolved {GamePath} to {NewPath}", gameFsPath, replacementPath ); #endif - } return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown ); } diff --git a/Penumbra/Service.cs b/Penumbra/Service.cs new file mode 100644 index 00000000..6f198f0c --- /dev/null +++ b/Penumbra/Service.cs @@ -0,0 +1,60 @@ +using System; + +namespace Penumbra +{ + /// + /// Basic service locator + /// + /// The class you want to store in the service locator + public static class Service< T > where T : class + { + private static T? _object; + + static Service() + { + } + + public static void Set( T obj ) + { + // ReSharper disable once JoinNullCheckWithUsage + if( obj == null ) + { + throw new ArgumentNullException( $"{nameof( obj )} is null!" ); + } + + _object = obj; + } + + public static T Set() + { + _object = Activator.CreateInstance< T >(); + + return _object; + } + + public static T Set( params object[] args ) + { + var obj = ( T? )Activator.CreateInstance( typeof( T ), args ); + + // ReSharper disable once JoinNullCheckWithUsage + if( obj == null ) + { + throw new Exception( "what he fuc" ); + } + + _object = obj; + + return obj; + } + + public static T Get() + { + if( _object == null ) + { + throw new InvalidOperationException( $"{nameof( T )} hasn't been registered!" ); + } + + return _object; + } + } +} \ No newline at end of file diff --git a/Penumbra/UI/SettingsInterface.cs b/Penumbra/UI/SettingsInterface.cs index 6e6b011e..709729e7 100644 --- a/Penumbra/UI/SettingsInterface.cs +++ b/Penumbra/UI/SettingsInterface.cs @@ -1,5 +1,6 @@ using System.IO; using System.Numerics; +using Penumbra.Mods; namespace Penumbra.UI { @@ -40,7 +41,8 @@ namespace Penumbra.UI // create the directory if it doesn't exist Directory.CreateDirectory( _plugin.Configuration.CurrentCollection ); - _plugin.ModManager.DiscoverMods( _plugin.Configuration.CurrentCollection ); + var modManager = Service< ModManager >.Get(); + modManager.DiscoverMods( _plugin.Configuration.CurrentCollection ); _menu.EffectiveTab.RebuildFileList( _plugin.Configuration.ShowAdvanced ); _menu.InstalledTab.Selector.ResetModNamesLower(); } diff --git a/Penumbra/UI/TabEffective.cs b/Penumbra/UI/TabEffective.cs index b758e0ed..e22c8978 100644 --- a/Penumbra/UI/TabEffective.cs +++ b/Penumbra/UI/TabEffective.cs @@ -11,13 +11,12 @@ namespace Penumbra.UI private const string LabelTab = "Effective File List"; private const float TextSizePadding = 5f; - private readonly ModManager _mods; + private ModManager _mods => Service< ModManager >.Get(); private (string, string)[] _fileList; private float _maxGamePath; public TabEffective( SettingsInterface ui ) { - _mods = ui._plugin.ModManager; RebuildFileList( ui._plugin.Configuration.ShowAdvanced ); } diff --git a/Penumbra/UI/TabInstalled.cs b/Penumbra/UI/TabInstalled.cs index 54d1942a..09ac8d10 100644 --- a/Penumbra/UI/TabInstalled.cs +++ b/Penumbra/UI/TabInstalled.cs @@ -1,4 +1,5 @@ using ImGuiNET; +using Penumbra.Mods; namespace Penumbra.UI { @@ -37,7 +38,7 @@ namespace Penumbra.UI return; } - if( _base._plugin.ModManager.Mods != null ) + if( Service< ModManager >.Get().Mods != null ) { Selector.Draw(); ImGui.SameLine(); diff --git a/Penumbra/UI/TabInstalledDetails.cs b/Penumbra/UI/TabInstalledDetails.cs index 59897609..cad534d2 100644 --- a/Penumbra/UI/TabInstalledDetails.cs +++ b/Penumbra/UI/TabInstalledDetails.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using ImGuiNET; using Penumbra.Models; +using Penumbra.Mods; namespace Penumbra.UI { @@ -127,8 +128,9 @@ namespace Penumbra.UI private void Save() { - _base._plugin.ModManager.Mods.Save(); - _base._plugin.ModManager.CalculateEffectiveFileList(); + var modManager = Service< ModManager >.Get(); + modManager.Mods.Save(); + modManager.CalculateEffectiveFileList(); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); } diff --git a/Penumbra/UI/TabInstalledModPanel.cs b/Penumbra/UI/TabInstalledModPanel.cs index 2b49289b..6315fb0d 100644 --- a/Penumbra/UI/TabInstalledModPanel.cs +++ b/Penumbra/UI/TabInstalledModPanel.cs @@ -4,6 +4,7 @@ using System.Numerics; using Dalamud.Plugin; using ImGuiNET; using Penumbra.Models; +using Penumbra.Mods; namespace Penumbra.UI { @@ -184,8 +185,9 @@ namespace Penumbra.UI if( ImGui.Checkbox( LabelModEnabled, ref enabled ) ) { Mod.Enabled = enabled; - _base._plugin.ModManager.Mods.Save(); - _base._plugin.ModManager.CalculateEffectiveFileList(); + var modManager = Service< ModManager >.Get(); + modManager.Mods.Save(); + modManager.CalculateEffectiveFileList(); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); } } @@ -241,7 +243,7 @@ namespace Penumbra.UI new Deduplicator( Mod.Mod.ModBasePath, Meta ).Run(); _selector.SaveCurrentMod(); Mod.Mod.RefreshModFiles(); - _base._plugin.ModManager.CalculateEffectiveFileList(); + Service< ModManager >.Get().CalculateEffectiveFileList(); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); } diff --git a/Penumbra/UI/TabInstalledSelector.cs b/Penumbra/UI/TabInstalledSelector.cs index a8c954b7..b0ac4045 100644 --- a/Penumbra/UI/TabInstalledSelector.cs +++ b/Penumbra/UI/TabInstalledSelector.cs @@ -32,7 +32,7 @@ namespace Penumbra.UI private static readonly string ArrowDownString = FontAwesomeIcon.ArrowDown.ToIconString(); private readonly SettingsInterface _base; - private ModCollection Mods => _base._plugin.ModManager.Mods; + private ModCollection Mods => Service< ModManager >.Get().Mods; private ModInfo _mod; private int _index; @@ -60,7 +60,7 @@ namespace Penumbra.UI if( ImGui.Button( iconString, SelectorButtonSizes ) ) { SetSelection( _index ); - _base._plugin.ModManager.ChangeModPriority( _mod, up ); + Service< ModManager >.Get().ChangeModPriority( _mod, up ); _modNamesLower.Swap( _index, _index + ( up ? 1 : -1 ) ); _index += up ? 1 : -1; } @@ -177,7 +177,7 @@ namespace Penumbra.UI if( ImGui.Button( ButtonYesDelete ) ) { ImGui.CloseCurrentPopup(); - _base._plugin.ModManager.DeleteMod( _mod.Mod ); + Service< ModManager >.Get().DeleteMod( _mod.Mod ); ClearSelection(); _base.ReloadMods(); } @@ -321,7 +321,7 @@ namespace Penumbra.UI } _mod.Mod.RefreshModFiles(); - _base._plugin.ModManager.CalculateEffectiveFileList(); + Service< ModManager >.Get().CalculateEffectiveFileList(); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); ResetModNamesLower(); }