Fix some caching issues.

This commit is contained in:
Ottermandias 2023-05-02 15:40:37 +02:00
parent 94a0864556
commit 9c0406ec9d
7 changed files with 54 additions and 24 deletions

View file

@ -51,6 +51,8 @@ public class CollectionCacheManager : IDisposable
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, -100); _communicator.ModOptionChanged.Subscribe(OnModOptionChange, -100);
_communicator.ModSettingChanged.Subscribe(OnModSettingChange); _communicator.ModSettingChanged.Subscribe(OnModSettingChange);
_communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange); _communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange);
_communicator.ModDiscoveryStarted.Subscribe(OnModDiscoveryStarted);
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished, -100);
if (!MetaFileManager.CharacterUtility.Ready) if (!MetaFileManager.CharacterUtility.Ready)
MetaFileManager.CharacterUtility.LoadingFinished += IncrementCounters; MetaFileManager.CharacterUtility.LoadingFinished += IncrementCounters;
@ -308,4 +310,20 @@ public class CollectionCacheManager : IDisposable
Penumbra.Log.Debug($"Creating {tasks.Length} necessary caches."); Penumbra.Log.Debug($"Creating {tasks.Length} necessary caches.");
Task.WaitAll(tasks); Task.WaitAll(tasks);
} }
private void OnModDiscoveryStarted()
{
foreach (var collection in Active)
{
collection._cache!.ResolvedFiles.Clear();
collection._cache!.Meta.Reset();
collection._cache!._conflicts.Clear();
}
}
private void OnModDiscoveryFinished()
{
var tasks = Active.Select(c => Task.Run(() => CalculateEffectiveFileListInternal(c))).ToArray();
Task.WaitAll(tasks);
}
} }

View file

@ -168,10 +168,10 @@ public class ModCacheManager : IDisposable
=> mod.TotalFileCount = mod.AllSubMods.Sum(s => s.Files.Count); => mod.TotalFileCount = mod.AllSubMods.Sum(s => s.Files.Count);
private static void UpdateSwapCount(Mod mod) private static void UpdateSwapCount(Mod mod)
=> mod.TotalFileCount = mod.AllSubMods.Sum(s => s.FileSwaps.Count); => mod.TotalSwapCount = mod.AllSubMods.Sum(s => s.FileSwaps.Count);
private static void UpdateMetaCount(Mod mod) private static void UpdateMetaCount(Mod mod)
=> mod.TotalFileCount = mod.AllSubMods.Sum(s => s.Manipulations.Count); => mod.TotalManipulations = mod.AllSubMods.Sum(s => s.Manipulations.Count);
private static void UpdateHasOptions(Mod mod) private static void UpdateHasOptions(Mod mod)
=> mod.HasOptions = mod.Groups.Any(o => o.IsOption); => mod.HasOptions = mod.Groups.Any(o => o.IsOption);

View file

@ -29,7 +29,7 @@ public enum ModPathChangeType
StartingReload, StartingReload,
} }
public sealed class ModManager : ModStorage public sealed class ModManager : ModStorage, IDisposable
{ {
private readonly Configuration _config; private readonly Configuration _config;
private readonly CommunicatorService _communicator; private readonly CommunicatorService _communicator;
@ -50,6 +50,7 @@ public sealed class ModManager : ModStorage
OptionEditor = optionEditor; OptionEditor = optionEditor;
Creator = creator; Creator = creator;
SetBaseDirectory(config.ModDirectory, true); SetBaseDirectory(config.ModDirectory, true);
_communicator.ModPathChanged.Subscribe(OnModPathChange);
DiscoverMods(); DiscoverMods();
} }
@ -66,7 +67,7 @@ public sealed class ModManager : ModStorage
public void DiscoverMods() public void DiscoverMods()
{ {
_communicator.ModDiscoveryStarted.Invoke(); _communicator.ModDiscoveryStarted.Invoke();
NewMods.Clear(); ClearNewMods();
Mods.Clear(); Mods.Clear();
BasePath.Refresh(); BasePath.Refresh();
@ -244,10 +245,10 @@ public sealed class ModManager : ModStorage
switch (type) switch (type)
{ {
case ModPathChangeType.Added: case ModPathChangeType.Added:
NewMods.Add(mod); SetNew(mod);
break; break;
case ModPathChangeType.Deleted: case ModPathChangeType.Deleted:
NewMods.Remove(mod); SetKnown(mod);
break; break;
case ModPathChangeType.Moved: case ModPathChangeType.Moved:
if (oldDirectory != null && newDirectory != null) if (oldDirectory != null && newDirectory != null)
@ -258,7 +259,7 @@ public sealed class ModManager : ModStorage
} }
public void Dispose() public void Dispose()
{ } => _communicator.ModPathChanged.Unsubscribe(OnModPathChange);
/// <summary> /// <summary>
/// Set the mod base directory. /// Set the mod base directory.

View file

@ -314,7 +314,7 @@ public class ModOptionEditor
return; return;
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1); _communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1);
subMod.ManipulationData = manipulations; subMod.ManipulationData.SetTo(manipulations);
_saveService.QueueSave(new ModSaveGroup(mod, groupIdx)); _saveService.QueueSave(new ModSaveGroup(mod, groupIdx));
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionMetaChanged, mod, groupIdx, optionIdx, -1); _communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionMetaChanged, mod, groupIdx, optionIdx, -1);
} }
@ -327,7 +327,7 @@ public class ModOptionEditor
return; return;
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1); _communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1);
subMod.FileData = replacements; subMod.FileData.SetTo(replacements);
_saveService.QueueSave(new ModSaveGroup(mod, groupIdx)); _saveService.QueueSave(new ModSaveGroup(mod, groupIdx));
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionFilesChanged, mod, groupIdx, optionIdx, -1); _communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionFilesChanged, mod, groupIdx, optionIdx, -1);
} }
@ -353,7 +353,7 @@ public class ModOptionEditor
return; return;
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1); _communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1);
subMod.FileSwapData = swaps; subMod.FileSwapData.SetTo(swaps);
_saveService.QueueSave(new ModSaveGroup(mod, groupIdx)); _saveService.QueueSave(new ModSaveGroup(mod, groupIdx));
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionSwapsChanged, mod, groupIdx, optionIdx, -1); _communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionSwapsChanged, mod, groupIdx, optionIdx, -1);
} }

View file

@ -53,14 +53,17 @@ public class ModStorage : IReadOnlyList<Mod>
/// Mods are removed when they are deleted or when they are toggled in any collection. /// Mods are removed when they are deleted or when they are toggled in any collection.
/// Also gets cleared on mod rediscovery. /// Also gets cleared on mod rediscovery.
/// </summary> /// </summary>
protected readonly HashSet<Mod> NewMods = new(); private readonly HashSet<Mod> _newMods = new();
public bool IsNew(Mod mod) public bool IsNew(Mod mod)
=> NewMods.Contains(mod); => _newMods.Contains(mod);
public void SetNew(Mod mod) public void SetNew(Mod mod)
=> NewMods.Add(mod); => _newMods.Add(mod);
public void SetKnown(Mod mod) public void SetKnown(Mod mod)
=> NewMods.Remove(mod); => _newMods.Remove(mod);
public void ClearNewMods()
=> _newMods.Clear();
} }

View file

@ -414,7 +414,7 @@ public partial class ModEditWindow : Window, IDisposable
if (ImGuiUtil.DrawDisabledButton("Revert Changes", Vector2.Zero, tt, setsEqual)) if (ImGuiUtil.DrawDisabledButton("Revert Changes", Vector2.Zero, tt, setsEqual))
_editor.SwapEditor.Revert(_editor.Option!); _editor.SwapEditor.Revert(_editor.Option!);
var otherSwaps = _editor.Mod!.TotalSwapCount - _editor.SwapEditor.Swaps.Count; var otherSwaps = _editor.Mod!.TotalSwapCount - _editor.Option!.FileSwaps.Count;
if (otherSwaps > 0) if (otherSwaps > 0)
{ {
ImGui.SameLine(); ImGui.SameLine();

View file

@ -6,7 +6,7 @@ namespace Penumbra.Util;
public static class DictionaryExtensions public static class DictionaryExtensions
{ {
// Returns whether two dictionaries contain equal keys and values. /// <summary> Returns whether two dictionaries contain equal keys and values. </summary>
public static bool SetEquals< TKey, TValue >( this IReadOnlyDictionary< TKey, TValue > lhs, IReadOnlyDictionary< TKey, TValue > rhs ) public static bool SetEquals< TKey, TValue >( this IReadOnlyDictionary< TKey, TValue > lhs, IReadOnlyDictionary< TKey, TValue > rhs )
{ {
if( ReferenceEquals( lhs, rhs ) ) if( ReferenceEquals( lhs, rhs ) )
@ -46,24 +46,32 @@ public static class DictionaryExtensions
return true; return true;
} }
// Set one dictionary to the other, deleting previous entries and ensuring capacity beforehand. /// <summary> Set one dictionary to the other, deleting previous entries and ensuring capacity beforehand. </summary>
public static void SetTo< TKey, TValue >( this Dictionary< TKey, TValue > lhs, IReadOnlyDictionary< TKey, TValue > rhs ) public static void SetTo< TKey, TValue >( this Dictionary< TKey, TValue > lhs, IReadOnlyDictionary< TKey, TValue > rhs )
where TKey : notnull where TKey : notnull
{ {
if( ReferenceEquals( lhs, rhs ) ) if( ReferenceEquals( lhs, rhs ) )
{
return; return;
}
lhs.Clear(); lhs.Clear();
lhs.EnsureCapacity( rhs.Count ); lhs.EnsureCapacity( rhs.Count );
foreach( var (key, value) in rhs ) foreach( var (key, value) in rhs )
{
lhs.Add( key, value ); lhs.Add( key, value );
} }
/// <summary> Set one set to the other, deleting previous entries and ensuring capacity beforehand. </summary>
public static void SetTo<T>(this HashSet<T> lhs, IReadOnlySet<T> rhs)
{
if (ReferenceEquals(lhs, rhs))
return;
lhs.Clear();
lhs.EnsureCapacity(rhs.Count);
foreach (var value in rhs)
lhs.Add(value);
} }
// Add all entries from the other dictionary that would not overwrite current keys. /// <summary> Add all entries from the other dictionary that would not overwrite current keys. </summary>
public static void AddFrom< TKey, TValue >( this Dictionary< TKey, TValue > lhs, IReadOnlyDictionary< TKey, TValue > rhs ) public static void AddFrom< TKey, TValue >( this Dictionary< TKey, TValue > lhs, IReadOnlyDictionary< TKey, TValue > rhs )
where TKey : notnull where TKey : notnull
{ {