Remove cached data from mod and use ModCaches where required.

This commit is contained in:
Ottermandias 2023-03-31 01:27:47 +02:00
parent 2ffbd7beba
commit e79b110429
14 changed files with 44 additions and 155 deletions

View file

@ -321,7 +321,7 @@ internal class ModCollectionCache : IDisposable
if( addMetaChanges )
{
++_collection.ChangeCounter;
if( mod.TotalManipulations > 0 )
if(Penumbra.ModCaches[mod.Index].TotalManipulations > 0 )
{
AddMetaFiles();
}
@ -533,7 +533,7 @@ internal class ModCollectionCache : IDisposable
foreach( var (manip, mod) in MetaManipulations )
{
Mod.ComputeChangedItems( items, manip );
ModCacheManager.ComputeChangedItems(identifier, items, manip );
AddItems( mod );
}
}

View file

@ -10,8 +10,6 @@ public interface IMod
public int Index { get; }
public int Priority { get; }
public int TotalManipulations { get; }
public ISubMod Default { get; }
public IReadOnlyList< IModGroup > Groups { get; }

View file

@ -12,6 +12,7 @@ namespace Penumbra.Mods;
public class ModNormalizer
{
private readonly ModManager _modManager;
private readonly ModCacheManager _modCacheManager;
private readonly List<List<Dictionary<Utf8GamePath, FullPath>>> _redirections = new();
public Mod Mod { get; private set; } = null!;
@ -24,8 +25,11 @@ public class ModNormalizer
public bool Running
=> Step < TotalSteps;
public ModNormalizer(ModManager modManager)
=> _modManager = modManager;
public ModNormalizer(ModManager modManager, ModCacheManager modCacheManager)
{
_modManager = modManager;
_modCacheManager = modCacheManager;
}
public void Normalize(Mod mod)
{
@ -36,7 +40,7 @@ public class ModNormalizer
_normalizationDirName = Path.Combine(Mod.ModPath.FullName, "TmpNormalization");
_oldDirName = Path.Combine(Mod.ModPath.FullName, "TmpNormalizationOld");
Step = 0;
TotalSteps = mod.TotalFileCount + 5;
TotalSteps = _modCacheManager[mod].TotalFileCount + 5;
Task.Run(NormalizeSync);
}

View file

@ -32,7 +32,6 @@ public class ModOptionEditor
mod._groups[groupIdx] = group.Convert(type);
_saveService.QueueSave(new ModSaveGroup(mod, groupIdx));
mod.HasOptions = mod.Groups.Any(o => o.IsOption);
_communicator.ModOptionChanged.Invoke(ModOptionChangeType.GroupTypeChanged, mod, groupIdx, -1, -1);
}

View file

@ -76,8 +76,6 @@ public partial class Mod
IncorporateAllMetaChanges(true);
}
ComputeChangedItems();
SetCounts();
return true;
}

View file

@ -1,91 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Penumbra.GameData.Data;
using Penumbra.GameData.Enums;
using Penumbra.Meta.Manipulations;
namespace Penumbra.Mods;
public sealed partial class Mod
{
public SortedList< string, object? > ChangedItems { get; } = new();
public string LowerChangedItemsString { get; private set; } = string.Empty;
internal void ComputeChangedItems()
{
ChangedItems.Clear();
foreach( var gamePath in AllRedirects )
{
Penumbra.Identifier.Identify( ChangedItems, gamePath.ToString() );
}
foreach( var manip in AllManipulations )
{
ComputeChangedItems( ChangedItems, manip );
}
LowerChangedItemsString = string.Join( "\0", ChangedItems.Keys.Select( k => k.ToLowerInvariant() ) );
}
public static void ComputeChangedItems( SortedList< string, object? > changedItems, MetaManipulation manip )
{
switch( manip.ManipulationType )
{
case MetaManipulation.Type.Imc:
switch( manip.Imc.ObjectType )
{
case ObjectType.Equipment:
case ObjectType.Accessory:
Penumbra.Identifier.Identify( changedItems,
GamePaths.Equipment.Mtrl.Path( manip.Imc.PrimaryId, GenderRace.MidlanderMale, manip.Imc.EquipSlot, manip.Imc.Variant, "a" ) );
break;
case ObjectType.Weapon:
Penumbra.Identifier.Identify( changedItems, GamePaths.Weapon.Mtrl.Path( manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.Variant, "a" ) );
break;
case ObjectType.DemiHuman:
Penumbra.Identifier.Identify( changedItems,
GamePaths.DemiHuman.Mtrl.Path( manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.EquipSlot, manip.Imc.Variant, "a" ) );
break;
case ObjectType.Monster:
Penumbra.Identifier.Identify( changedItems, GamePaths.Monster.Mtrl.Path( manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.Variant, "a" ) );
break;
}
break;
case MetaManipulation.Type.Eqdp:
Penumbra.Identifier.Identify( changedItems,
GamePaths.Equipment.Mdl.Path( manip.Eqdp.SetId, Names.CombinedRace( manip.Eqdp.Gender, manip.Eqdp.Race ), manip.Eqdp.Slot ) );
break;
case MetaManipulation.Type.Eqp:
Penumbra.Identifier.Identify( changedItems, GamePaths.Equipment.Mdl.Path( manip.Eqp.SetId, GenderRace.MidlanderMale, manip.Eqp.Slot ) );
break;
case MetaManipulation.Type.Est:
switch( manip.Est.Slot )
{
case EstManipulation.EstType.Hair:
changedItems.TryAdd( $"Customization: {manip.Est.Race} {manip.Est.Gender} Hair (Hair) {manip.Est.SetId}", null );
break;
case EstManipulation.EstType.Face:
changedItems.TryAdd( $"Customization: {manip.Est.Race} {manip.Est.Gender} Face (Face) {manip.Est.SetId}", null );
break;
case EstManipulation.EstType.Body:
Penumbra.Identifier.Identify( changedItems,
GamePaths.Equipment.Mdl.Path( manip.Est.SetId, Names.CombinedRace( manip.Est.Gender, manip.Est.Race ), EquipSlot.Body ) );
break;
case EstManipulation.EstType.Head:
Penumbra.Identifier.Identify( changedItems,
GamePaths.Equipment.Mdl.Path( manip.Est.SetId, Names.CombinedRace( manip.Est.Gender, manip.Est.Race ), EquipSlot.Head ) );
break;
}
break;
case MetaManipulation.Type.Gmp:
Penumbra.Identifier.Identify( changedItems, GamePaths.Equipment.Mdl.Path( manip.Gmp.SetId, GenderRace.MidlanderMale, EquipSlot.Head ) );
break;
case MetaManipulation.Type.Rsp:
changedItems.TryAdd( $"{manip.Rsp.SubRace.ToName()} {manip.Rsp.Attribute.ToFullString()}", null );
break;
}
}
}

View file

@ -20,29 +20,6 @@ public partial class Mod
internal readonly SubMod _default;
internal readonly List<IModGroup> _groups = new();
public int TotalFileCount { get; internal set; }
public int TotalSwapCount { get; internal set; }
public int TotalManipulations { get; internal set; }
public bool HasOptions { get; internal set; }
internal bool SetCounts()
{
TotalFileCount = 0;
TotalSwapCount = 0;
TotalManipulations = 0;
foreach (var s in AllSubMods)
{
TotalFileCount += s.Files.Count;
TotalSwapCount += s.FileSwaps.Count;
TotalManipulations += s.Manipulations.Count;
}
HasOptions = _groups.Any(o
=> o is MultiModGroup m && m.PrioritizedOptions.Count > 0
|| o is SingleModGroup s && s.OptionData.Count > 1);
return true;
}
public IEnumerable<ISubMod> AllSubMods
=> _groups.SelectMany(o => o).Prepend(_default);

View file

@ -15,7 +15,6 @@ public sealed partial class Mod
public IReadOnlyList<string> LocalTags { get; private set; } = Array.Empty<string>();
public string AllTagsLower { get; private set; } = string.Empty;
public string Note { get; internal set; } = string.Empty;
public bool Favorite { get; internal set; } = false;
@ -46,9 +45,6 @@ public sealed partial class Mod
}
}
if (type != 0)
AllTagsLower = string.Join('\0', ModTags.Concat(LocalTags).Select(s => s.ToLowerInvariant()));
return type;
}

View file

@ -36,7 +36,7 @@ public class ModCacheManager : IDisposable, IReadOnlyList<ModCache>
}
public IEnumerator<ModCache> GetEnumerator()
=> _cache.GetEnumerator();
=> _cache.Take(Count).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();

View file

@ -49,6 +49,7 @@ public class Penumbra : IDalamudPlugin
public static GameEventManager GameEvents { get; private set; } = null!;
public static MetaFileManager MetaFileManager { get; private set; } = null!;
public static ModManager ModManager { get; private set; } = null!;
public static ModCacheManager ModCaches { get; private set; } = null!;
public static CollectionManager CollectionManager { get; private set; } = null!;
public static TempCollectionManager TempCollections { get; private set; } = null!;
public static TempModManager TempMods { get; private set; } = null!;
@ -105,7 +106,7 @@ public class Penumbra : IDalamudPlugin
RedrawService = _tmp.Services.GetRequiredService<RedrawService>();
_tmp.Services.GetRequiredService<ResourceService>();
ResourceLoader = _tmp.Services.GetRequiredService<ResourceLoader>();
_tmp.Services.GetRequiredService<ModCacheManager>();
ModCaches = _tmp.Services.GetRequiredService<ModCacheManager>();
using (var t = _tmp.Services.GetRequiredService<StartTracker>().Measure(StartTimeType.PathResolver))
{
PathResolver = _tmp.Services.GetRequiredService<PathResolver>();
@ -238,13 +239,13 @@ public class Penumbra : IDalamudPlugin
sb.Append($"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n");
sb.AppendLine("**Mods**");
sb.Append($"> **`Installed Mods: `** {ModManager.Count}\n");
sb.Append($"> **`Mods with Config: `** {ModManager.Count(m => m.HasOptions)}\n");
sb.Append($"> **`Mods with Config: `** {ModCaches.Count(m => m.HasOptions)}\n");
sb.Append(
$"> **`Mods with File Redirections: `** {ModManager.Count(m => m.TotalFileCount > 0)}, Total: {ModManager.Sum(m => m.TotalFileCount)}\n");
$"> **`Mods with File Redirections: `** {ModCaches.Count(m => m.TotalFileCount > 0)}, Total: {ModCaches.Sum(m => m.TotalFileCount)}\n");
sb.Append(
$"> **`Mods with FileSwaps: `** {ModManager.Count(m => m.TotalSwapCount > 0)}, Total: {ModManager.Sum(m => m.TotalSwapCount)}\n");
$"> **`Mods with FileSwaps: `** {ModCaches.Count(m => m.TotalSwapCount > 0)}, Total: {ModCaches.Sum(m => m.TotalSwapCount)}\n");
sb.Append(
$"> **`Mods with Meta Manipulations:`** {ModManager.Count(m => m.TotalManipulations > 0)}, Total {ModManager.Sum(m => m.TotalManipulations)}\n");
$"> **`Mods with Meta Manipulations:`** {ModCaches.Count(m => m.TotalManipulations > 0)}, Total {ModCaches.Sum(m => m.TotalManipulations)}\n");
sb.Append($"> **`IMC Exceptions Thrown: `** {ValidityChecker.ImcExceptions.Count}\n");
sb.Append(
$"> **`#Temp Mods: `** {TempMods.Mods.Sum(kvp => kvp.Value.Count) + TempMods.ModsForAllCollections.Count}\n");
@ -265,7 +266,7 @@ public class Penumbra : IDalamudPlugin
=> sb.Append($"**Collection {c.AnonymizedName}**\n"
+ $"> **`Inheritances: `** {c.Inheritance.Count}\n"
+ $"> **`Enabled Mods: `** {c.ActualSettings.Count(s => s is { Enabled: true })}\n"
+ $"> **`Conflicts (Solved/Total): `** {c.AllConflicts.SelectMany(x => x).Sum(x => x.HasPriority ? 0 : x.Conflicts.Count)}/{c.AllConflicts.SelectMany(x => x).Sum(x => x.HasPriority || !x.Solved ? 0 : x.Conflicts.Count)}\n");
+ $"> **`Conflicts (Solved/Total): `** {c.AllConflicts.SelectMany(x => x).Sum(x => x.HasPriority && x.Solved ? x.Conflicts.Count : 0)}/{c.AllConflicts.SelectMany(x => x).Sum(x => x.HasPriority ? x.Conflicts.Count : 0)}\n");
sb.AppendLine("**Collections**");
sb.Append($"> **`#Collections: `** {CollectionManager.Count - 1}\n");

View file

@ -82,7 +82,7 @@ public partial class ModEditWindow
return f.SubModUsage.Count == 0
? Enumerable.Repeat((file, "Unused", string.Empty, 0x40000080u), 1)
: f.SubModUsage.Select(s => (file, s.Item2.ToString(), s.Item1.FullName,
_editor.Option! == s.Item1 && _mod!.HasOptions ? 0x40008000u : 0u));
_editor.Option! == s.Item1 && _modCaches[_mod!].HasOptions ? 0x40008000u : 0u));
});
void DrawLine((string, string, string, uint) data)

View file

@ -24,10 +24,11 @@ public partial class ModEditWindow : Window, IDisposable
{
private const string WindowBaseLabel = "###SubModEdit";
private readonly ModEditor _editor;
private readonly Configuration _config;
private readonly ItemSwapTab _itemSwapTab;
private readonly DataManager _gameData;
private readonly ModEditor _editor;
private readonly ModCacheManager _modCaches;
private readonly Configuration _config;
private readonly ItemSwapTab _itemSwapTab;
private readonly DataManager _gameData;
private Mod? _mod;
private Vector2 _iconSize = Vector2.Zero;
@ -490,12 +491,13 @@ public partial class ModEditWindow : Window, IDisposable
}
public ModEditWindow(FileDialogService fileDialog, ItemSwapTab itemSwapTab, DataManager gameData,
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory)
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, ModCacheManager modCaches)
: base(WindowBaseLabel)
{
_itemSwapTab = itemSwapTab;
_config = config;
_editor = editor;
_modCaches = modCaches;
_gameData = gameData;
_fileDialog = fileDialog;
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _fileDialog, "Materials", ".mtrl",

View file

@ -30,6 +30,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
private readonly Configuration _config;
private readonly FileDialogService _fileDialog;
private readonly ModManager _modManager;
private readonly ModCacheManager _modCaches;
private readonly CollectionManager _collectionManager;
private readonly TutorialService _tutorial;
private readonly ModEditor _modEditor;
@ -42,7 +43,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
public ModFileSystemSelector(CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager,
CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog, ChatService chat,
ModEditor modEditor)
ModEditor modEditor, ModCacheManager modCaches)
: base(fileSystem, DalamudServices.KeyState, HandleException)
{
_communicator = communicator;
@ -53,6 +54,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
_fileDialog = fileDialog;
_chat = chat;
_modEditor = modEditor;
_modCaches = modCaches;
// @formatter:off
SubscribeRightClickFolder(EnableDescendants, 10);
@ -609,8 +611,8 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
0 => !(leaf.FullName().Contains(_modFilter.Lower, IgnoreCase) || mod.Name.Contains(_modFilter)),
1 => !mod.Name.Contains(_modFilter),
2 => !mod.Author.Contains(_modFilter),
3 => !mod.LowerChangedItemsString.Contains(_modFilter.Lower),
4 => !mod.AllTagsLower.Contains(_modFilter.Lower),
3 => !_modCaches[mod].LowerChangedItemsString.Contains(_modFilter.Lower),
4 => !_modCaches[mod].AllTagsLower.Contains(_modFilter.Lower),
_ => false, // Should never happen
};
}
@ -639,12 +641,13 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
private bool CheckStateFilters(Mod mod, ModSettings? settings, ModCollection collection, ref ModState state)
{
var isNew = _modManager.IsNew(mod);
var cache = _modCaches[mod.Index];
// Handle mod details.
if (CheckFlags(mod.TotalFileCount, ModFilter.HasNoFiles, ModFilter.HasFiles)
|| CheckFlags(mod.TotalSwapCount, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps)
|| CheckFlags(mod.TotalManipulations, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations)
|| CheckFlags(mod.HasOptions ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig)
|| CheckFlags(isNew ? 1 : 0, ModFilter.NotNew, ModFilter.IsNew))
if (CheckFlags(cache.TotalFileCount, ModFilter.HasNoFiles, ModFilter.HasFiles)
|| CheckFlags(cache.TotalSwapCount, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps)
|| CheckFlags(cache.TotalManipulations, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations)
|| CheckFlags(cache.HasOptions ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig)
|| CheckFlags(isNew ? 1 : 0, ModFilter.NotNew, ModFilter.IsNew))
return true;
// Handle Favoritism

View file

@ -6,7 +6,7 @@ using OtterGui.Classes;
using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.Api;
using Penumbra.UI.Classes;
using Penumbra.Mods;
namespace Penumbra.UI.ModsTab;
@ -14,18 +14,20 @@ public class ModPanelChangedItemsTab : ITab
{
private readonly ModFileSystemSelector _selector;
private readonly PenumbraApi _api;
private readonly ModCacheManager _modCaches;
public ReadOnlySpan<byte> Label
=> "Changed Items"u8;
public ModPanelChangedItemsTab(PenumbraApi api, ModFileSystemSelector selector)
public ModPanelChangedItemsTab(PenumbraApi api, ModFileSystemSelector selector, ModCacheManager modCaches)
{
_api = api;
_selector = selector;
_api = api;
_selector = selector;
_modCaches = modCaches;
}
public bool IsVisible
=> _selector.Selected!.ChangedItems.Count > 0;
=> _modCaches[_selector.Selected!].ChangedItems.Count > 0;
public void DrawContent()
{
@ -33,7 +35,7 @@ public class ModPanelChangedItemsTab : ITab
if (!list)
return;
var zipList = ZipList.FromSortedList(_selector.Selected!.ChangedItems);
var zipList = ZipList.FromSortedList(_modCaches[_selector.Selected!].ChangedItems);
var height = ImGui.GetTextLineHeight();
ImGuiClip.ClippedDraw(zipList, kvp => UiHelpers.DrawChangedItem(_api, kvp.Item1, kvp.Item2, true), height);
}