Change imc handling in caches slightly.

This commit is contained in:
Ottermandias 2023-06-13 16:01:38 +02:00
parent 03cb88be10
commit 636f14a06d
4 changed files with 62 additions and 54 deletions

View file

@ -165,7 +165,7 @@ public class CollectionCache : IDisposable
var (paths, manipulations) = ModData.RemoveMod(mod);
if (addMetaChanges)
++_collection.ChangeCounter;
_collection.IncrementCounter();
foreach (var path in paths)
{
@ -240,7 +240,7 @@ public class CollectionCache : IDisposable
if (addMetaChanges)
{
++_collection.ChangeCounter;
_collection.IncrementCounter();
if (mod.TotalManipulations > 0)
AddMetaFiles(false);

View file

@ -174,7 +174,7 @@ public class CollectionCacheManager : IDisposable
cache.AddMetaFiles(true);
++collection.ChangeCounter;
collection.IncrementCounter();
MetaFileManager.ApplyDefaultFiles(collection);
}
@ -280,7 +280,7 @@ public class CollectionCacheManager : IDisposable
private void IncrementCounters()
{
foreach (var collection in _storage.Where(c => c.HasCache))
++collection.ChangeCounter;
collection.IncrementCounter();
MetaFileManager.CharacterUtility.LoadingFinished -= IncrementCounters;
}

View file

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using OtterGui.Filesystem;
using System.Linq;
using Penumbra.Meta;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
@ -12,7 +12,7 @@ namespace Penumbra.Collections.Cache;
public readonly struct ImcCache : IDisposable
{
private readonly Dictionary<Utf8GamePath, ImcFile> _imcFiles = new();
private readonly List< ImcManipulation > _imcManipulations = new();
private readonly List<(ImcManipulation, ImcFile)> _imcManipulations = new();
public ImcCache()
{ }
@ -20,16 +20,12 @@ public readonly struct ImcCache : IDisposable
public void SetFiles(ModCollection collection, bool fromFullCompute)
{
if (fromFullCompute)
{
foreach (var path in _imcFiles.Keys)
collection._cache!.ForceFileSync(path, CreateImcPath(collection, path));
}
else
{
foreach (var path in _imcFiles.Keys)
collection._cache!.ForceFile(path, CreateImcPath(collection, path));
}
}
public void Reset(ModCollection collection)
{
@ -45,23 +41,24 @@ public readonly struct ImcCache : IDisposable
public bool ApplyMod(MetaFileManager manager, ModCollection collection, ImcManipulation manip)
{
if (!manip.Validate())
{
return false;
var idx = _imcManipulations.FindIndex(p => p.Item1.Equals(manip));
if (idx < 0)
{
idx = _imcManipulations.Count;
_imcManipulations.Add((manip, null!));
}
_imcManipulations.AddOrReplace( manip );
var path = manip.GamePath();
try
{
if (!_imcFiles.TryGetValue(path, out var file))
{
file = new ImcFile(manager, manip);
}
_imcManipulations[idx] = (manip, file);
if (!manip.Apply(file))
{
return false;
}
_imcFiles[path] = file;
var fullPath = CreateImcPath(collection, path);
@ -84,24 +81,31 @@ public readonly struct ImcCache : IDisposable
public bool RevertMod(MetaFileManager manager, ModCollection collection, ImcManipulation m)
{
if( !m.Validate() || !_imcManipulations.Remove( m ) )
{
if (!m.Validate())
return false;
var idx = _imcManipulations.FindIndex(p => p.Item1.Equals(m));
if (idx < 0)
return false;
var (_, file) = _imcManipulations[idx];
_imcManipulations.RemoveAt(idx);
if (_imcManipulations.All(p => !ReferenceEquals(p.Item2, file)))
{
_imcFiles.Remove(file.Path);
collection._cache!.ForceFile(file.Path, FullPath.Empty);
file.Dispose();
return true;
}
var path = m.GamePath();
if( !_imcFiles.TryGetValue( path, out var file ) )
{
return false;
}
var def = ImcFile.GetDefault( manager, path, m.EquipSlot, m.Variant, out _ );
var def = ImcFile.GetDefault(manager, file.Path, m.EquipSlot, m.Variant, out _);
var manip = m.Copy(def);
if (!manip.Apply(file))
return false;
var fullPath = CreateImcPath( collection, path );
collection._cache!.ForceFile( path, fullPath );
var fullPath = CreateImcPath(collection, file.Path);
collection._cache!.ForceFile(file.Path, fullPath);
return true;
}

View file

@ -47,7 +47,11 @@ public partial class ModCollection
/// Count the number of changes of the effective file list.
/// This is used for material and imc changes.
/// </summary>
public int ChangeCounter { get; internal set; }
public int ChangeCounter { get; private set; }
/// <summary> Increment the number of changes in the effective file list. </summary>
public int IncrementCounter()
=> ++ChangeCounter;
/// <summary>
/// If a ModSetting is null, it can be inherited from other collections.