Skip to content

Commit 636f14a

Browse files
committed
Change imc handling in caches slightly.
1 parent 03cb88b commit 636f14a

File tree

4 files changed

+60
-52
lines changed

4 files changed

+60
-52
lines changed

Penumbra/Collections/Cache/CollectionCache.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ internal void RemoveModSync(IMod mod, bool addMetaChanges)
165165
var (paths, manipulations) = ModData.RemoveMod(mod);
166166

167167
if (addMetaChanges)
168-
++_collection.ChangeCounter;
168+
_collection.IncrementCounter();
169169

170170
foreach (var path in paths)
171171
{
@@ -240,7 +240,7 @@ internal void AddModSync(IMod mod, bool addMetaChanges)
240240

241241
if (addMetaChanges)
242242
{
243-
++_collection.ChangeCounter;
243+
_collection.IncrementCounter();
244244
if (mod.TotalManipulations > 0)
245245
AddMetaFiles(false);
246246

Penumbra/Collections/Cache/CollectionCacheManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private void FullRecalculation(ModCollection collection)
174174

175175
cache.AddMetaFiles(true);
176176

177-
++collection.ChangeCounter;
177+
collection.IncrementCounter();
178178

179179
MetaFileManager.ApplyDefaultFiles(collection);
180180
}
@@ -280,7 +280,7 @@ private void OnModOptionChange(ModOptionChangeType type, Mod mod, int groupIdx,
280280
private void IncrementCounters()
281281
{
282282
foreach (var collection in _storage.Where(c => c.HasCache))
283-
++collection.ChangeCounter;
283+
collection.IncrementCounter();
284284
MetaFileManager.CharacterUtility.LoadingFinished -= IncrementCounters;
285285
}
286286

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics.CodeAnalysis;
4-
using OtterGui.Filesystem;
4+
using System.Linq;
55
using Penumbra.Meta;
66
using Penumbra.Meta.Files;
77
using Penumbra.Meta.Manipulations;
@@ -11,113 +11,117 @@ namespace Penumbra.Collections.Cache;
1111

1212
public readonly struct ImcCache : IDisposable
1313
{
14-
private readonly Dictionary< Utf8GamePath, ImcFile > _imcFiles = new();
15-
private readonly List< ImcManipulation > _imcManipulations = new();
14+
private readonly Dictionary<Utf8GamePath, ImcFile> _imcFiles = new();
15+
private readonly List<(ImcManipulation, ImcFile)> _imcManipulations = new();
1616

1717
public ImcCache()
18-
{ }
18+
{ }
1919

2020
public void SetFiles(ModCollection collection, bool fromFullCompute)
2121
{
2222
if (fromFullCompute)
23-
{
2423
foreach (var path in _imcFiles.Keys)
2524
collection._cache!.ForceFileSync(path, CreateImcPath(collection, path));
26-
}
2725
else
28-
{
2926
foreach (var path in _imcFiles.Keys)
3027
collection._cache!.ForceFile(path, CreateImcPath(collection, path));
31-
}
3228
}
3329

3430
public void Reset(ModCollection collection)
3531
{
36-
foreach( var (path, file) in _imcFiles )
32+
foreach (var (path, file) in _imcFiles)
3733
{
38-
collection._cache!.RemovePath( path );
34+
collection._cache!.RemovePath(path);
3935
file.Reset();
4036
}
4137

4238
_imcManipulations.Clear();
4339
}
4440

45-
public bool ApplyMod( MetaFileManager manager, ModCollection collection, ImcManipulation manip )
41+
public bool ApplyMod(MetaFileManager manager, ModCollection collection, ImcManipulation manip)
4642
{
47-
if( !manip.Validate() )
48-
{
43+
if (!manip.Validate())
4944
return false;
50-
}
5145

52-
_imcManipulations.AddOrReplace( manip );
46+
var idx = _imcManipulations.FindIndex(p => p.Item1.Equals(manip));
47+
if (idx < 0)
48+
{
49+
idx = _imcManipulations.Count;
50+
_imcManipulations.Add((manip, null!));
51+
}
52+
5353
var path = manip.GamePath();
5454
try
5555
{
56-
if( !_imcFiles.TryGetValue( path, out var file ) )
57-
{
58-
file = new ImcFile( manager, manip );
59-
}
56+
if (!_imcFiles.TryGetValue(path, out var file))
57+
file = new ImcFile(manager, manip);
6058

61-
if( !manip.Apply( file ) )
62-
{
59+
_imcManipulations[idx] = (manip, file);
60+
if (!manip.Apply(file))
6361
return false;
64-
}
6562

66-
_imcFiles[ path ] = file;
67-
var fullPath = CreateImcPath( collection, path );
68-
collection._cache!.ForceFile( path, fullPath );
63+
_imcFiles[path] = file;
64+
var fullPath = CreateImcPath(collection, path);
65+
collection._cache!.ForceFile(path, fullPath);
6966

7067
return true;
7168
}
72-
catch( ImcException e )
69+
catch (ImcException e)
7370
{
74-
manager.ValidityChecker.ImcExceptions.Add( e );
75-
Penumbra.Log.Error( e.ToString() );
71+
manager.ValidityChecker.ImcExceptions.Add(e);
72+
Penumbra.Log.Error(e.ToString());
7673
}
77-
catch( Exception e )
74+
catch (Exception e)
7875
{
79-
Penumbra.Log.Error( $"Could not apply IMC Manipulation {manip}:\n{e}" );
76+
Penumbra.Log.Error($"Could not apply IMC Manipulation {manip}:\n{e}");
8077
}
8178

8279
return false;
8380
}
8481

85-
public bool RevertMod( MetaFileManager manager, ModCollection collection, ImcManipulation m )
82+
public bool RevertMod(MetaFileManager manager, ModCollection collection, ImcManipulation m)
8683
{
87-
if( !m.Validate() || !_imcManipulations.Remove( m ) )
88-
{
84+
if (!m.Validate())
85+
return false;
86+
87+
var idx = _imcManipulations.FindIndex(p => p.Item1.Equals(m));
88+
if (idx < 0)
8989
return false;
90-
}
9190

92-
var path = m.GamePath();
93-
if( !_imcFiles.TryGetValue( path, out var file ) )
94-
{
95-
return false;
96-
}
91+
var (_, file) = _imcManipulations[idx];
92+
_imcManipulations.RemoveAt(idx);
9793

98-
var def = ImcFile.GetDefault( manager, path, m.EquipSlot, m.Variant, out _ );
99-
var manip = m.Copy( def );
100-
if( !manip.Apply( file ) )
94+
if (_imcManipulations.All(p => !ReferenceEquals(p.Item2, file)))
95+
{
96+
_imcFiles.Remove(file.Path);
97+
collection._cache!.ForceFile(file.Path, FullPath.Empty);
98+
file.Dispose();
99+
return true;
100+
}
101+
102+
var def = ImcFile.GetDefault(manager, file.Path, m.EquipSlot, m.Variant, out _);
103+
var manip = m.Copy(def);
104+
if (!manip.Apply(file))
101105
return false;
102106

103-
var fullPath = CreateImcPath( collection, path );
104-
collection._cache!.ForceFile( path, fullPath );
107+
var fullPath = CreateImcPath(collection, file.Path);
108+
collection._cache!.ForceFile(file.Path, fullPath);
105109

106110
return true;
107111
}
108112

109113
public void Dispose()
110114
{
111-
foreach( var file in _imcFiles.Values )
115+
foreach (var file in _imcFiles.Values)
112116
file.Dispose();
113117

114118
_imcFiles.Clear();
115119
_imcManipulations.Clear();
116120
}
117121

118-
private static FullPath CreateImcPath( ModCollection collection, Utf8GamePath path )
122+
private static FullPath CreateImcPath(ModCollection collection, Utf8GamePath path)
119123
=> new($"|{collection.Name}_{collection.ChangeCounter}|{path}");
120124

121125
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file)
122126
=> _imcFiles.TryGetValue(path, out file);
123-
}
127+
}

Penumbra/Collections/ModCollection.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ public string AnonymizedName
4747
/// Count the number of changes of the effective file list.
4848
/// This is used for material and imc changes.
4949
/// </summary>
50-
public int ChangeCounter { get; internal set; }
50+
public int ChangeCounter { get; private set; }
51+
52+
/// <summary> Increment the number of changes in the effective file list. </summary>
53+
public int IncrementCounter()
54+
=> ++ChangeCounter;
5155

5256
/// <summary>
5357
/// If a ModSetting is null, it can be inherited from other collections.

0 commit comments

Comments
 (0)