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