Turn Collections to List instead of Dict.

This commit is contained in:
Ottermandias 2022-03-23 13:03:55 +01:00
parent 9c0fc8a8c7
commit 519543772c
9 changed files with 50 additions and 36 deletions

View file

@ -134,7 +134,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
CheckInitialized(); CheckInitialized();
try try
{ {
if( !Penumbra.CollectionManager.Collections.TryGetValue( collectionName, out var collection ) ) if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
{ {
collection = ModCollection.Empty; collection = ModCollection.Empty;
} }

View file

@ -135,7 +135,7 @@ public partial class MetaManager
fileDescriptor->ResourceHandle->FileNameLength = split[ 1 ].Length; fileDescriptor->ResourceHandle->FileNameLength = split[ 1 ].Length;
var ret = Penumbra.ResourceLoader.ReadSqPackHook.Original( resourceManager, fileDescriptor, priority, isSync ); 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 != null
&& collection.Cache.MetaManipulations.Imc.Files.TryGetValue( && collection.Cache.MetaManipulations.Imc.Files.TryGetValue(
Utf8GamePath.FromSpan( split[ 1 ].Span, out var p, false ) ? p : Utf8GamePath.Empty, out var file ) ) Utf8GamePath.FromSpan( split[ 1 ].Span, out var p, false ) ? p : Utf8GamePath.Empty, out var file ) )

View file

@ -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 ); collection.UpdateSetting( baseDir, meta, true );
} }

View file

@ -5,7 +5,6 @@ using System.Linq;
using Dalamud.Logging; using Dalamud.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Penumbra.GameData.ByteString; using Penumbra.GameData.ByteString;
using Penumbra.GameData.Util;
namespace Penumbra.Mod; namespace Penumbra.Mod;

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Dalamud.Logging; using Dalamud.Logging;
@ -25,7 +26,7 @@ public class CollectionManager : IDisposable
{ {
private readonly ModManager _manager; 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 Dictionary< string, ModCollection > CharacterCollection { get; } = new();
public ModCollection CurrentCollection { get; private set; } = ModCollection.Empty; public ModCollection CurrentCollection { get; private set; } = ModCollection.Empty;
@ -35,6 +36,15 @@ public class CollectionManager : IDisposable
public bool IsActive( ModCollection collection ) public bool IsActive( ModCollection collection )
=> ReferenceEquals( collection, DefaultCollection ) || ReferenceEquals( collection, ForcedCollection ); => 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. // Is invoked after the collections actually changed.
public event CollectionChangeDelegate? CollectionChanged; public event CollectionChangeDelegate? CollectionChanged;
@ -43,6 +53,7 @@ public class CollectionManager : IDisposable
_manager = manager; _manager = manager;
_manager.ModsRediscovered += OnModsRediscovered; _manager.ModsRediscovered += OnModsRediscovered;
_manager.ModChange += OnModChanged;
ReadCollections(); ReadCollections();
LoadConfigCollections( Penumbra.Config ); LoadConfigCollections( Penumbra.Config );
} }
@ -50,6 +61,7 @@ public class CollectionManager : IDisposable
public void Dispose() public void Dispose()
{ {
_manager.ModsRediscovered -= OnModsRediscovered; _manager.ModsRediscovered -= OnModsRediscovered;
_manager.ModChange -= OnModChanged;
} }
private void OnModsRediscovered() private void OnModsRediscovered()
@ -63,7 +75,7 @@ public class CollectionManager : IDisposable
switch( type ) switch( type )
{ {
case ModChangeType.Added: case ModChangeType.Added:
foreach( var collection in Collections.Values ) foreach( var collection in Collections )
{ {
collection.AddMod( mod ); collection.AddMod( mod );
} }
@ -75,7 +87,7 @@ public class CollectionManager : IDisposable
case ModChangeType.Changed: case ModChangeType.Changed:
// TODO // TODO
break; 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() 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 ) ); collection.CreateCache( _manager.StructuredMods.AllMods( _manager.Config.SortFoldersFirst ) );
} }
@ -101,7 +113,7 @@ public class CollectionManager : IDisposable
public void RemoveModFromCaches( DirectoryInfo modDir ) public void RemoveModFromCaches( DirectoryInfo modDir )
{ {
foreach( var collection in Collections.Values ) foreach( var collection in Collections )
{ {
collection.Cache?.RemoveMod( modDir ); 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 ) 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 ) if( metaChanges )
{ {
@ -138,16 +150,16 @@ public class CollectionManager : IDisposable
public bool AddCollection( string name, Dictionary< string, ModSettings > settings ) public bool AddCollection( string name, Dictionary< string, ModSettings > settings )
{ {
var nameFixed = name.RemoveInvalidPathSymbols().ToLowerInvariant(); 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." ); PluginLog.Warning( $"The new collection {name} would lead to the same path as one that already exists." );
return false; return false;
} }
var newCollection = new ModCollection( name, settings ); var newCollection = new ModCollection( name, settings );
Collections.Add( name, newCollection ); Collections.Add( newCollection );
CollectionChanged?.Invoke( null, newCollection, CollectionType.Inactive );
newCollection.Save(); newCollection.Save();
CollectionChanged?.Invoke( null, newCollection, CollectionType.Inactive );
SetCollection( newCollection, CollectionType.Current ); SetCollection( newCollection, CollectionType.Current );
return true; return true;
} }
@ -160,15 +172,17 @@ public class CollectionManager : IDisposable
return false; return false;
} }
if( !Collections.TryGetValue( name, out var collection ) ) var idx = Collections.IndexOf( c => c.Name == name );
if( idx < 0 )
{ {
return false; return false;
} }
CollectionChanged?.Invoke( collection, null, CollectionType.Inactive ); var collection = Collections[ idx ];
if( CurrentCollection == collection ) if( CurrentCollection == collection )
{ {
SetCollection( Collections[ ModCollection.DefaultCollection ], CollectionType.Current ); SetCollection( Default, CollectionType.Current );
} }
if( ForcedCollection == collection ) if( ForcedCollection == collection )
@ -190,7 +204,8 @@ public class CollectionManager : IDisposable
} }
collection.Delete(); collection.Delete();
Collections.Remove( name ); Collections.RemoveAt( idx );
CollectionChanged?.Invoke( collection, null, CollectionType.Inactive );
return true; return true;
} }
@ -294,7 +309,7 @@ public class CollectionManager : IDisposable
private bool LoadCurrentCollection( Configuration config ) private bool LoadCurrentCollection( Configuration config )
{ {
if( Collections.TryGetValue( config.CurrentCollection, out var currentCollection ) ) if( ByName( config.CurrentCollection, out var currentCollection ) )
{ {
CurrentCollection = currentCollection; CurrentCollection = currentCollection;
AddCache( 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." ); PluginLog.Error( $"Last choice of CurrentCollection {config.CurrentCollection} is not available, reset to Default." );
CurrentCollection = Collections[ ModCollection.DefaultCollection ]; CurrentCollection = Default;
if( CurrentCollection.Cache == null ) if( CurrentCollection.Cache == null )
{ {
CurrentCollection.CreateCache( _manager.StructuredMods.AllMods( _manager.Config.SortFoldersFirst ) ); CurrentCollection.CreateCache( _manager.StructuredMods.AllMods( _manager.Config.SortFoldersFirst ) );
@ -320,7 +335,7 @@ public class CollectionManager : IDisposable
return false; return false;
} }
if( Collections.TryGetValue( config.ForcedCollection, out var forcedCollection ) ) if( ByName( config.ForcedCollection, out var forcedCollection ) )
{ {
ForcedCollection = forcedCollection; ForcedCollection = forcedCollection;
AddCache( ForcedCollection ); AddCache( ForcedCollection );
@ -341,7 +356,7 @@ public class CollectionManager : IDisposable
return false; return false;
} }
if( Collections.TryGetValue( config.DefaultCollection, out var defaultCollection ) ) if( ByName( config.DefaultCollection, out var defaultCollection ) )
{ {
DefaultCollection = defaultCollection; DefaultCollection = defaultCollection;
AddCache( DefaultCollection ); AddCache( DefaultCollection );
@ -363,7 +378,7 @@ public class CollectionManager : IDisposable
{ {
CharacterCollection.Add( player, ModCollection.Empty ); CharacterCollection.Add( player, ModCollection.Empty );
} }
else if( Collections.TryGetValue( collectionName, out var charCollection ) ) else if( ByName( collectionName, out var charCollection ) )
{ {
AddCache( charCollection ); AddCache( charCollection );
CharacterCollection.Add( player, charCollection ); CharacterCollection.Add( player, charCollection );
@ -411,22 +426,22 @@ public class CollectionManager : IDisposable
PluginLog.Warning( $"Collection {file.Name} does not correspond to {collection.Name}." ); 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." ); PluginLog.Warning( $"Duplicate collection found: {collection.Name} already exists." );
} }
else else
{ {
Collections.Add( collection.Name, collection ); Collections.Add( collection );
} }
} }
} }
if( !Collections.ContainsKey( ModCollection.DefaultCollection ) ) if( ByName( ModCollection.DefaultCollection ) == null )
{ {
var defaultCollection = new ModCollection(); var defaultCollection = new ModCollection();
defaultCollection.Save(); defaultCollection.Save();
Collections.Add( defaultCollection.Name, defaultCollection ); Collections.Add( defaultCollection );
} }
} }
} }

View file

@ -82,7 +82,7 @@ public static class ModManagerEditExtensions
manager.Config.Save(); 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 ) ) if( collection.Settings.TryGetValue( oldBasePath.Name, out var settings ) )
{ {
@ -140,7 +140,7 @@ public static class ModManagerEditExtensions
mod.SaveMeta(); 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 ) ) if( !collection.Settings.TryGetValue( mod.BasePath.Name, out var settings ) )
{ {
@ -176,7 +176,7 @@ public static class ModManagerEditExtensions
return ( oldSetting & bitmaskFront ) | ( ( oldSetting & bitmaskBack ) >> 1 ); 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 ) ) if( !collection.Settings.TryGetValue( mod.BasePath.Name, out var settings ) )
{ {

View file

@ -214,7 +214,7 @@ public class Penumbra : IDalamudPlugin
var collection = string.Equals( collectionName, ModCollection.Empty.Name, StringComparison.InvariantCultureIgnoreCase ) var collection = string.Equals( collectionName, ModCollection.Empty.Name, StringComparison.InvariantCultureIgnoreCase )
? ModCollection.Empty ? ModCollection.Empty
: CollectionManager.Collections.Values.FirstOrDefault( c : CollectionManager.Collections.FirstOrDefault( c
=> string.Equals( c.Name, collectionName, StringComparison.InvariantCultureIgnoreCase ) ); => string.Equals( c.Name, collectionName, StringComparison.InvariantCultureIgnoreCase ) );
if( collection == null ) if( collection == null )
{ {

View file

@ -31,7 +31,7 @@ public partial class SettingsInterface
private void UpdateNames() 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'; _collectionNames = string.Join( "\0", _collections.Skip( 1 ).Select( c => c.Name ) ) + '\0';
_collectionNamesWithNone = "None\0" + _collectionNames; _collectionNamesWithNone = "None\0" + _collectionNames;
UpdateIndices(); UpdateIndices();
@ -87,7 +87,7 @@ public partial class SettingsInterface
if( Penumbra.CollectionManager.AddCollection( _newCollectionName, settings ) ) if( Penumbra.CollectionManager.AddCollection( _newCollectionName, settings ) )
{ {
UpdateNames(); UpdateNames();
SetCurrentCollection( Penumbra.CollectionManager.Collections[ _newCollectionName ], true ); SetCurrentCollection( Penumbra.CollectionManager.ByName( _newCollectionName )!, true );
} }
_newCollectionName = string.Empty; _newCollectionName = string.Empty;
@ -222,7 +222,7 @@ public partial class SettingsInterface
{ {
var index = _currentForcedIndex; var index = _currentForcedIndex;
ImGui.SetNextItemWidth( SettingsMenu.InputTextWidth ); 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 ) if( ImGui.Combo( "##Forced Collection", ref index, _collectionNamesWithNone )
&& index != _currentForcedIndex && index != _currentForcedIndex
&& Penumbra.CollectionManager.CharacterCollection.Count > 0 ) && Penumbra.CollectionManager.CharacterCollection.Count > 0 )

View file

@ -422,14 +422,14 @@ public partial class SettingsInterface
_fullFilenameList = null; _fullFilenameList = null;
_selector.SaveCurrentMod(); _selector.SaveCurrentMod();
// Since files may have changed, we need to recompute effective files. // Since files may have changed, we need to recompute effective files.
foreach( var collection in Penumbra.CollectionManager.Collections.Values foreach( var collection in Penumbra.CollectionManager.Collections
.Where( c => c.Cache != null && c.Settings[ Mod!.Data.BasePath.Name ].Enabled ) ) .Where( c => c.Cache != null && c.Settings[ Mod.Data.BasePath.Name ].Enabled ) )
{ {
collection.CalculateEffectiveFileList( false, Penumbra.CollectionManager.IsActive( collection ) ); collection.CalculateEffectiveFileList( false, Penumbra.CollectionManager.IsActive( collection ) );
} }
// If the mod is enabled in the current collection, its conflicts may have changed. // 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(); _selector.Cache.TriggerFilterReset();
} }