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

View file

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

View file

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

View file

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

View file

@ -76,8 +76,6 @@ public partial class Mod
IncorporateAllMetaChanges(true); IncorporateAllMetaChanges(true);
} }
ComputeChangedItems();
SetCounts();
return true; 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 SubMod _default;
internal readonly List<IModGroup> _groups = new(); 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 public IEnumerable<ISubMod> AllSubMods
=> _groups.SelectMany(o => o).Prepend(_default); => _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 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 string Note { get; internal set; } = string.Empty;
public bool Favorite { get; internal set; } = false; 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; return type;
} }

View file

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

View file

@ -49,6 +49,7 @@ public class Penumbra : IDalamudPlugin
public static GameEventManager GameEvents { get; private set; } = null!; public static GameEventManager GameEvents { get; private set; } = null!;
public static MetaFileManager MetaFileManager { get; private set; } = null!; public static MetaFileManager MetaFileManager { get; private set; } = null!;
public static ModManager ModManager { 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 CollectionManager CollectionManager { get; private set; } = null!;
public static TempCollectionManager TempCollections { get; private set; } = null!; public static TempCollectionManager TempCollections { get; private set; } = null!;
public static TempModManager TempMods { 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>(); RedrawService = _tmp.Services.GetRequiredService<RedrawService>();
_tmp.Services.GetRequiredService<ResourceService>(); _tmp.Services.GetRequiredService<ResourceService>();
ResourceLoader = _tmp.Services.GetRequiredService<ResourceLoader>(); ResourceLoader = _tmp.Services.GetRequiredService<ResourceLoader>();
_tmp.Services.GetRequiredService<ModCacheManager>(); ModCaches = _tmp.Services.GetRequiredService<ModCacheManager>();
using (var t = _tmp.Services.GetRequiredService<StartTracker>().Measure(StartTimeType.PathResolver)) using (var t = _tmp.Services.GetRequiredService<StartTracker>().Measure(StartTimeType.PathResolver))
{ {
PathResolver = _tmp.Services.GetRequiredService<PathResolver>(); PathResolver = _tmp.Services.GetRequiredService<PathResolver>();
@ -238,13 +239,13 @@ public class Penumbra : IDalamudPlugin
sb.Append($"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n"); sb.Append($"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n");
sb.AppendLine("**Mods**"); sb.AppendLine("**Mods**");
sb.Append($"> **`Installed Mods: `** {ModManager.Count}\n"); 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( 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( 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( 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($"> **`IMC Exceptions Thrown: `** {ValidityChecker.ImcExceptions.Count}\n");
sb.Append( sb.Append(
$"> **`#Temp Mods: `** {TempMods.Mods.Sum(kvp => kvp.Value.Count) + TempMods.ModsForAllCollections.Count}\n"); $"> **`#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" => sb.Append($"**Collection {c.AnonymizedName}**\n"
+ $"> **`Inheritances: `** {c.Inheritance.Count}\n" + $"> **`Inheritances: `** {c.Inheritance.Count}\n"
+ $"> **`Enabled Mods: `** {c.ActualSettings.Count(s => s is { Enabled: true })}\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.AppendLine("**Collections**");
sb.Append($"> **`#Collections: `** {CollectionManager.Count - 1}\n"); sb.Append($"> **`#Collections: `** {CollectionManager.Count - 1}\n");

View file

@ -82,7 +82,7 @@ public partial class ModEditWindow
return f.SubModUsage.Count == 0 return f.SubModUsage.Count == 0
? Enumerable.Repeat((file, "Unused", string.Empty, 0x40000080u), 1) ? Enumerable.Repeat((file, "Unused", string.Empty, 0x40000080u), 1)
: f.SubModUsage.Select(s => (file, s.Item2.ToString(), s.Item1.FullName, : 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) 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 const string WindowBaseLabel = "###SubModEdit";
private readonly ModEditor _editor; private readonly ModEditor _editor;
private readonly Configuration _config; private readonly ModCacheManager _modCaches;
private readonly ItemSwapTab _itemSwapTab; private readonly Configuration _config;
private readonly DataManager _gameData; private readonly ItemSwapTab _itemSwapTab;
private readonly DataManager _gameData;
private Mod? _mod; private Mod? _mod;
private Vector2 _iconSize = Vector2.Zero; private Vector2 _iconSize = Vector2.Zero;
@ -490,12 +491,13 @@ public partial class ModEditWindow : Window, IDisposable
} }
public ModEditWindow(FileDialogService fileDialog, ItemSwapTab itemSwapTab, DataManager gameData, public ModEditWindow(FileDialogService fileDialog, ItemSwapTab itemSwapTab, DataManager gameData,
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory) Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, ModCacheManager modCaches)
: base(WindowBaseLabel) : base(WindowBaseLabel)
{ {
_itemSwapTab = itemSwapTab; _itemSwapTab = itemSwapTab;
_config = config; _config = config;
_editor = editor; _editor = editor;
_modCaches = modCaches;
_gameData = gameData; _gameData = gameData;
_fileDialog = fileDialog; _fileDialog = fileDialog;
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _fileDialog, "Materials", ".mtrl", _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 Configuration _config;
private readonly FileDialogService _fileDialog; private readonly FileDialogService _fileDialog;
private readonly ModManager _modManager; private readonly ModManager _modManager;
private readonly ModCacheManager _modCaches;
private readonly CollectionManager _collectionManager; private readonly CollectionManager _collectionManager;
private readonly TutorialService _tutorial; private readonly TutorialService _tutorial;
private readonly ModEditor _modEditor; private readonly ModEditor _modEditor;
@ -42,7 +43,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
public ModFileSystemSelector(CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager, public ModFileSystemSelector(CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager,
CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog, ChatService chat, CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog, ChatService chat,
ModEditor modEditor) ModEditor modEditor, ModCacheManager modCaches)
: base(fileSystem, DalamudServices.KeyState, HandleException) : base(fileSystem, DalamudServices.KeyState, HandleException)
{ {
_communicator = communicator; _communicator = communicator;
@ -53,6 +54,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector<Mod, ModF
_fileDialog = fileDialog; _fileDialog = fileDialog;
_chat = chat; _chat = chat;
_modEditor = modEditor; _modEditor = modEditor;
_modCaches = modCaches;
// @formatter:off // @formatter:off
SubscribeRightClickFolder(EnableDescendants, 10); 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)), 0 => !(leaf.FullName().Contains(_modFilter.Lower, IgnoreCase) || mod.Name.Contains(_modFilter)),
1 => !mod.Name.Contains(_modFilter), 1 => !mod.Name.Contains(_modFilter),
2 => !mod.Author.Contains(_modFilter), 2 => !mod.Author.Contains(_modFilter),
3 => !mod.LowerChangedItemsString.Contains(_modFilter.Lower), 3 => !_modCaches[mod].LowerChangedItemsString.Contains(_modFilter.Lower),
4 => !mod.AllTagsLower.Contains(_modFilter.Lower), 4 => !_modCaches[mod].AllTagsLower.Contains(_modFilter.Lower),
_ => false, // Should never happen _ => 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) private bool CheckStateFilters(Mod mod, ModSettings? settings, ModCollection collection, ref ModState state)
{ {
var isNew = _modManager.IsNew(mod); var isNew = _modManager.IsNew(mod);
var cache = _modCaches[mod.Index];
// Handle mod details. // Handle mod details.
if (CheckFlags(mod.TotalFileCount, ModFilter.HasNoFiles, ModFilter.HasFiles) if (CheckFlags(cache.TotalFileCount, ModFilter.HasNoFiles, ModFilter.HasFiles)
|| CheckFlags(mod.TotalSwapCount, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps) || CheckFlags(cache.TotalSwapCount, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps)
|| CheckFlags(mod.TotalManipulations, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations) || CheckFlags(cache.TotalManipulations, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations)
|| CheckFlags(mod.HasOptions ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig) || CheckFlags(cache.HasOptions ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig)
|| CheckFlags(isNew ? 1 : 0, ModFilter.NotNew, ModFilter.IsNew)) || CheckFlags(isNew ? 1 : 0, ModFilter.NotNew, ModFilter.IsNew))
return true; return true;
// Handle Favoritism // Handle Favoritism

View file

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