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.ModSettingChanged.Subscribe(OnModSettingChange);
_communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange);
_communicator.ModDiscoveryStarted.Subscribe(OnModDiscoveryStarted);
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished, -100);
if (!MetaFileManager.CharacterUtility.Ready)
MetaFileManager.CharacterUtility.LoadingFinished += IncrementCounters;
@ -308,4 +310,20 @@ public class CollectionCacheManager : IDisposable
Penumbra.Log.Debug($"Creating {tasks.Length} necessary caches.");
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);
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)
=> mod.TotalFileCount = mod.AllSubMods.Sum(s => s.Manipulations.Count);
=> mod.TotalManipulations = mod.AllSubMods.Sum(s => s.Manipulations.Count);
private static void UpdateHasOptions(Mod mod)
=> mod.HasOptions = mod.Groups.Any(o => o.IsOption);

View file

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

View file

@ -314,7 +314,7 @@ public class ModOptionEditor
return;
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1);
subMod.ManipulationData = manipulations;
subMod.ManipulationData.SetTo(manipulations);
_saveService.QueueSave(new ModSaveGroup(mod, groupIdx));
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionMetaChanged, mod, groupIdx, optionIdx, -1);
}
@ -327,7 +327,7 @@ public class ModOptionEditor
return;
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1);
subMod.FileData = replacements;
subMod.FileData.SetTo(replacements);
_saveService.QueueSave(new ModSaveGroup(mod, groupIdx));
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionFilesChanged, mod, groupIdx, optionIdx, -1);
}
@ -353,7 +353,7 @@ public class ModOptionEditor
return;
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, groupIdx, optionIdx, -1);
subMod.FileSwapData = swaps;
subMod.FileSwapData.SetTo(swaps);
_saveService.QueueSave(new ModSaveGroup(mod, groupIdx));
_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.
/// Also gets cleared on mod rediscovery.
/// </summary>
protected readonly HashSet<Mod> NewMods = new();
private readonly HashSet<Mod> _newMods = new();
public bool IsNew(Mod mod)
=> NewMods.Contains(mod);
=> _newMods.Contains(mod);
public void SetNew(Mod mod)
=> NewMods.Add(mod);
=> _newMods.Add(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))
_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)
{
ImGui.SameLine();

View file

@ -6,7 +6,7 @@ namespace Penumbra.Util;
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 )
{
if( ReferenceEquals( lhs, rhs ) )
@ -46,24 +46,32 @@ public static class DictionaryExtensions
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 )
where TKey : notnull
{
if( ReferenceEquals( lhs, rhs ) )
{
return;
}
lhs.Clear();
lhs.EnsureCapacity( rhs.Count );
foreach( var (key, value) in rhs )
{
lhs.Add( key, value );
}
}
// Add all entries from the other dictionary that would not overwrite current keys.
/// <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);
}
/// <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 )
where TKey : notnull
{