mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Remove cached data from mod and use ModCaches where required.
This commit is contained in:
parent
2ffbd7beba
commit
e79b110429
14 changed files with 44 additions and 155 deletions
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,8 +76,6 @@ public partial class Mod
|
|||
IncorporateAllMetaChanges(true);
|
||||
}
|
||||
|
||||
ComputeChangedItems();
|
||||
SetCounts();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class ModCacheManager : IDisposable, IReadOnlyList<ModCache>
|
|||
}
|
||||
|
||||
public IEnumerator<ModCache> GetEnumerator()
|
||||
=> _cache.GetEnumerator();
|
||||
=> _cache.Take(Count).GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue