mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-26 10:29:20 +01:00
Get rid off all MetaManipulation things.
This commit is contained in:
parent
361082813b
commit
3170edfeb6
63 changed files with 2422 additions and 2847 deletions
|
|
@ -1,3 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Meta.Files;
|
||||
|
|
@ -6,116 +9,132 @@ using Penumbra.String.Classes;
|
|||
|
||||
namespace Penumbra.Collections.Cache;
|
||||
|
||||
public readonly struct ImcCache : IDisposable
|
||||
public sealed class ImcCache(MetaFileManager manager, ModCollection collection) : MetaCacheBase<ImcIdentifier, ImcEntry>(manager, collection)
|
||||
{
|
||||
private readonly Dictionary<Utf8GamePath, ImcFile> _imcFiles = [];
|
||||
private readonly List<(ImcManipulation, ImcFile)> _imcManipulations = [];
|
||||
private readonly Dictionary<Utf8GamePath, (ImcFile, HashSet<ImcIdentifier>)> _imcFiles = [];
|
||||
|
||||
public ImcCache()
|
||||
{ }
|
||||
public override void SetFiles()
|
||||
=> SetFiles(false);
|
||||
|
||||
public void SetFiles(ModCollection collection, bool fromFullCompute)
|
||||
public bool GetFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file)
|
||||
{
|
||||
if (!_imcFiles.TryGetValue(path, out var p))
|
||||
{
|
||||
file = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
file = p.Item1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetFiles(bool fromFullCompute)
|
||||
{
|
||||
if (fromFullCompute)
|
||||
foreach (var path in _imcFiles.Keys)
|
||||
collection._cache!.ForceFileSync(path, PathDataHandler.CreateImc(path.Path, collection));
|
||||
foreach (var (path, _) in _imcFiles)
|
||||
Collection._cache!.ForceFileSync(path, PathDataHandler.CreateImc(path.Path, Collection));
|
||||
else
|
||||
foreach (var path in _imcFiles.Keys)
|
||||
collection._cache!.ForceFile(path, PathDataHandler.CreateImc(path.Path, collection));
|
||||
foreach (var (path, _) in _imcFiles)
|
||||
Collection._cache!.ForceFile(path, PathDataHandler.CreateImc(path.Path, Collection));
|
||||
}
|
||||
|
||||
public void Reset(ModCollection collection)
|
||||
public override void ResetFiles()
|
||||
{
|
||||
foreach (var (path, file) in _imcFiles)
|
||||
foreach (var (path, _) in _imcFiles)
|
||||
Collection._cache!.ForceFile(path, FullPath.Empty);
|
||||
}
|
||||
|
||||
protected override void IncorporateChangesInternal()
|
||||
{
|
||||
if (!Manager.CharacterUtility.Ready)
|
||||
return;
|
||||
|
||||
foreach (var (identifier, (_, entry)) in this)
|
||||
ApplyFile(identifier, entry);
|
||||
|
||||
Penumbra.Log.Verbose($"{Collection.AnonymizedName}: Loaded {Count} delayed IMC manipulations.");
|
||||
}
|
||||
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
foreach (var (path, (file, set)) in _imcFiles)
|
||||
{
|
||||
collection._cache!.RemovePath(path);
|
||||
Collection._cache!.RemovePath(path);
|
||||
file.Reset();
|
||||
set.Clear();
|
||||
}
|
||||
|
||||
_imcManipulations.Clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
public bool ApplyMod(MetaFileManager manager, ModCollection collection, ImcManipulation manip)
|
||||
protected override void ApplyModInternal(ImcIdentifier identifier, ImcEntry entry)
|
||||
{
|
||||
if (!manip.Validate(true))
|
||||
return false;
|
||||
if (Manager.CharacterUtility.Ready)
|
||||
ApplyFile(identifier, entry);
|
||||
}
|
||||
|
||||
var idx = _imcManipulations.FindIndex(p => p.Item1.Equals(manip));
|
||||
if (idx < 0)
|
||||
{
|
||||
idx = _imcManipulations.Count;
|
||||
_imcManipulations.Add((manip, null!));
|
||||
}
|
||||
|
||||
var path = manip.GamePath();
|
||||
private void ApplyFile(ImcIdentifier identifier, ImcEntry entry)
|
||||
{
|
||||
var path = identifier.GamePath();
|
||||
try
|
||||
{
|
||||
if (!_imcFiles.TryGetValue(path, out var file))
|
||||
file = new ImcFile(manager, manip.Identifier);
|
||||
if (!_imcFiles.TryGetValue(path, out var pair))
|
||||
pair = (new ImcFile(Manager, identifier), []);
|
||||
|
||||
_imcManipulations[idx] = (manip, file);
|
||||
if (!manip.Apply(file))
|
||||
return false;
|
||||
|
||||
_imcFiles[path] = file;
|
||||
var fullPath = PathDataHandler.CreateImc(file.Path.Path, collection);
|
||||
collection._cache!.ForceFile(path, fullPath);
|
||||
if (!Apply(pair.Item1, identifier, entry))
|
||||
return;
|
||||
|
||||
return true;
|
||||
pair.Item2.Add(identifier);
|
||||
_imcFiles[path] = pair;
|
||||
var fullPath = PathDataHandler.CreateImc(pair.Item1.Path.Path, Collection);
|
||||
Collection._cache!.ForceFile(path, fullPath);
|
||||
}
|
||||
catch (ImcException e)
|
||||
{
|
||||
manager.ValidityChecker.ImcExceptions.Add(e);
|
||||
Manager.ValidityChecker.ImcExceptions.Add(e);
|
||||
Penumbra.Log.Error(e.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not apply IMC Manipulation {manip}:\n{e}");
|
||||
Penumbra.Log.Error($"Could not apply IMC Manipulation {identifier}:\n{e}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool RevertMod(MetaFileManager manager, ModCollection collection, ImcManipulation m)
|
||||
protected override void RevertModInternal(ImcIdentifier identifier)
|
||||
{
|
||||
if (!m.Validate(false))
|
||||
return false;
|
||||
var path = identifier.GamePath();
|
||||
if (!_imcFiles.TryGetValue(path, out var pair))
|
||||
return;
|
||||
|
||||
var idx = _imcManipulations.FindIndex(p => p.Item1.Equals(m));
|
||||
if (idx < 0)
|
||||
return false;
|
||||
if (!pair.Item2.Remove(identifier))
|
||||
return;
|
||||
|
||||
var (_, file) = _imcManipulations[idx];
|
||||
_imcManipulations.RemoveAt(idx);
|
||||
|
||||
if (_imcManipulations.All(p => !ReferenceEquals(p.Item2, file)))
|
||||
if (pair.Item2.Count == 0)
|
||||
{
|
||||
_imcFiles.Remove(file.Path);
|
||||
collection._cache!.ForceFile(file.Path, FullPath.Empty);
|
||||
file.Dispose();
|
||||
return true;
|
||||
_imcFiles.Remove(path);
|
||||
Collection._cache!.ForceFile(pair.Item1.Path, FullPath.Empty);
|
||||
pair.Item1.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var def = ImcFile.GetDefault(manager, file.Path, m.EquipSlot, m.Variant.Id, out _);
|
||||
var manip = m.Copy(def);
|
||||
if (!manip.Apply(file))
|
||||
return false;
|
||||
var def = ImcFile.GetDefault(Manager, pair.Item1.Path, identifier.EquipSlot, identifier.Variant, out _);
|
||||
if (!Apply(pair.Item1, identifier, def))
|
||||
return;
|
||||
|
||||
var fullPath = PathDataHandler.CreateImc(file.Path.Path, collection);
|
||||
collection._cache!.ForceFile(file.Path, fullPath);
|
||||
|
||||
return true;
|
||||
var fullPath = PathDataHandler.CreateImc(pair.Item1.Path.Path, Collection);
|
||||
Collection._cache!.ForceFile(pair.Item1.Path, fullPath);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public static bool Apply(ImcFile file, ImcIdentifier identifier, ImcEntry entry)
|
||||
=> file.SetEntry(ImcFile.PartIndex(identifier.EquipSlot), identifier.Variant.Id, entry);
|
||||
|
||||
protected override void Dispose(bool _)
|
||||
{
|
||||
foreach (var file in _imcFiles.Values)
|
||||
foreach (var (_, (file, _)) in _imcFiles)
|
||||
file.Dispose();
|
||||
|
||||
Clear();
|
||||
_imcFiles.Clear();
|
||||
_imcManipulations.Clear();
|
||||
}
|
||||
|
||||
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file)
|
||||
=> _imcFiles.TryGetValue(path, out file);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue