mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
123 lines
No EOL
3.3 KiB
C#
123 lines
No EOL
3.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using OtterGui.Filesystem;
|
|
using Penumbra.Meta;
|
|
using Penumbra.Meta.Files;
|
|
using Penumbra.Meta.Manipulations;
|
|
using Penumbra.String.Classes;
|
|
|
|
namespace Penumbra.Collections.Cache;
|
|
|
|
public readonly struct ImcCache : IDisposable
|
|
{
|
|
private readonly Dictionary< Utf8GamePath, ImcFile > _imcFiles = new();
|
|
private readonly List< ImcManipulation > _imcManipulations = new();
|
|
|
|
public ImcCache()
|
|
{ }
|
|
|
|
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)
|
|
{
|
|
foreach( var (path, file) in _imcFiles )
|
|
{
|
|
collection._cache!.RemovePath( path );
|
|
file.Reset();
|
|
}
|
|
|
|
_imcManipulations.Clear();
|
|
}
|
|
|
|
public bool ApplyMod( MetaFileManager manager, ModCollection collection, ImcManipulation manip )
|
|
{
|
|
if( !manip.Validate() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_imcManipulations.AddOrReplace( manip );
|
|
var path = manip.GamePath();
|
|
try
|
|
{
|
|
if( !_imcFiles.TryGetValue( path, out var file ) )
|
|
{
|
|
file = new ImcFile( manager, manip );
|
|
}
|
|
|
|
if( !manip.Apply( file ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_imcFiles[ path ] = file;
|
|
var fullPath = CreateImcPath( collection, path );
|
|
collection._cache!.ForceFile( path, fullPath );
|
|
|
|
return true;
|
|
}
|
|
catch( ImcException 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}" );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool RevertMod( MetaFileManager manager, ModCollection collection, ImcManipulation m )
|
|
{
|
|
if( !m.Validate() || !_imcManipulations.Remove( m ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
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 manip = m.Copy( def );
|
|
if( !manip.Apply( file ) )
|
|
return false;
|
|
|
|
var fullPath = CreateImcPath( collection, path );
|
|
collection._cache!.ForceFile( path, fullPath );
|
|
|
|
return true;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
foreach( var file in _imcFiles.Values )
|
|
file.Dispose();
|
|
|
|
_imcFiles.Clear();
|
|
_imcManipulations.Clear();
|
|
}
|
|
|
|
private static FullPath CreateImcPath( ModCollection collection, Utf8GamePath path )
|
|
=> new($"|{collection.Name}_{collection.ChangeCounter}|{path}");
|
|
|
|
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file)
|
|
=> _imcFiles.TryGetValue(path, out file);
|
|
} |