From 519543772c3bbcb380b9850d61ca0c20ff4f56db Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 23 Mar 2022 13:03:55 +0100 Subject: [PATCH] Turn Collections to List instead of Dict. --- Penumbra/Api/PenumbraApi.cs | 2 +- Penumbra/Meta/Manager/MetaManager.Imc.cs | 2 +- Penumbra/Mod/ModCleanup.cs | 2 +- Penumbra/Mod/ModMeta.cs | 1 - Penumbra/Mods/CollectionManager.cs | 59 ++++++++++++------- Penumbra/Mods/ModManagerEditExtensions.cs | 6 +- Penumbra/Penumbra.cs | 2 +- Penumbra/UI/MenuTabs/TabCollections.cs | 6 +- .../TabInstalled/TabInstalledDetails.cs | 6 +- 9 files changed, 50 insertions(+), 36 deletions(-) diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index ef649144..540e1432 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -134,7 +134,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi CheckInitialized(); try { - if( !Penumbra.CollectionManager.Collections.TryGetValue( collectionName, out var collection ) ) + if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) ) { collection = ModCollection.Empty; } diff --git a/Penumbra/Meta/Manager/MetaManager.Imc.cs b/Penumbra/Meta/Manager/MetaManager.Imc.cs index 991094f4..abe86fe5 100644 --- a/Penumbra/Meta/Manager/MetaManager.Imc.cs +++ b/Penumbra/Meta/Manager/MetaManager.Imc.cs @@ -135,7 +135,7 @@ public partial class MetaManager fileDescriptor->ResourceHandle->FileNameLength = split[ 1 ].Length; var ret = Penumbra.ResourceLoader.ReadSqPackHook.Original( resourceManager, fileDescriptor, priority, isSync ); - if( Penumbra.CollectionManager.Collections.TryGetValue( split[ 0 ].ToString(), out var collection ) + if( Penumbra.CollectionManager.ByName( split[ 0 ].ToString(), out var collection ) && collection.Cache != null && collection.Cache.MetaManipulations.Imc.Files.TryGetValue( Utf8GamePath.FromSpan( split[ 1 ].Span, out var p, false ) ? p : Utf8GamePath.Empty, out var file ) ) diff --git a/Penumbra/Mod/ModCleanup.cs b/Penumbra/Mod/ModCleanup.cs index 8e202351..38c316e2 100644 --- a/Penumbra/Mod/ModCleanup.cs +++ b/Penumbra/Mod/ModCleanup.cs @@ -521,7 +521,7 @@ public class ModCleanup } } - foreach( var collection in Penumbra.CollectionManager.Collections.Values ) + foreach( var collection in Penumbra.CollectionManager.Collections ) { collection.UpdateSetting( baseDir, meta, true ); } diff --git a/Penumbra/Mod/ModMeta.cs b/Penumbra/Mod/ModMeta.cs index 5a4776eb..d4c18b3b 100644 --- a/Penumbra/Mod/ModMeta.cs +++ b/Penumbra/Mod/ModMeta.cs @@ -5,7 +5,6 @@ using System.Linq; using Dalamud.Logging; using Newtonsoft.Json; using Penumbra.GameData.ByteString; -using Penumbra.GameData.Util; namespace Penumbra.Mod; diff --git a/Penumbra/Mods/CollectionManager.cs b/Penumbra/Mods/CollectionManager.cs index 9763bfa4..7f6e5468 100644 --- a/Penumbra/Mods/CollectionManager.cs +++ b/Penumbra/Mods/CollectionManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using Dalamud.Logging; @@ -25,7 +26,7 @@ public class CollectionManager : IDisposable { private readonly ModManager _manager; - public Dictionary< string, ModCollection > Collections { get; } = new(StringComparer.InvariantCultureIgnoreCase); + public List< ModCollection > Collections { get; } = new(); public Dictionary< string, ModCollection > CharacterCollection { get; } = new(); public ModCollection CurrentCollection { get; private set; } = ModCollection.Empty; @@ -35,6 +36,15 @@ public class CollectionManager : IDisposable public bool IsActive( ModCollection collection ) => ReferenceEquals( collection, DefaultCollection ) || ReferenceEquals( collection, ForcedCollection ); + public ModCollection Default + => ByName( ModCollection.DefaultCollection )!; + + public ModCollection? ByName( string name ) + => Collections.Find( c => c.Name == name ); + + public bool ByName( string name, [NotNullWhen( true )] out ModCollection? collection ) + => Collections.FindFirst( c => c.Name == name, out collection ); + // Is invoked after the collections actually changed. public event CollectionChangeDelegate? CollectionChanged; @@ -43,6 +53,7 @@ public class CollectionManager : IDisposable _manager = manager; _manager.ModsRediscovered += OnModsRediscovered; + _manager.ModChange += OnModChanged; ReadCollections(); LoadConfigCollections( Penumbra.Config ); } @@ -50,6 +61,7 @@ public class CollectionManager : IDisposable public void Dispose() { _manager.ModsRediscovered -= OnModsRediscovered; + _manager.ModChange -= OnModChanged; } private void OnModsRediscovered() @@ -63,7 +75,7 @@ public class CollectionManager : IDisposable switch( type ) { case ModChangeType.Added: - foreach( var collection in Collections.Values ) + foreach( var collection in Collections ) { collection.AddMod( mod ); } @@ -75,7 +87,7 @@ public class CollectionManager : IDisposable case ModChangeType.Changed: // TODO break; - default: throw new ArgumentOutOfRangeException( nameof( type ), type, null ); + default: throw new ArgumentOutOfRangeException( nameof( type ), type, null ); } } @@ -91,7 +103,7 @@ public class CollectionManager : IDisposable public void RecreateCaches() { - foreach( var collection in Collections.Values.Where( c => c.Cache != null ) ) + foreach( var collection in Collections.Where( c => c.Cache != null ) ) { collection.CreateCache( _manager.StructuredMods.AllMods( _manager.Config.SortFoldersFirst ) ); } @@ -101,7 +113,7 @@ public class CollectionManager : IDisposable public void RemoveModFromCaches( DirectoryInfo modDir ) { - foreach( var collection in Collections.Values ) + foreach( var collection in Collections ) { collection.Cache?.RemoveMod( modDir ); } @@ -109,7 +121,7 @@ public class CollectionManager : IDisposable internal void UpdateCollections( ModData mod, bool metaChanges, ResourceChange fileChanges, bool nameChange, bool reloadMeta ) { - foreach( var collection in Collections.Values ) + foreach( var collection in Collections ) { if( metaChanges ) { @@ -138,16 +150,16 @@ public class CollectionManager : IDisposable public bool AddCollection( string name, Dictionary< string, ModSettings > settings ) { var nameFixed = name.RemoveInvalidPathSymbols().ToLowerInvariant(); - if( nameFixed.Length == 0 || Collections.Values.Any( c => c.Name.RemoveInvalidPathSymbols().ToLowerInvariant() == nameFixed ) ) + if( nameFixed.Length == 0 || Collections.Any( c => c.Name.RemoveInvalidPathSymbols().ToLowerInvariant() == nameFixed ) ) { PluginLog.Warning( $"The new collection {name} would lead to the same path as one that already exists." ); return false; } var newCollection = new ModCollection( name, settings ); - Collections.Add( name, newCollection ); - CollectionChanged?.Invoke( null, newCollection, CollectionType.Inactive ); + Collections.Add( newCollection ); newCollection.Save(); + CollectionChanged?.Invoke( null, newCollection, CollectionType.Inactive ); SetCollection( newCollection, CollectionType.Current ); return true; } @@ -160,15 +172,17 @@ public class CollectionManager : IDisposable return false; } - if( !Collections.TryGetValue( name, out var collection ) ) + var idx = Collections.IndexOf( c => c.Name == name ); + if( idx < 0 ) { return false; } - CollectionChanged?.Invoke( collection, null, CollectionType.Inactive ); + var collection = Collections[ idx ]; + if( CurrentCollection == collection ) { - SetCollection( Collections[ ModCollection.DefaultCollection ], CollectionType.Current ); + SetCollection( Default, CollectionType.Current ); } if( ForcedCollection == collection ) @@ -190,7 +204,8 @@ public class CollectionManager : IDisposable } collection.Delete(); - Collections.Remove( name ); + Collections.RemoveAt( idx ); + CollectionChanged?.Invoke( collection, null, CollectionType.Inactive ); return true; } @@ -294,7 +309,7 @@ public class CollectionManager : IDisposable private bool LoadCurrentCollection( Configuration config ) { - if( Collections.TryGetValue( config.CurrentCollection, out var currentCollection ) ) + if( ByName( config.CurrentCollection, out var currentCollection ) ) { CurrentCollection = currentCollection; AddCache( CurrentCollection ); @@ -302,7 +317,7 @@ public class CollectionManager : IDisposable } PluginLog.Error( $"Last choice of CurrentCollection {config.CurrentCollection} is not available, reset to Default." ); - CurrentCollection = Collections[ ModCollection.DefaultCollection ]; + CurrentCollection = Default; if( CurrentCollection.Cache == null ) { CurrentCollection.CreateCache( _manager.StructuredMods.AllMods( _manager.Config.SortFoldersFirst ) ); @@ -320,7 +335,7 @@ public class CollectionManager : IDisposable return false; } - if( Collections.TryGetValue( config.ForcedCollection, out var forcedCollection ) ) + if( ByName( config.ForcedCollection, out var forcedCollection ) ) { ForcedCollection = forcedCollection; AddCache( ForcedCollection ); @@ -341,7 +356,7 @@ public class CollectionManager : IDisposable return false; } - if( Collections.TryGetValue( config.DefaultCollection, out var defaultCollection ) ) + if( ByName( config.DefaultCollection, out var defaultCollection ) ) { DefaultCollection = defaultCollection; AddCache( DefaultCollection ); @@ -363,7 +378,7 @@ public class CollectionManager : IDisposable { CharacterCollection.Add( player, ModCollection.Empty ); } - else if( Collections.TryGetValue( collectionName, out var charCollection ) ) + else if( ByName( collectionName, out var charCollection ) ) { AddCache( charCollection ); CharacterCollection.Add( player, charCollection ); @@ -411,22 +426,22 @@ public class CollectionManager : IDisposable PluginLog.Warning( $"Collection {file.Name} does not correspond to {collection.Name}." ); } - if( Collections.ContainsKey( collection.Name ) ) + if( ByName( collection.Name ) != null ) { PluginLog.Warning( $"Duplicate collection found: {collection.Name} already exists." ); } else { - Collections.Add( collection.Name, collection ); + Collections.Add( collection ); } } } - if( !Collections.ContainsKey( ModCollection.DefaultCollection ) ) + if( ByName( ModCollection.DefaultCollection ) == null ) { var defaultCollection = new ModCollection(); defaultCollection.Save(); - Collections.Add( defaultCollection.Name, defaultCollection ); + Collections.Add( defaultCollection ); } } } \ No newline at end of file diff --git a/Penumbra/Mods/ModManagerEditExtensions.cs b/Penumbra/Mods/ModManagerEditExtensions.cs index 59714c16..93c96c86 100644 --- a/Penumbra/Mods/ModManagerEditExtensions.cs +++ b/Penumbra/Mods/ModManagerEditExtensions.cs @@ -82,7 +82,7 @@ public static class ModManagerEditExtensions manager.Config.Save(); } - foreach( var collection in Penumbra.CollectionManager.Collections.Values ) + foreach( var collection in Penumbra.CollectionManager.Collections ) { if( collection.Settings.TryGetValue( oldBasePath.Name, out var settings ) ) { @@ -140,7 +140,7 @@ public static class ModManagerEditExtensions mod.SaveMeta(); - foreach( var collection in Penumbra.CollectionManager.Collections.Values ) + foreach( var collection in Penumbra.CollectionManager.Collections ) { if( !collection.Settings.TryGetValue( mod.BasePath.Name, out var settings ) ) { @@ -176,7 +176,7 @@ public static class ModManagerEditExtensions return ( oldSetting & bitmaskFront ) | ( ( oldSetting & bitmaskBack ) >> 1 ); } - foreach( var collection in Penumbra.CollectionManager.Collections.Values ) + foreach( var collection in Penumbra.CollectionManager.Collections ) { if( !collection.Settings.TryGetValue( mod.BasePath.Name, out var settings ) ) { diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs index 8dc512f8..bdea9ecd 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/Penumbra.cs @@ -214,7 +214,7 @@ public class Penumbra : IDalamudPlugin var collection = string.Equals( collectionName, ModCollection.Empty.Name, StringComparison.InvariantCultureIgnoreCase ) ? ModCollection.Empty - : CollectionManager.Collections.Values.FirstOrDefault( c + : CollectionManager.Collections.FirstOrDefault( c => string.Equals( c.Name, collectionName, StringComparison.InvariantCultureIgnoreCase ) ); if( collection == null ) { diff --git a/Penumbra/UI/MenuTabs/TabCollections.cs b/Penumbra/UI/MenuTabs/TabCollections.cs index 18bf6b82..4bcb4224 100644 --- a/Penumbra/UI/MenuTabs/TabCollections.cs +++ b/Penumbra/UI/MenuTabs/TabCollections.cs @@ -31,7 +31,7 @@ public partial class SettingsInterface private void UpdateNames() { - _collections = Penumbra.CollectionManager.Collections.Values.Prepend( ModCollection.Empty ).ToArray(); + _collections = Penumbra.CollectionManager.Collections.Prepend( ModCollection.Empty ).ToArray(); _collectionNames = string.Join( "\0", _collections.Skip( 1 ).Select( c => c.Name ) ) + '\0'; _collectionNamesWithNone = "None\0" + _collectionNames; UpdateIndices(); @@ -87,7 +87,7 @@ public partial class SettingsInterface if( Penumbra.CollectionManager.AddCollection( _newCollectionName, settings ) ) { UpdateNames(); - SetCurrentCollection( Penumbra.CollectionManager.Collections[ _newCollectionName ], true ); + SetCurrentCollection( Penumbra.CollectionManager.ByName( _newCollectionName )!, true ); } _newCollectionName = string.Empty; @@ -222,7 +222,7 @@ public partial class SettingsInterface { var index = _currentForcedIndex; ImGui.SetNextItemWidth( SettingsMenu.InputTextWidth ); - using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, Penumbra.CollectionManager.CharacterCollection.Count == 0 ); + using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, Penumbra.CollectionManager.CharacterCollection.Count == 0 ); if( ImGui.Combo( "##Forced Collection", ref index, _collectionNamesWithNone ) && index != _currentForcedIndex && Penumbra.CollectionManager.CharacterCollection.Count > 0 ) diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs index 1e0a92d1..3843fdb6 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs @@ -422,14 +422,14 @@ public partial class SettingsInterface _fullFilenameList = null; _selector.SaveCurrentMod(); // Since files may have changed, we need to recompute effective files. - foreach( var collection in Penumbra.CollectionManager.Collections.Values - .Where( c => c.Cache != null && c.Settings[ Mod!.Data.BasePath.Name ].Enabled ) ) + foreach( var collection in Penumbra.CollectionManager.Collections + .Where( c => c.Cache != null && c.Settings[ Mod.Data.BasePath.Name ].Enabled ) ) { collection.CalculateEffectiveFileList( false, Penumbra.CollectionManager.IsActive( collection ) ); } // If the mod is enabled in the current collection, its conflicts may have changed. - if( Mod!.Settings.Enabled ) + if( Mod.Settings.Enabled ) { _selector.Cache.TriggerFilterReset(); }