using OtterGui.Classes; using Penumbra.GameData.Enums; using Penumbra.Mods; using Penumbra.Interop.Structs; using Penumbra.Meta.Files; using Penumbra.Meta.Manipulations; using Penumbra.String.Classes; using Penumbra.Collections.Cache; using Penumbra.Interop.Services; using Penumbra.Mods.Editor; using Penumbra.GameData.Structs; namespace Penumbra.Collections; public partial class ModCollection { // Only active collections need to have a cache. internal CollectionCache? _cache; public bool HasCache => _cache != null; // Handle temporary mods for this collection. public void Apply(TemporaryMod tempMod, bool created) { if (created) _cache?.AddMod(tempMod, tempMod.TotalManipulations > 0); else _cache?.ReloadMod(tempMod, tempMod.TotalManipulations > 0); } public void Remove(TemporaryMod tempMod) { _cache?.RemoveMod(tempMod, tempMod.TotalManipulations > 0); } public IEnumerable ReverseResolvePath(FullPath path) => _cache?.ReverseResolvePath(path) ?? Array.Empty(); public HashSet[] ReverseResolvePaths(IReadOnlyCollection paths) => _cache?.ReverseResolvePaths(paths) ?? paths.Select(_ => new HashSet()).ToArray(); public FullPath? ResolvePath(Utf8GamePath path) => _cache?.ResolvePath(path); // Obtain data from the cache. internal MetaCache? MetaCache => _cache?.Meta; public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out ImcFile? file) { if (_cache != null) return _cache.Meta.GetImcFile(path, out file); file = null; return false; } internal IReadOnlyDictionary ResolvedFiles => _cache?.ResolvedFiles ?? new ConcurrentDictionary(); internal IReadOnlyDictionary, object?)> ChangedItems => _cache?.ChangedItems ?? new Dictionary, object?)>(); internal IEnumerable> AllConflicts => _cache?.AllConflicts ?? Array.Empty>(); internal SingleArray Conflicts(Mod mod) => _cache?.Conflicts(mod) ?? new SingleArray(); public void SetFiles(CharacterUtility utility) { if (_cache == null) { utility.ResetAll(); } else { _cache.Meta.SetFiles(); Penumbra.Log.Debug($"Set CharacterUtility resources for collection {Identifier}."); } } public void SetMetaFile(CharacterUtility utility, MetaIndex idx) { if (_cache == null) utility.ResetResource(idx); else _cache.Meta.SetFile(idx); } // Used for short periods of changed files. public MetaList.MetaReverter? TemporarilySetEqdpFile(CharacterUtility utility, GenderRace genderRace, bool accessory) { if (_cache != null) return _cache?.Meta.TemporarilySetEqdpFile(genderRace, accessory); var idx = CharacterUtilityData.EqdpIdx(genderRace, accessory); return idx >= 0 ? utility.TemporarilyResetResource(idx) : null; } public MetaList.MetaReverter TemporarilySetCmpFile(CharacterUtility utility) => _cache?.Meta.TemporarilySetCmpFile() ?? utility.TemporarilyResetResource(MetaIndex.HumanCmp); public MetaList.MetaReverter TemporarilySetEstFile(CharacterUtility utility, EstType type) => _cache?.Meta.TemporarilySetEstFile(type) ?? utility.TemporarilyResetResource((MetaIndex)type); }