mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
meta tmp
This commit is contained in:
parent
9037166d92
commit
0186f176d0
11 changed files with 356 additions and 461 deletions
49
Penumbra/Collections/Cache/CmpCache.cs
Normal file
49
Penumbra/Collections/Cache/CmpCache.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OtterGui.Filesystem;
|
||||||
|
using Penumbra.Interop.Services;
|
||||||
|
using Penumbra.Interop.Structs;
|
||||||
|
using Penumbra.Meta.Files;
|
||||||
|
using Penumbra.Meta.Manipulations;
|
||||||
|
|
||||||
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
|
public struct CmpCache : IDisposable
|
||||||
|
{
|
||||||
|
private CmpFile? _cmpFile = null;
|
||||||
|
private readonly List< RspManipulation > _cmpManipulations = new();
|
||||||
|
|
||||||
|
public CmpCache()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public void SetFiles(CollectionCacheManager manager)
|
||||||
|
=> manager.SetFile( _cmpFile, MetaIndex.HumanCmp );
|
||||||
|
|
||||||
|
public CharacterUtility.MetaList.MetaReverter TemporarilySetFiles(CollectionCacheManager manager)
|
||||||
|
=> manager.TemporarilySetFile( _cmpFile, MetaIndex.HumanCmp );
|
||||||
|
|
||||||
|
public bool ApplyMod( CollectionCacheManager manager, RspManipulation manip )
|
||||||
|
{
|
||||||
|
_cmpManipulations.AddOrReplace( manip );
|
||||||
|
_cmpFile ??= new CmpFile();
|
||||||
|
return manip.Apply( _cmpFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RevertMod( CollectionCacheManager manager, RspManipulation manip )
|
||||||
|
{
|
||||||
|
if (!_cmpManipulations.Remove(manip))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var def = CmpFile.GetDefault( manip.SubRace, manip.Attribute );
|
||||||
|
manip = new RspManipulation( manip.SubRace, manip.Attribute, def );
|
||||||
|
return manip.Apply( _cmpFile! );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_cmpFile?.Dispose();
|
||||||
|
_cmpFile = null;
|
||||||
|
_cmpManipulations.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,12 +20,14 @@ public class CollectionCacheManager : IDisposable
|
||||||
private readonly FrameworkManager _framework;
|
private readonly FrameworkManager _framework;
|
||||||
private readonly ActiveCollections _active;
|
private readonly ActiveCollections _active;
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly CommunicatorService _communicator;
|
||||||
private readonly CharacterUtility _characterUtility;
|
|
||||||
private readonly TempModManager _tempMods;
|
private readonly TempModManager _tempMods;
|
||||||
private readonly ModStorage _modStorage;
|
private readonly ModStorage _modStorage;
|
||||||
private readonly ModCacheManager _modCaches;
|
private readonly ModCacheManager _modCaches;
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly ResidentResourceManager _resources;
|
|
||||||
|
internal readonly ValidityChecker ValidityChecker;
|
||||||
|
internal readonly CharacterUtility CharacterUtility;
|
||||||
|
internal readonly ResidentResourceManager ResidentResources;
|
||||||
|
|
||||||
private readonly Dictionary<ModCollection, CollectionCache> _caches = new();
|
private readonly Dictionary<ModCollection, CollectionCache> _caches = new();
|
||||||
|
|
||||||
|
|
@ -37,17 +39,18 @@ public class CollectionCacheManager : IDisposable
|
||||||
|
|
||||||
public CollectionCacheManager(FrameworkManager framework, ActiveCollections active, CommunicatorService communicator,
|
public CollectionCacheManager(FrameworkManager framework, ActiveCollections active, CommunicatorService communicator,
|
||||||
CharacterUtility characterUtility, TempModManager tempMods, ModStorage modStorage, Configuration config,
|
CharacterUtility characterUtility, TempModManager tempMods, ModStorage modStorage, Configuration config,
|
||||||
ResidentResourceManager resources, ModCacheManager modCaches)
|
ResidentResourceManager residentResources, ModCacheManager modCaches, ValidityChecker validityChecker)
|
||||||
{
|
{
|
||||||
_framework = framework;
|
_framework = framework;
|
||||||
_active = active;
|
_active = active;
|
||||||
_communicator = communicator;
|
_communicator = communicator;
|
||||||
_characterUtility = characterUtility;
|
CharacterUtility = characterUtility;
|
||||||
_tempMods = tempMods;
|
_tempMods = tempMods;
|
||||||
_modStorage = modStorage;
|
_modStorage = modStorage;
|
||||||
_config = config;
|
_config = config;
|
||||||
_resources = resources;
|
ResidentResources = residentResources;
|
||||||
_modCaches = modCaches;
|
_modCaches = modCaches;
|
||||||
|
ValidityChecker = validityChecker;
|
||||||
|
|
||||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||||
_communicator.ModPathChanged.Subscribe(OnModChangeAddition, -100);
|
_communicator.ModPathChanged.Subscribe(OnModChangeAddition, -100);
|
||||||
|
|
@ -58,8 +61,8 @@ public class CollectionCacheManager : IDisposable
|
||||||
_communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange);
|
_communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange);
|
||||||
CreateNecessaryCaches();
|
CreateNecessaryCaches();
|
||||||
|
|
||||||
if (!_characterUtility.Ready)
|
if (!CharacterUtility.Ready)
|
||||||
_characterUtility.LoadingFinished += IncrementCounters;
|
CharacterUtility.LoadingFinished += IncrementCounters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
@ -71,7 +74,7 @@ public class CollectionCacheManager : IDisposable
|
||||||
_communicator.ModOptionChanged.Unsubscribe(OnModOptionChange);
|
_communicator.ModOptionChanged.Unsubscribe(OnModOptionChange);
|
||||||
_communicator.ModSettingChanged.Unsubscribe(OnModSettingChange);
|
_communicator.ModSettingChanged.Unsubscribe(OnModSettingChange);
|
||||||
_communicator.CollectionInheritanceChanged.Unsubscribe(OnCollectionInheritanceChange);
|
_communicator.CollectionInheritanceChanged.Unsubscribe(OnCollectionInheritanceChange);
|
||||||
_characterUtility.LoadingFinished -= IncrementCounters;
|
CharacterUtility.LoadingFinished -= IncrementCounters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Only creates a new cache, does not update an existing one. </summary>
|
/// <summary> Only creates a new cache, does not update an existing one. </summary>
|
||||||
|
|
@ -80,7 +83,7 @@ public class CollectionCacheManager : IDisposable
|
||||||
if (_caches.ContainsKey(collection) || collection.Index == ModCollection.Empty.Index)
|
if (_caches.ContainsKey(collection) || collection.Index == ModCollection.Empty.Index)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var cache = new CollectionCache(collection);
|
var cache = new CollectionCache(this, collection);
|
||||||
_caches.Add(collection, cache);
|
_caches.Add(collection, cache);
|
||||||
collection._cache = cache;
|
collection._cache = cache;
|
||||||
Penumbra.Log.Verbose($"Created new cache for collection {collection.AnonymizedName}.");
|
Penumbra.Log.Verbose($"Created new cache for collection {collection.AnonymizedName}.");
|
||||||
|
|
@ -95,6 +98,9 @@ public class CollectionCacheManager : IDisposable
|
||||||
=> _framework.RegisterImportant(nameof(CalculateEffectiveFileList) + collection.Name,
|
=> _framework.RegisterImportant(nameof(CalculateEffectiveFileList) + collection.Name,
|
||||||
() => CalculateEffectiveFileListInternal(collection));
|
() => CalculateEffectiveFileListInternal(collection));
|
||||||
|
|
||||||
|
public bool IsDefault(ModCollection collection)
|
||||||
|
=> _active.Default == collection;
|
||||||
|
|
||||||
private void CalculateEffectiveFileListInternal(ModCollection collection)
|
private void CalculateEffectiveFileListInternal(ModCollection collection)
|
||||||
{
|
{
|
||||||
// Skip the empty collection.
|
// Skip the empty collection.
|
||||||
|
|
@ -133,10 +139,10 @@ public class CollectionCacheManager : IDisposable
|
||||||
|
|
||||||
++collection.ChangeCounter;
|
++collection.ChangeCounter;
|
||||||
|
|
||||||
if (_active.Default != collection || !_characterUtility.Ready || !_config.EnableMods)
|
if (_active.Default != collection || !CharacterUtility.Ready || !_config.EnableMods)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_resources.Reload();
|
ResidentResources.Reload();
|
||||||
cache.MetaManipulations.SetFiles();
|
cache.MetaManipulations.SetFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,7 +238,7 @@ public class CollectionCacheManager : IDisposable
|
||||||
{
|
{
|
||||||
foreach (var (collection, _) in _caches)
|
foreach (var (collection, _) in _caches)
|
||||||
++collection.ChangeCounter;
|
++collection.ChangeCounter;
|
||||||
_characterUtility.LoadingFinished -= IncrementCounters;
|
CharacterUtility.LoadingFinished -= IncrementCounters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnModSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx, bool _)
|
private void OnModSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx, bool _)
|
||||||
|
|
|
||||||
82
Penumbra/Collections/Cache/EqdpCache.cs
Normal file
82
Penumbra/Collections/Cache/EqdpCache.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OtterGui;
|
||||||
|
using OtterGui.Filesystem;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.Interop.Services;
|
||||||
|
using Penumbra.Interop.Structs;
|
||||||
|
using Penumbra.Meta.Files;
|
||||||
|
using Penumbra.Meta.Manipulations;
|
||||||
|
|
||||||
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
|
public readonly struct EqdpCache : IDisposable
|
||||||
|
{
|
||||||
|
private readonly ExpandedEqdpFile?[] _eqdpFiles = new ExpandedEqdpFile[CharacterUtilityData.EqdpIndices.Length]; // TODO: female Hrothgar
|
||||||
|
private readonly List<EqdpManipulation> _eqdpManipulations = new();
|
||||||
|
|
||||||
|
public EqdpCache()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public void SetFiles(CollectionCacheManager manager)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < CharacterUtilityData.EqdpIndices.Length; ++i)
|
||||||
|
manager.SetFile(_eqdpFiles[i], CharacterUtilityData.EqdpIndices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharacterUtility.MetaList.MetaReverter? TemporarilySetEqdpFile(CollectionCacheManager manager, GenderRace genderRace, bool accessory)
|
||||||
|
{
|
||||||
|
var idx = CharacterUtilityData.EqdpIdx(genderRace, accessory);
|
||||||
|
if ((int)idx == -1)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var i = CharacterUtilityData.EqdpIndices.IndexOf(idx);
|
||||||
|
return i != -1 ? manager.TemporarilySetFile(_eqdpFiles[i], idx) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset(CollectionCacheManager manager)
|
||||||
|
{
|
||||||
|
foreach (var file in _eqdpFiles.OfType<ExpandedEqdpFile>())
|
||||||
|
{
|
||||||
|
var relevant = CharacterUtility.RelevantIndices[file.Index.Value];
|
||||||
|
file.Reset(_eqdpManipulations.Where(m => m.FileIndex() == relevant).Select(m => (int)m.SetId));
|
||||||
|
}
|
||||||
|
|
||||||
|
_eqdpManipulations.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ApplyMod(CollectionCacheManager manager, EqdpManipulation manip)
|
||||||
|
{
|
||||||
|
_eqdpManipulations.AddOrReplace(manip);
|
||||||
|
var file = _eqdpFiles[Array.IndexOf(CharacterUtilityData.EqdpIndices, manip.FileIndex())] ??=
|
||||||
|
new ExpandedEqdpFile(Names.CombinedRace(manip.Gender, manip.Race), manip.Slot.IsAccessory()); // TODO: female Hrothgar
|
||||||
|
return manip.Apply(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RevertMod(CollectionCacheManager manager, EqdpManipulation manip)
|
||||||
|
{
|
||||||
|
if (!_eqdpManipulations.Remove(manip))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var def = ExpandedEqdpFile.GetDefault(Names.CombinedRace(manip.Gender, manip.Race), manip.Slot.IsAccessory(), manip.SetId);
|
||||||
|
var file = _eqdpFiles[Array.IndexOf(CharacterUtilityData.EqdpIndices, manip.FileIndex())]!;
|
||||||
|
manip = new EqdpManipulation(def, manip.Slot, manip.Gender, manip.Race, manip.SetId);
|
||||||
|
return manip.Apply(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExpandedEqdpFile? EqdpFile(GenderRace race, bool accessory)
|
||||||
|
=> _eqdpFiles
|
||||||
|
[Array.IndexOf(CharacterUtilityData.EqdpIndices, CharacterUtilityData.EqdpIdx(race, accessory))]; // TODO: female Hrothgar
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < _eqdpFiles.Length; ++i)
|
||||||
|
{
|
||||||
|
_eqdpFiles[i]?.Dispose();
|
||||||
|
_eqdpFiles[i] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_eqdpManipulations.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
53
Penumbra/Collections/Cache/EqpCache.cs
Normal file
53
Penumbra/Collections/Cache/EqpCache.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OtterGui.Filesystem;
|
||||||
|
using Penumbra.Interop.Services;
|
||||||
|
using Penumbra.Interop.Structs;
|
||||||
|
using Penumbra.Meta.Files;
|
||||||
|
using Penumbra.Meta.Manipulations;
|
||||||
|
|
||||||
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
|
public struct EqpCache : IDisposable
|
||||||
|
{
|
||||||
|
private ExpandedEqpFile? _eqpFile = null;
|
||||||
|
private readonly List< EqpManipulation > _eqpManipulations = new();
|
||||||
|
|
||||||
|
public EqpCache()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public void SetFiles(CollectionCacheManager manager)
|
||||||
|
=> manager.SetFile( _eqpFile, MetaIndex.Eqp );
|
||||||
|
|
||||||
|
public static void ResetFiles(CollectionCacheManager manager)
|
||||||
|
=> manager.SetFile( null, MetaIndex.Eqp );
|
||||||
|
|
||||||
|
public CharacterUtility.MetaList.MetaReverter TemporarilySetFiles(CollectionCacheManager manager)
|
||||||
|
=> manager.TemporarilySetFile( _eqpFile, MetaIndex.Eqp );
|
||||||
|
|
||||||
|
public bool ApplyMod( CollectionCacheManager manager, EqpManipulation manip )
|
||||||
|
{
|
||||||
|
_eqpManipulations.AddOrReplace( manip );
|
||||||
|
_eqpFile ??= new ExpandedEqpFile();
|
||||||
|
return manip.Apply( _eqpFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RevertMod( CollectionCacheManager manager, EqpManipulation manip )
|
||||||
|
{
|
||||||
|
var idx = _eqpManipulations.FindIndex( manip.Equals );
|
||||||
|
if (idx < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var def = ExpandedEqpFile.GetDefault( manip.SetId );
|
||||||
|
manip = new EqpManipulation( def, manip.Slot, manip.SetId );
|
||||||
|
return manip.Apply( _eqpFile! );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_eqpFile?.Dispose();
|
||||||
|
_eqpFile = null;
|
||||||
|
_eqpManipulations.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ using Penumbra.Meta.Manipulations;
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
public partial class MetaCache
|
public struct EstCache : IDisposable
|
||||||
{
|
{
|
||||||
private EstFile? _estFaceFile = null;
|
private EstFile? _estFaceFile = null;
|
||||||
private EstFile? _estHairFile = null;
|
private EstFile? _estHairFile = null;
|
||||||
|
|
@ -18,23 +18,18 @@ public partial class MetaCache
|
||||||
|
|
||||||
private readonly List< EstManipulation > _estManipulations = new();
|
private readonly List< EstManipulation > _estManipulations = new();
|
||||||
|
|
||||||
public void SetEstFiles()
|
public EstCache()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public void SetFiles(CollectionCacheManager manager)
|
||||||
{
|
{
|
||||||
SetFile( _estFaceFile, MetaIndex.FaceEst );
|
manager.SetFile( _estFaceFile, MetaIndex.FaceEst );
|
||||||
SetFile( _estHairFile, MetaIndex.HairEst );
|
manager.SetFile( _estHairFile, MetaIndex.HairEst );
|
||||||
SetFile( _estBodyFile, MetaIndex.BodyEst );
|
manager.SetFile( _estBodyFile, MetaIndex.BodyEst );
|
||||||
SetFile( _estHeadFile, MetaIndex.HeadEst );
|
manager.SetFile( _estHeadFile, MetaIndex.HeadEst );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ResetEstFiles()
|
public CharacterUtility.MetaList.MetaReverter? TemporarilySetFiles(CollectionCacheManager manager, EstManipulation.EstType type)
|
||||||
{
|
|
||||||
SetFile( null, MetaIndex.FaceEst );
|
|
||||||
SetFile( null, MetaIndex.HairEst );
|
|
||||||
SetFile( null, MetaIndex.BodyEst );
|
|
||||||
SetFile( null, MetaIndex.HeadEst );
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharacterUtility.MetaList.MetaReverter? TemporarilySetEstFile(EstManipulation.EstType type)
|
|
||||||
{
|
{
|
||||||
var (file, idx) = type switch
|
var (file, idx) = type switch
|
||||||
{
|
{
|
||||||
|
|
@ -45,10 +40,10 @@ public partial class MetaCache
|
||||||
_ => ( null, 0 ),
|
_ => ( null, 0 ),
|
||||||
};
|
};
|
||||||
|
|
||||||
return idx != 0 ? TemporarilySetFile( file, idx ) : null;
|
return idx != 0 ? manager.TemporarilySetFile( file, idx ) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetEst()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_estFaceFile?.Reset();
|
_estFaceFile?.Reset();
|
||||||
_estHairFile?.Reset();
|
_estHairFile?.Reset();
|
||||||
|
|
@ -57,7 +52,7 @@ public partial class MetaCache
|
||||||
_estManipulations.Clear();
|
_estManipulations.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ApplyMod( EstManipulation m )
|
public bool ApplyMod( CollectionCacheManager manager, EstManipulation m )
|
||||||
{
|
{
|
||||||
_estManipulations.AddOrReplace( m );
|
_estManipulations.AddOrReplace( m );
|
||||||
var file = m.Slot switch
|
var file = m.Slot switch
|
||||||
|
|
@ -71,10 +66,11 @@ public partial class MetaCache
|
||||||
return m.Apply( file );
|
return m.Apply( file );
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RevertMod( EstManipulation m )
|
public bool RevertMod( CollectionCacheManager manager, EstManipulation m )
|
||||||
{
|
|
||||||
if( _estManipulations.Remove( m ) )
|
|
||||||
{
|
{
|
||||||
|
if (!_estManipulations.Remove(m))
|
||||||
|
return false;
|
||||||
|
|
||||||
var def = EstFile.GetDefault( m.Slot, Names.CombinedRace( m.Gender, m.Race ), m.SetId );
|
var def = EstFile.GetDefault( m.Slot, Names.CombinedRace( m.Gender, m.Race ), m.SetId );
|
||||||
var manip = new EstManipulation( m.Gender, m.Race, m.Slot, m.SetId, def );
|
var manip = new EstManipulation( m.Gender, m.Race, m.Slot, m.SetId, def );
|
||||||
var file = m.Slot switch
|
var file = m.Slot switch
|
||||||
|
|
@ -86,12 +82,10 @@ public partial class MetaCache
|
||||||
_ => throw new ArgumentOutOfRangeException(),
|
_ => throw new ArgumentOutOfRangeException(),
|
||||||
};
|
};
|
||||||
return manip.Apply( file );
|
return manip.Apply( file );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
public void Dispose()
|
||||||
}
|
|
||||||
|
|
||||||
public void DisposeEst()
|
|
||||||
{
|
{
|
||||||
_estFaceFile?.Dispose();
|
_estFaceFile?.Dispose();
|
||||||
_estHairFile?.Dispose();
|
_estHairFile?.Dispose();
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
|
|
@ -8,51 +9,47 @@ using Penumbra.Meta.Manipulations;
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
public partial class MetaCache
|
public struct GmpCache : IDisposable
|
||||||
{
|
{
|
||||||
private ExpandedGmpFile? _gmpFile = null;
|
private ExpandedGmpFile? _gmpFile = null;
|
||||||
private readonly List< GmpManipulation > _gmpManipulations = new();
|
private readonly List< GmpManipulation > _gmpManipulations = new();
|
||||||
|
|
||||||
public void SetGmpFiles()
|
public GmpCache()
|
||||||
=> SetFile( _gmpFile, MetaIndex.Gmp );
|
{}
|
||||||
|
|
||||||
public static void ResetGmpFiles()
|
public void SetFiles(CollectionCacheManager manager)
|
||||||
=> SetFile( null, MetaIndex.Gmp );
|
=> manager.SetFile( _gmpFile, MetaIndex.Gmp );
|
||||||
|
|
||||||
public CharacterUtility.MetaList.MetaReverter TemporarilySetGmpFile()
|
public CharacterUtility.MetaList.MetaReverter TemporarilySetFiles(CollectionCacheManager manager)
|
||||||
=> TemporarilySetFile( _gmpFile, MetaIndex.Gmp );
|
=> manager.TemporarilySetFile( _gmpFile, MetaIndex.Gmp );
|
||||||
|
|
||||||
public void ResetGmp()
|
public void ResetGmp(CollectionCacheManager manager)
|
||||||
{
|
{
|
||||||
if( _gmpFile == null )
|
if( _gmpFile == null )
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
_gmpFile.Reset( _gmpManipulations.Select( m => ( int )m.SetId ) );
|
_gmpFile.Reset( _gmpManipulations.Select( m => ( int )m.SetId ) );
|
||||||
_gmpManipulations.Clear();
|
_gmpManipulations.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ApplyMod( GmpManipulation manip )
|
public bool ApplyMod( CollectionCacheManager manager, GmpManipulation manip )
|
||||||
{
|
{
|
||||||
_gmpManipulations.AddOrReplace( manip );
|
_gmpManipulations.AddOrReplace( manip );
|
||||||
_gmpFile ??= new ExpandedGmpFile();
|
_gmpFile ??= new ExpandedGmpFile();
|
||||||
return manip.Apply( _gmpFile );
|
return manip.Apply( _gmpFile );
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RevertMod( GmpManipulation manip )
|
public bool RevertMod( CollectionCacheManager manager, GmpManipulation manip )
|
||||||
{
|
|
||||||
if( _gmpManipulations.Remove( manip ) )
|
|
||||||
{
|
{
|
||||||
|
if (!_gmpManipulations.Remove(manip))
|
||||||
|
return false;
|
||||||
|
|
||||||
var def = ExpandedGmpFile.GetDefault( manip.SetId );
|
var def = ExpandedGmpFile.GetDefault( manip.SetId );
|
||||||
manip = new GmpManipulation( def, manip.SetId );
|
manip = new GmpManipulation( def, manip.SetId );
|
||||||
return manip.Apply( _gmpFile! );
|
return manip.Apply( _gmpFile! );
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
public void Dispose()
|
||||||
}
|
|
||||||
|
|
||||||
public void DisposeGmp()
|
|
||||||
{
|
{
|
||||||
_gmpFile?.Dispose();
|
_gmpFile?.Dispose();
|
||||||
_gmpFile = null;
|
_gmpFile = null;
|
||||||
|
|
@ -8,46 +8,32 @@ using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
public partial class MetaCache
|
public readonly struct ImcCache : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Dictionary< Utf8GamePath, ImcFile > _imcFiles = new();
|
private readonly Dictionary< Utf8GamePath, ImcFile > _imcFiles = new();
|
||||||
private readonly List< ImcManipulation > _imcManipulations = new();
|
private readonly List< ImcManipulation > _imcManipulations = new();
|
||||||
|
|
||||||
public void SetImcFiles()
|
public ImcCache()
|
||||||
{
|
{ }
|
||||||
if( !_collection.HasCache )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void SetFiles(CollectionCacheManager manager, ModCollection collection)
|
||||||
|
{
|
||||||
foreach( var path in _imcFiles.Keys )
|
foreach( var path in _imcFiles.Keys )
|
||||||
{
|
collection._cache!.ForceFile( path, CreateImcPath( collection, path ) );
|
||||||
_collection.ForceFile( path, CreateImcPath( path ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetImc()
|
public void Reset(CollectionCacheManager manager, ModCollection collection)
|
||||||
{
|
|
||||||
if( _collection.HasCache )
|
|
||||||
{
|
{
|
||||||
foreach( var (path, file) in _imcFiles )
|
foreach( var (path, file) in _imcFiles )
|
||||||
{
|
{
|
||||||
_collection.RemoveFile( path );
|
collection._cache!.RemoveFile( path );
|
||||||
file.Reset();
|
file.Reset();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach( var (_, file) in _imcFiles )
|
|
||||||
{
|
|
||||||
file.Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_imcManipulations.Clear();
|
_imcManipulations.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ApplyMod( ImcManipulation manip )
|
public bool ApplyMod( CollectionCacheManager manager, ModCollection collection, ImcManipulation manip )
|
||||||
{
|
{
|
||||||
if( !manip.Valid )
|
if( !manip.Valid )
|
||||||
{
|
{
|
||||||
|
|
@ -69,17 +55,14 @@ public partial class MetaCache
|
||||||
}
|
}
|
||||||
|
|
||||||
_imcFiles[ path ] = file;
|
_imcFiles[ path ] = file;
|
||||||
var fullPath = CreateImcPath( path );
|
var fullPath = CreateImcPath( collection, path );
|
||||||
if( _collection.HasCache )
|
collection._cache!.ForceFile( path, fullPath );
|
||||||
{
|
|
||||||
_collection.ForceFile( path, fullPath );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch( ImcException e )
|
catch( ImcException e )
|
||||||
{
|
{
|
||||||
Penumbra.ValidityChecker.ImcExceptions.Add( e );
|
manager.ValidityChecker.ImcExceptions.Add( e );
|
||||||
Penumbra.Log.Error( e.ToString() );
|
Penumbra.Log.Error( e.ToString() );
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
|
|
@ -90,7 +73,7 @@ public partial class MetaCache
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RevertMod( ImcManipulation m )
|
public bool RevertMod( CollectionCacheManager manager, ModCollection collection, ImcManipulation m )
|
||||||
{
|
{
|
||||||
if( !m.Valid || !_imcManipulations.Remove( m ) )
|
if( !m.Valid || !_imcManipulations.Remove( m ) )
|
||||||
{
|
{
|
||||||
|
|
@ -106,32 +89,25 @@ public partial class MetaCache
|
||||||
var def = ImcFile.GetDefault( path, m.EquipSlot, m.Variant, out _ );
|
var def = ImcFile.GetDefault( path, m.EquipSlot, m.Variant, out _ );
|
||||||
var manip = m.Copy( def );
|
var manip = m.Copy( def );
|
||||||
if( !manip.Apply( file ) )
|
if( !manip.Apply( file ) )
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
var fullPath = CreateImcPath( path );
|
var fullPath = CreateImcPath( collection, path );
|
||||||
if( _collection.HasCache )
|
collection._cache!.ForceFile( path, fullPath );
|
||||||
{
|
|
||||||
_collection.ForceFile( path, fullPath );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisposeImc()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
foreach( var file in _imcFiles.Values )
|
foreach( var file in _imcFiles.Values )
|
||||||
{
|
|
||||||
file.Dispose();
|
file.Dispose();
|
||||||
}
|
|
||||||
|
|
||||||
_imcFiles.Clear();
|
_imcFiles.Clear();
|
||||||
_imcManipulations.Clear();
|
_imcManipulations.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private FullPath CreateImcPath( Utf8GamePath path )
|
private static FullPath CreateImcPath( ModCollection collection, Utf8GamePath path )
|
||||||
=> new($"|{_collection.Name}_{_collection.ChangeCounter}|{path}");
|
=> new($"|{collection.Name}_{collection.ChangeCounter}|{path}");
|
||||||
|
|
||||||
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file)
|
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file)
|
||||||
=> _imcFiles.TryGetValue(path, out file);
|
=> _imcFiles.TryGetValue(path, out file);
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using OtterGui.Filesystem;
|
|
||||||
using Penumbra.Interop.Services;
|
|
||||||
using Penumbra.Interop.Structs;
|
|
||||||
using Penumbra.Meta.Files;
|
|
||||||
using Penumbra.Meta.Manipulations;
|
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
|
||||||
|
|
||||||
public partial class MetaCache
|
|
||||||
{
|
|
||||||
private CmpFile? _cmpFile = null;
|
|
||||||
private readonly List< RspManipulation > _cmpManipulations = new();
|
|
||||||
|
|
||||||
public void SetCmpFiles()
|
|
||||||
=> SetFile( _cmpFile, MetaIndex.HumanCmp );
|
|
||||||
|
|
||||||
public static void ResetCmpFiles()
|
|
||||||
=> SetFile( null, MetaIndex.HumanCmp );
|
|
||||||
|
|
||||||
public CharacterUtility.MetaList.MetaReverter TemporarilySetCmpFile()
|
|
||||||
=> TemporarilySetFile( _cmpFile, MetaIndex.HumanCmp );
|
|
||||||
|
|
||||||
public void ResetCmp()
|
|
||||||
{
|
|
||||||
if( _cmpFile == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cmpFile.Reset( _cmpManipulations.Select( m => ( m.SubRace, m.Attribute ) ) );
|
|
||||||
_cmpManipulations.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ApplyMod( RspManipulation manip )
|
|
||||||
{
|
|
||||||
_cmpManipulations.AddOrReplace( manip );
|
|
||||||
_cmpFile ??= new CmpFile();
|
|
||||||
return manip.Apply( _cmpFile );
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RevertMod( RspManipulation manip )
|
|
||||||
{
|
|
||||||
if( _cmpManipulations.Remove( manip ) )
|
|
||||||
{
|
|
||||||
var def = CmpFile.GetDefault( manip.SubRace, manip.Attribute );
|
|
||||||
manip = new RspManipulation( manip.SubRace, manip.Attribute, def );
|
|
||||||
return manip.Apply( _cmpFile! );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisposeCmp()
|
|
||||||
{
|
|
||||||
_cmpFile?.Dispose();
|
|
||||||
_cmpFile = null;
|
|
||||||
_cmpManipulations.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Filesystem;
|
|
||||||
using Penumbra.GameData.Enums;
|
|
||||||
using Penumbra.Interop.Services;
|
|
||||||
using Penumbra.Interop.Structs;
|
|
||||||
using Penumbra.Meta.Files;
|
|
||||||
using Penumbra.Meta.Manipulations;
|
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
|
||||||
|
|
||||||
public partial class MetaCache
|
|
||||||
{
|
|
||||||
private readonly ExpandedEqdpFile?[] _eqdpFiles = new ExpandedEqdpFile[CharacterUtilityData.EqdpIndices.Length]; // TODO: female Hrothgar
|
|
||||||
|
|
||||||
private readonly List< EqdpManipulation > _eqdpManipulations = new();
|
|
||||||
|
|
||||||
public void SetEqdpFiles()
|
|
||||||
{
|
|
||||||
for( var i = 0; i < CharacterUtilityData.EqdpIndices.Length; ++i )
|
|
||||||
{
|
|
||||||
SetFile( _eqdpFiles[ i ], CharacterUtilityData.EqdpIndices[ i ] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharacterUtility.MetaList.MetaReverter? TemporarilySetEqdpFile( GenderRace genderRace, bool accessory )
|
|
||||||
{
|
|
||||||
var idx = CharacterUtilityData.EqdpIdx( genderRace, accessory );
|
|
||||||
if( ( int )idx != -1 )
|
|
||||||
{
|
|
||||||
var i = CharacterUtilityData.EqdpIndices.IndexOf( idx );
|
|
||||||
if( i != -1 )
|
|
||||||
{
|
|
||||||
return TemporarilySetFile( _eqdpFiles[ i ], idx );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ResetEqdpFiles()
|
|
||||||
{
|
|
||||||
foreach( var idx in CharacterUtilityData.EqdpIndices )
|
|
||||||
{
|
|
||||||
SetFile( null, idx );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetEqdp()
|
|
||||||
{
|
|
||||||
foreach( var file in _eqdpFiles.OfType< ExpandedEqdpFile >() )
|
|
||||||
{
|
|
||||||
var relevant = CharacterUtility.RelevantIndices[ file.Index.Value ];
|
|
||||||
file.Reset( _eqdpManipulations.Where( m => m.FileIndex() == relevant ).Select( m => ( int )m.SetId ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
_eqdpManipulations.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ApplyMod( EqdpManipulation manip )
|
|
||||||
{
|
|
||||||
_eqdpManipulations.AddOrReplace( manip );
|
|
||||||
var file = _eqdpFiles[ Array.IndexOf( CharacterUtilityData.EqdpIndices, manip.FileIndex() ) ] ??=
|
|
||||||
new ExpandedEqdpFile( Names.CombinedRace( manip.Gender, manip.Race ), manip.Slot.IsAccessory() ); // TODO: female Hrothgar
|
|
||||||
return manip.Apply( file );
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RevertMod( EqdpManipulation manip )
|
|
||||||
{
|
|
||||||
if( _eqdpManipulations.Remove( manip ) )
|
|
||||||
{
|
|
||||||
var def = ExpandedEqdpFile.GetDefault( Names.CombinedRace( manip.Gender, manip.Race ), manip.Slot.IsAccessory(), manip.SetId );
|
|
||||||
var file = _eqdpFiles[ Array.IndexOf( CharacterUtilityData.EqdpIndices, manip.FileIndex() ) ]!;
|
|
||||||
manip = new EqdpManipulation( def, manip.Slot, manip.Gender, manip.Race, manip.SetId );
|
|
||||||
return manip.Apply( file );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExpandedEqdpFile? EqdpFile( GenderRace race, bool accessory )
|
|
||||||
=> _eqdpFiles
|
|
||||||
[ Array.IndexOf( CharacterUtilityData.EqdpIndices, CharacterUtilityData.EqdpIdx( race, accessory ) ) ]; // TODO: female Hrothgar
|
|
||||||
|
|
||||||
public void DisposeEqdp()
|
|
||||||
{
|
|
||||||
for( var i = 0; i < _eqdpFiles.Length; ++i )
|
|
||||||
{
|
|
||||||
_eqdpFiles[ i ]?.Dispose();
|
|
||||||
_eqdpFiles[ i ] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_eqdpManipulations.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using OtterGui.Filesystem;
|
|
||||||
using Penumbra.Interop.Services;
|
|
||||||
using Penumbra.Interop.Structs;
|
|
||||||
using Penumbra.Meta.Files;
|
|
||||||
using Penumbra.Meta.Manipulations;
|
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
|
||||||
|
|
||||||
public partial class MetaCache
|
|
||||||
{
|
|
||||||
private ExpandedEqpFile? _eqpFile = null;
|
|
||||||
private readonly List< EqpManipulation > _eqpManipulations = new();
|
|
||||||
|
|
||||||
public void SetEqpFiles()
|
|
||||||
=> SetFile( _eqpFile, MetaIndex.Eqp );
|
|
||||||
|
|
||||||
public static void ResetEqpFiles()
|
|
||||||
=> SetFile( null, MetaIndex.Eqp );
|
|
||||||
|
|
||||||
public CharacterUtility.MetaList.MetaReverter TemporarilySetEqpFile()
|
|
||||||
=> TemporarilySetFile( _eqpFile, MetaIndex.Eqp );
|
|
||||||
|
|
||||||
public void ResetEqp()
|
|
||||||
{
|
|
||||||
if( _eqpFile == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_eqpFile.Reset( _eqpManipulations.Select( m => ( int )m.SetId ) );
|
|
||||||
_eqpManipulations.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ApplyMod( EqpManipulation manip )
|
|
||||||
{
|
|
||||||
_eqpManipulations.AddOrReplace( manip );
|
|
||||||
_eqpFile ??= new ExpandedEqpFile();
|
|
||||||
return manip.Apply( _eqpFile );
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RevertMod( EqpManipulation manip )
|
|
||||||
{
|
|
||||||
var idx = _eqpManipulations.FindIndex( manip.Equals );
|
|
||||||
if( idx >= 0 )
|
|
||||||
{
|
|
||||||
var def = ExpandedEqpFile.GetDefault( manip.SetId );
|
|
||||||
manip = new EqpManipulation( def, manip.Slot, manip.SetId );
|
|
||||||
return manip.Apply( _eqpFile! );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisposeEqp()
|
|
||||||
{
|
|
||||||
_eqpFile?.Dispose();
|
|
||||||
_eqpFile = null;
|
|
||||||
_eqpManipulations.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -12,115 +12,115 @@ using Penumbra.Mods;
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
public partial class MetaCache : IDisposable, IEnumerable< KeyValuePair< MetaManipulation, IMod > >
|
public struct MetaCache : IDisposable, IEnumerable<KeyValuePair<MetaManipulation, IMod>>
|
||||||
{
|
{
|
||||||
private readonly Dictionary< MetaManipulation, IMod > _manipulations = new();
|
private readonly CollectionCacheManager _manager;
|
||||||
private readonly ModCollection _collection;
|
private readonly ModCollection _collection;
|
||||||
|
private readonly Dictionary<MetaManipulation, IMod> _manipulations = new();
|
||||||
|
private EqpCache _eqpCache = new();
|
||||||
|
private readonly EqdpCache _eqdpCache = new();
|
||||||
|
private EstCache _estCache = new();
|
||||||
|
private GmpCache _gmpCache = new();
|
||||||
|
private CmpCache _cmpCache = new();
|
||||||
|
private readonly ImcCache _imcCache;
|
||||||
|
|
||||||
public bool TryGetValue( MetaManipulation manip, [NotNullWhen( true )] out IMod? mod )
|
public bool TryGetValue(MetaManipulation manip, [NotNullWhen(true)] out IMod? mod)
|
||||||
=> _manipulations.TryGetValue( manip, out mod );
|
=> _manipulations.TryGetValue(manip, out mod);
|
||||||
|
|
||||||
public int Count
|
public int Count
|
||||||
=> _manipulations.Count;
|
=> _manipulations.Count;
|
||||||
|
|
||||||
public IReadOnlyCollection< MetaManipulation > Manipulations
|
public IReadOnlyCollection<MetaManipulation> Manipulations
|
||||||
=> _manipulations.Keys;
|
=> _manipulations.Keys;
|
||||||
|
|
||||||
public IEnumerator< KeyValuePair< MetaManipulation, IMod > > GetEnumerator()
|
public IEnumerator<KeyValuePair<MetaManipulation, IMod>> GetEnumerator()
|
||||||
=> _manipulations.GetEnumerator();
|
=> _manipulations.GetEnumerator();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
=> GetEnumerator();
|
=> GetEnumerator();
|
||||||
|
|
||||||
public MetaCache( ModCollection collection )
|
public MetaCache(CollectionCacheManager manager, ModCollection collection)
|
||||||
{
|
{
|
||||||
_collection = collection;
|
_manager = manager;
|
||||||
if( !Penumbra.CharacterUtility.Ready )
|
_imcCache = new ImcCache(collection);
|
||||||
{
|
if (!_manager.CharacterUtility.Ready)
|
||||||
Penumbra.CharacterUtility.LoadingFinished += ApplyStoredManipulations;
|
_manager.CharacterUtility.LoadingFinished += ApplyStoredManipulations;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFiles()
|
public void SetFiles()
|
||||||
{
|
{
|
||||||
SetEqpFiles();
|
_eqpCache.SetFiles(_manager);
|
||||||
SetEqdpFiles();
|
_eqdpCache.SetFiles(_manager);
|
||||||
SetGmpFiles();
|
_estCache.SetFiles(_manager);
|
||||||
SetEstFiles();
|
_gmpCache.SetFiles(_manager);
|
||||||
SetCmpFiles();
|
_cmpCache.SetFiles(_manager);
|
||||||
SetImcFiles();
|
_imcCache.SetFiles(_manager, _collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
ResetEqp();
|
_eqpCache.Reset(_manager);
|
||||||
ResetEqdp();
|
_eqdpCache.Reset(_manager);
|
||||||
ResetGmp();
|
_estCache.Reset(_manager);
|
||||||
ResetEst();
|
_gmpCache.Reset(_manager);
|
||||||
ResetCmp();
|
_cmpCache.Reset(_manager);
|
||||||
ResetImc();
|
_imcCache.Reset(_manager, _collection);
|
||||||
_manipulations.Clear();
|
_manipulations.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
_manager.CharacterUtility.LoadingFinished -= ApplyStoredManipulations;
|
||||||
|
_eqpCache.Dispose();
|
||||||
|
_eqdpCache.Dispose();
|
||||||
|
_estCache.Dispose();
|
||||||
|
_gmpCache.Dispose();
|
||||||
|
_cmpCache.Dispose();
|
||||||
|
_imcCache.Dispose();
|
||||||
_manipulations.Clear();
|
_manipulations.Clear();
|
||||||
Penumbra.CharacterUtility.LoadingFinished -= ApplyStoredManipulations;
|
|
||||||
DisposeEqp();
|
|
||||||
DisposeEqdp();
|
|
||||||
DisposeCmp();
|
|
||||||
DisposeGmp();
|
|
||||||
DisposeEst();
|
|
||||||
DisposeImc();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ApplyMod( MetaManipulation manip, IMod mod )
|
public bool ApplyMod(MetaManipulation manip, IMod mod)
|
||||||
{
|
{
|
||||||
if( _manipulations.ContainsKey( manip ) )
|
if (_manipulations.ContainsKey(manip))
|
||||||
{
|
_manipulations.Remove(manip);
|
||||||
_manipulations.Remove( manip );
|
|
||||||
}
|
|
||||||
|
|
||||||
_manipulations[ manip ] = mod;
|
_manipulations[manip] = mod;
|
||||||
|
|
||||||
if( !Penumbra.CharacterUtility.Ready )
|
if (!_manager.CharacterUtility.Ready)
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// Imc manipulations do not require character utility,
|
// Imc manipulations do not require character utility,
|
||||||
// but they do require the file space to be ready.
|
// but they do require the file space to be ready.
|
||||||
return manip.ManipulationType switch
|
return manip.ManipulationType switch
|
||||||
{
|
{
|
||||||
MetaManipulation.Type.Eqp => ApplyMod( manip.Eqp ),
|
MetaManipulation.Type.Eqp => _eqpCache.ApplyMod(_manager, manip.Eqp),
|
||||||
MetaManipulation.Type.Gmp => ApplyMod( manip.Gmp ),
|
MetaManipulation.Type.Eqdp => _eqdpCache.ApplyMod(_manager, manip.Eqdp),
|
||||||
MetaManipulation.Type.Eqdp => ApplyMod( manip.Eqdp ),
|
MetaManipulation.Type.Est => _estCache.ApplyMod(_manager, manip.Est),
|
||||||
MetaManipulation.Type.Est => ApplyMod( manip.Est ),
|
MetaManipulation.Type.Gmp => _gmpCache.ApplyMod(_manager, manip.Gmp),
|
||||||
MetaManipulation.Type.Rsp => ApplyMod( manip.Rsp ),
|
MetaManipulation.Type.Rsp => _cmpCache.ApplyMod(_manager, manip.Rsp),
|
||||||
MetaManipulation.Type.Imc => ApplyMod( manip.Imc ),
|
MetaManipulation.Type.Imc => _imcCache.ApplyMod(_manager, _collection, manip.Imc),
|
||||||
MetaManipulation.Type.Unknown => false,
|
MetaManipulation.Type.Unknown => false,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RevertMod( MetaManipulation manip )
|
public bool RevertMod(MetaManipulation manip)
|
||||||
{
|
|
||||||
var ret = _manipulations.Remove( manip );
|
|
||||||
if( !Penumbra.CharacterUtility.Ready )
|
|
||||||
{
|
{
|
||||||
|
var ret = _manipulations.Remove(manip);
|
||||||
|
if (!Penumbra.CharacterUtility.Ready)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
// Imc manipulations do not require character utility,
|
// Imc manipulations do not require character utility,
|
||||||
// but they do require the file space to be ready.
|
// but they do require the file space to be ready.
|
||||||
return manip.ManipulationType switch
|
return manip.ManipulationType switch
|
||||||
{
|
{
|
||||||
MetaManipulation.Type.Eqp => RevertMod( (MetaManipulation)manip.Eqp ),
|
MetaManipulation.Type.Eqp => _eqpCache.RevertMod(_manager, manip.Eqp),
|
||||||
MetaManipulation.Type.Gmp => RevertMod( (MetaManipulation)manip.Gmp ),
|
MetaManipulation.Type.Eqdp => _eqdpCache.RevertMod(_manager, manip.Eqdp),
|
||||||
MetaManipulation.Type.Eqdp => RevertMod( (MetaManipulation)manip.Eqdp ),
|
MetaManipulation.Type.Est => _estCache.RevertMod(_manager, manip.Est),
|
||||||
MetaManipulation.Type.Est => RevertMod( (MetaManipulation)manip.Est ),
|
MetaManipulation.Type.Gmp => _gmpCache.RevertMod(_manager, manip.Gmp),
|
||||||
MetaManipulation.Type.Rsp => RevertMod( (MetaManipulation)manip.Rsp ),
|
MetaManipulation.Type.Rsp => _cmpCache.RevertMod(_manager, manip.Rsp),
|
||||||
MetaManipulation.Type.Imc => RevertMod( (MetaManipulation)manip.Imc ),
|
MetaManipulation.Type.Imc => _imcCache.RevertMod(_manager, _collection, manip.Imc),
|
||||||
MetaManipulation.Type.Unknown => false,
|
MetaManipulation.Type.Unknown => false,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
@ -129,22 +129,20 @@ public partial class MetaCache : IDisposable, IEnumerable< KeyValuePair< MetaMan
|
||||||
// Use this when CharacterUtility becomes ready.
|
// Use this when CharacterUtility becomes ready.
|
||||||
private void ApplyStoredManipulations()
|
private void ApplyStoredManipulations()
|
||||||
{
|
{
|
||||||
if( !Penumbra.CharacterUtility.Ready )
|
if (!Penumbra.CharacterUtility.Ready)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var loaded = 0;
|
var loaded = 0;
|
||||||
foreach( var manip in Manipulations )
|
foreach (var manip in Manipulations)
|
||||||
{
|
{
|
||||||
loaded += manip.ManipulationType switch
|
loaded += manip.ManipulationType switch
|
||||||
{
|
{
|
||||||
MetaManipulation.Type.Eqp => ApplyMod( manip.Eqp ),
|
MetaManipulation.Type.Eqp => _eqpCache.ApplyMod(_manager, manip.Eqp),
|
||||||
MetaManipulation.Type.Gmp => ApplyMod( manip.Gmp ),
|
MetaManipulation.Type.Eqdp => _eqdpCache.ApplyMod(_manager, manip.Eqdp),
|
||||||
MetaManipulation.Type.Eqdp => ApplyMod( manip.Eqdp ),
|
MetaManipulation.Type.Est => _estCache.ApplyMod(_manager, manip.Est),
|
||||||
MetaManipulation.Type.Est => ApplyMod( manip.Est ),
|
MetaManipulation.Type.Gmp => _gmpCache.ApplyMod(_manager, manip.Gmp),
|
||||||
MetaManipulation.Type.Rsp => ApplyMod( manip.Rsp ),
|
MetaManipulation.Type.Rsp => _cmpCache.ApplyMod(_manager, manip.Rsp),
|
||||||
MetaManipulation.Type.Imc => ApplyMod( manip.Imc ),
|
MetaManipulation.Type.Imc => _imcCache.ApplyMod(_manager, _collection, manip.Imc),
|
||||||
MetaManipulation.Type.Unknown => false,
|
MetaManipulation.Type.Unknown => false,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
@ -152,68 +150,28 @@ public partial class MetaCache : IDisposable, IEnumerable< KeyValuePair< MetaMan
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Penumbra.CollectionManager.Active.Default == _collection )
|
if (_manager.IsDefault(_collection))
|
||||||
{
|
{
|
||||||
SetFiles();
|
SetFiles();
|
||||||
Penumbra.ResidentResources.Reload();
|
_manager.ResidentResources.Reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
Penumbra.CharacterUtility.LoadingFinished -= ApplyStoredManipulations;
|
_manager.CharacterUtility.LoadingFinished -= ApplyStoredManipulations;
|
||||||
Penumbra.Log.Debug( $"{_collection.AnonymizedName}: Loaded {loaded} delayed meta manipulations." );
|
Penumbra.Log.Debug($"{_collection.AnonymizedName}: Loaded {loaded} delayed meta manipulations.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFile( MetaIndex metaIndex )
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
|
public unsafe void SetFile(MetaBaseFile? file, MetaIndex metaIndex)
|
||||||
{
|
{
|
||||||
switch( metaIndex )
|
if (file == null)
|
||||||
{
|
_manager.CharacterUtility.ResetResource(metaIndex);
|
||||||
case MetaIndex.Eqp:
|
|
||||||
SetFile( _eqpFile, metaIndex );
|
|
||||||
break;
|
|
||||||
case MetaIndex.Gmp:
|
|
||||||
SetFile( _gmpFile, metaIndex );
|
|
||||||
break;
|
|
||||||
case MetaIndex.HumanCmp:
|
|
||||||
SetFile( _cmpFile, metaIndex );
|
|
||||||
break;
|
|
||||||
case MetaIndex.FaceEst:
|
|
||||||
SetFile( _estFaceFile, metaIndex );
|
|
||||||
break;
|
|
||||||
case MetaIndex.HairEst:
|
|
||||||
SetFile( _estHairFile, metaIndex );
|
|
||||||
break;
|
|
||||||
case MetaIndex.HeadEst:
|
|
||||||
SetFile( _estHeadFile, metaIndex );
|
|
||||||
break;
|
|
||||||
case MetaIndex.BodyEst:
|
|
||||||
SetFile( _estBodyFile, metaIndex );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
var i = CharacterUtilityData.EqdpIndices.IndexOf( metaIndex );
|
|
||||||
if( i != -1 )
|
|
||||||
{
|
|
||||||
SetFile( _eqdpFiles[ i ], metaIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
|
|
||||||
private static unsafe void SetFile( MetaBaseFile? file, MetaIndex metaIndex )
|
|
||||||
{
|
|
||||||
if( file == null )
|
|
||||||
{
|
|
||||||
Penumbra.CharacterUtility.ResetResource( metaIndex );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
_manager.CharacterUtility.SetResource(metaIndex, (IntPtr)file.Data, file.Length);
|
||||||
Penumbra.CharacterUtility.SetResource( metaIndex, ( IntPtr )file.Data, file.Length );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
private static unsafe CharacterUtility.MetaList.MetaReverter TemporarilySetFile( MetaBaseFile? file, MetaIndex metaIndex )
|
public unsafe CharacterUtility.MetaList.MetaReverter TemporarilySetFile(MetaBaseFile? file, MetaIndex metaIndex)
|
||||||
=> file == null
|
=> file == null
|
||||||
? Penumbra.CharacterUtility.TemporarilyResetResource( metaIndex )
|
? _manager.CharacterUtility.TemporarilyResetResource(metaIndex)
|
||||||
: Penumbra.CharacterUtility.TemporarilySetResource( metaIndex, ( IntPtr )file.Data, file.Length );
|
: _manager.CharacterUtility.TemporarilySetResource(metaIndex, (IntPtr)file.Data, file.Length);
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue