From c2fb18ab5380c4cfdf05562e5de42310cf42fe1a Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Mon, 1 May 2023 18:43:49 +0200 Subject: [PATCH] Change CollectionCache handling. --- .../Cache/CollectionCacheManager.cs | 65 ++++++++++--------- Penumbra/Penumbra.cs | 4 +- Penumbra/UI/ImportPopup.cs | 3 +- Penumbra/UI/Tabs/DebugTab.cs | 53 +++++++-------- 4 files changed, 63 insertions(+), 62 deletions(-) diff --git a/Penumbra/Collections/Cache/CollectionCacheManager.cs b/Penumbra/Collections/Cache/CollectionCacheManager.cs index 336d52a9..5a4ab2dd 100644 --- a/Penumbra/Collections/Cache/CollectionCacheManager.cs +++ b/Penumbra/Collections/Cache/CollectionCacheManager.cs @@ -21,20 +21,18 @@ public class CollectionCacheManager : IDisposable private readonly CommunicatorService _communicator; private readonly TempModManager _tempMods; private readonly ModStorage _modStorage; + private readonly CollectionStorage _storage; private readonly ActiveCollections _active; internal readonly MetaFileManager MetaFileManager; - private readonly Dictionary _caches = new(); + public int Count { get; private set; } - public int Count - => _caches.Count; - - public IEnumerable<(ModCollection Collection, CollectionCache Cache)> Active - => _caches.Where(c => c.Key.Index > ModCollection.Empty.Index).Select(p => (p.Key, p.Value)); + public IEnumerable Active + => _storage.Where(c => c.HasCache); public CollectionCacheManager(FrameworkManager framework, CommunicatorService communicator, - TempModManager tempMods, ModStorage modStorage, MetaFileManager metaFileManager, ActiveCollections active) + TempModManager tempMods, ModStorage modStorage, MetaFileManager metaFileManager, ActiveCollections active, CollectionStorage storage) { _framework = framework; _communicator = communicator; @@ -42,6 +40,7 @@ public class CollectionCacheManager : IDisposable _modStorage = modStorage; MetaFileManager = metaFileManager; _active = active; + _storage = storage; _communicator.CollectionChange.Subscribe(OnCollectionChange, -100); _communicator.ModPathChanged.Subscribe(OnModChangeAddition, -100); @@ -72,12 +71,11 @@ public class CollectionCacheManager : IDisposable /// Only creates a new cache, does not update an existing one. public bool CreateCache(ModCollection collection) { - if (_caches.ContainsKey(collection) || collection.Index == ModCollection.Empty.Index) + if (collection.HasCache || collection.Index == ModCollection.Empty.Index) return false; - var cache = new CollectionCache(this, collection); - _caches.Add(collection, cache); - collection._cache = cache; + collection._cache = new CollectionCache(this, collection); + ++Count; Penumbra.Log.Verbose($"Created new cache for collection {collection.AnonymizedName}."); return true; } @@ -97,28 +95,34 @@ public class CollectionCacheManager : IDisposable return; Penumbra.Log.Debug($"[{Thread.CurrentThread.ManagedThreadId}] Recalculating effective file list for {collection.AnonymizedName}"); - if (!_caches.TryGetValue(collection, out var cache)) + if (!collection.HasCache) { Penumbra.Log.Error( $"[{Thread.CurrentThread.ManagedThreadId}] Recalculating effective file list for {collection.AnonymizedName} failed, no cache exists."); return; } - FullRecalculation(collection, cache); + FullRecalculation(collection); Penumbra.Log.Debug( $"[{Thread.CurrentThread.ManagedThreadId}] Recalculation of effective file list for {collection.AnonymizedName} finished."); } - private void FullRecalculation(ModCollection collection, CollectionCache cache) + private void FullRecalculation(ModCollection collection) { + var cache = collection._cache; + if (cache == null) + return; + cache.ResolvedFiles.Clear(); cache.Meta.Reset(); cache._conflicts.Clear(); // Add all forced redirects. - foreach (var tempMod in _tempMods.ModsForAllCollections.Concat( - _tempMods.Mods.TryGetValue(collection, out var list) ? list : Array.Empty())) + foreach (var tempMod in _tempMods.ModsForAllCollections + .Concat(_tempMods.Mods.TryGetValue(collection, out var list) + ? list + : Array.Empty())) cache.AddMod(tempMod, false); foreach (var mod in _modStorage) @@ -157,11 +161,11 @@ public class CollectionCacheManager : IDisposable { case ModPathChangeType.Deleted: case ModPathChangeType.StartingReload: - foreach (var collection in _caches.Keys.Where(c => c[mod.Index].Settings?.Enabled == true)) + foreach (var collection in _storage.Where(c => c.HasCache && c[mod.Index].Settings?.Enabled == true)) collection._cache!.RemoveMod(mod, true); break; case ModPathChangeType.Moved: - foreach (var collection in _caches.Keys.Where(c => c.HasCache && c[mod.Index].Settings?.Enabled == true)) + foreach (var collection in _storage.Where(c => c.HasCache && c[mod.Index].Settings?.Enabled == true)) collection._cache!.ReloadMod(mod, true); break; } @@ -172,13 +176,13 @@ public class CollectionCacheManager : IDisposable if (type is not (ModPathChangeType.Added or ModPathChangeType.Reloaded)) return; - foreach (var collection in _caches.Keys.Where(c => c[mod.Index].Settings?.Enabled == true)) + foreach (var collection in _storage.Where(c => c.HasCache && c[mod.Index].Settings?.Enabled == true)) collection._cache!.AddMod(mod, true); } /// Apply a mod change to all collections with a cache. private void OnGlobalModChange(TemporaryMod mod, bool created, bool removed) - => TempModManager.OnGlobalModChange(_caches.Keys, mod, created, removed); + => TempModManager.OnGlobalModChange(_storage.Where(c => c.HasCache), mod, created, removed); /// Remove a cache from a collection if it is active. private void RemoveCache(ModCollection? collection) @@ -198,7 +202,7 @@ public class CollectionCacheManager : IDisposable { if (type is ModOptionChangeType.PrepareChange) { - foreach (var collection in _caches.Keys.Where(collection => collection[mod.Index].Settings is { Enabled: true })) + foreach (var collection in _storage.Where(collection => collection.HasCache && collection[mod.Index].Settings is { Enabled: true })) collection._cache!.RemoveMod(mod, false); return; @@ -209,7 +213,7 @@ public class CollectionCacheManager : IDisposable if (!recomputeList) return; - foreach (var collection in _caches.Keys.Where(collection => collection[mod.Index].Settings is { Enabled: true })) + foreach (var collection in _storage.Where(collection => collection.HasCache && collection[mod.Index].Settings is { Enabled: true })) { if (reload) collection._cache!.ReloadMod(mod, true); @@ -221,16 +225,17 @@ public class CollectionCacheManager : IDisposable /// Increment the counter to ensure new files are loaded after applying meta changes. private void IncrementCounters() { - foreach (var (collection, _) in _caches) + foreach (var collection in _storage.Where(c => c.HasCache)) ++collection.ChangeCounter; MetaFileManager.CharacterUtility.LoadingFinished -= IncrementCounters; } private void OnModSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx, bool _) { - if (!_caches.TryGetValue(collection, out var cache)) + if (!collection.HasCache) return; + var cache = collection._cache!; switch (type) { case ModSettingChange.Inheritance: @@ -259,7 +264,7 @@ public class CollectionCacheManager : IDisposable break; case ModSettingChange.MultiInheritance: case ModSettingChange.MultiEnableState: - FullRecalculation(collection, cache); + FullRecalculation(collection); break; } } @@ -269,19 +274,17 @@ public class CollectionCacheManager : IDisposable /// just recompute everything. /// private void OnCollectionInheritanceChange(ModCollection collection, bool _) - { - if (_caches.TryGetValue(collection, out var cache)) - FullRecalculation(collection, cache); - } + => FullRecalculation(collection); /// Clear the current cache of a collection. private void ClearCache(ModCollection collection) { - if (!_caches.Remove(collection, out var cache)) + if (!collection.HasCache) return; - cache.Dispose(); + collection._cache!.Dispose(); collection._cache = null; + --Count; Penumbra.Log.Verbose($"Cleared cache of collection {collection.AnonymizedName}."); } diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs index 997ff784..ffd32df8 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/Penumbra.cs @@ -225,8 +225,8 @@ public class Penumbra : IDalamudPlugin foreach (var (name, id, collection) in _collectionManager.Active.Individuals.Assignments) sb.Append($"> **`{id[0].Incognito(name) + ':',-30}`** {collection.AnonymizedName}\n"); - foreach (var (collection, cache) in _collectionManager.Caches.Active) - PrintCollection(collection, cache); + foreach (var collection in _collectionManager.Caches.Active) + PrintCollection(collection, collection._cache!); return sb.ToString(); } diff --git a/Penumbra/UI/ImportPopup.cs b/Penumbra/UI/ImportPopup.cs index 0a5f160e..17a21dc7 100644 --- a/Penumbra/UI/ImportPopup.cs +++ b/Penumbra/UI/ImportPopup.cs @@ -5,6 +5,7 @@ using ImGuiNET; using OtterGui.Raii; using Penumbra.Import.Structs; using Penumbra.Mods.Manager; +using Penumbra.Services; namespace Penumbra.UI; @@ -36,7 +37,7 @@ public sealed class ImportPopup : Window if (!_modImportManager.IsImporting(out var import)) return; - const string importPopup = "##importPopup"; + const string importPopup = "##PenumbraImportPopup"; if (!ImGui.IsPopupOpen(importPopup)) ImGui.OpenPopup(importPopup); diff --git a/Penumbra/UI/Tabs/DebugTab.cs b/Penumbra/UI/Tabs/DebugTab.cs index 20cb1a19..0e821ab8 100644 --- a/Penumbra/UI/Tabs/DebugTab.cs +++ b/Penumbra/UI/Tabs/DebugTab.cs @@ -6,10 +6,8 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Group; using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.System.Resource; -using FFXIVClientStructs.Interop; using ImGuiNET; using OtterGui; -using OtterGui.Raii; using OtterGui.Widgets; using Penumbra.Api; using Penumbra.Collections.Manager; @@ -148,37 +146,36 @@ public class DebugTab : ITab } } - using (var tree = TreeNode("Collections")) + using (var tree = TreeNode($"Collections ({_collectionManager.Caches.Count}/{_collectionManager.Storage.Count - 1})###Collections")) { - if (!tree) - return; - - using var table = Table("##DebugCollectionsTable", 2, ImGuiTableFlags.SizingFixedFit); - if (!table) - return; - - foreach (var collection in _collectionManager.Storage) - PrintValue(collection.Name, collection.HasCache.ToString()); + if (tree) + { + using var table = Table("##DebugCollectionsTable", 2, ImGuiTableFlags.SizingFixedFit); + if (table) + foreach (var collection in _collectionManager.Storage) + PrintValue(collection.Name, collection.HasCache.ToString()); + } } - using (var tree = TreeNode("Mods")) + var issues = _modManager.WithIndex().Count(p => p.Index != p.Value.Index); + using (var tree = TreeNode($"Mods ({issues} Issues)###Mods")) { - if (!tree) - return; - - using var table = Table("##DebugModsTable", 3, ImGuiTableFlags.SizingFixedFit); - if (!table) - return; - - var lastIndex = -1; - foreach (var mod in _modManager) + if (tree) { - PrintValue(mod.Name, mod.Index.ToString("D5")); - ImGui.TableNextColumn(); - var index = mod.Index; - if (index != lastIndex + 1) - ImGui.TextUnformatted("!!!"); - lastIndex = index; + using var table = Table("##DebugModsTable", 3, ImGuiTableFlags.SizingFixedFit); + if (table) + { + var lastIndex = -1; + foreach (var mod in _modManager) + { + PrintValue(mod.Name, mod.Index.ToString("D5")); + ImGui.TableNextColumn(); + var index = mod.Index; + if (index != lastIndex + 1) + ImGui.TextUnformatted("!!!"); + lastIndex = index; + } + } } } }