Merge branch 'master' into dev/pie-lover
This commit is contained in:
@@ -79,7 +79,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
||||
|
||||
LayoutContent();
|
||||
|
||||
addon->SubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
|
||||
//addon->SubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
|
||||
|
||||
System.LootedItemsTracker.OnLootedItemsChanged += OnLootedItemsChanged;
|
||||
|
||||
|
||||
@@ -62,6 +62,10 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
private readonly HashSet<uint> _searchMatchScratch = new();
|
||||
private bool _isRefreshing;
|
||||
|
||||
private int _requestedUpdateCount;
|
||||
private int _refreshFromLifecycleCount;
|
||||
private long _lastLogTick;
|
||||
|
||||
public void ManualRefresh()
|
||||
{
|
||||
if (!IsOpen) return;
|
||||
@@ -104,6 +108,10 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
try
|
||||
{
|
||||
_isRefreshing = true;
|
||||
|
||||
_refreshFromLifecycleCount++;
|
||||
LogRefreshStats();
|
||||
|
||||
InventoryState.RefreshFromGame();
|
||||
RefreshCategoriesCore(autosize: true);
|
||||
}
|
||||
@@ -405,8 +413,24 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
RefreshCategoriesCore(false);
|
||||
}
|
||||
|
||||
private void LogRefreshStats()
|
||||
{
|
||||
long now = Environment.TickCount64;
|
||||
if (now - _lastLogTick > 1000) // Log every second
|
||||
{
|
||||
Services.Logger.DebugOnly($"[Perf] Last 1s: OnRequestedUpdate={_requestedUpdateCount}, RefreshFromLifecycle={_refreshFromLifecycleCount}");
|
||||
_requestedUpdateCount = 0;
|
||||
_refreshFromLifecycleCount = 0;
|
||||
_lastLogTick = now;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
||||
{
|
||||
_requestedUpdateCount++;
|
||||
LogRefreshStats();
|
||||
|
||||
base.OnRequestedUpdate(addon, numberArrayData, stringArrayData);
|
||||
|
||||
if (DragDropState.IsDragging)
|
||||
@@ -415,6 +439,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
InventoryState.RefreshFromGame();
|
||||
RefreshCategoriesCore(autosize: true);
|
||||
}
|
||||
*/
|
||||
|
||||
protected override void OnSetup(AtkUnitBase* addon)
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ public static class Util
|
||||
{
|
||||
FileInfo file = JsonFileHelper.GetFileInfo(SystemConfiguration.FileName);
|
||||
var config = JsonFileHelper.LoadFile<SystemConfiguration>(file.FullName);
|
||||
config?.EnsureInitialized();
|
||||
config.EnsureInitialized();
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ public sealed unsafe class LootedItemsTracker : IDisposable
|
||||
private readonly List<LootedItemInfo> _lootedItems = new(capacity: 64);
|
||||
private readonly Dictionary<(uint ItemId, bool IsHq), (InventoryItem Item, int Quantity)> _pendingChanges = new(capacity: 32);
|
||||
|
||||
private static HashSet<uint>? _filteredCategoryItems;
|
||||
|
||||
private bool _isEnabled;
|
||||
private long _batchStartTick;
|
||||
private bool _hasPendingRemoval;
|
||||
@@ -171,12 +173,18 @@ public sealed unsafe class LootedItemsTracker : IDisposable
|
||||
|
||||
private static bool ShouldFilterItem(uint itemId)
|
||||
{
|
||||
if (!Services.DataManager.GetExcelSheet<Item>().TryGetRow(itemId, out var item))
|
||||
return false;
|
||||
if (_filteredCategoryItems == null)
|
||||
{
|
||||
_filteredCategoryItems = new HashSet<uint>();
|
||||
var sheet = Services.DataManager.GetExcelSheet<Item>();
|
||||
foreach (var row in sheet)
|
||||
{
|
||||
if (row.ItemUICategory.RowId == 62)
|
||||
_filteredCategoryItems.Add(row.RowId);
|
||||
}
|
||||
Services.Logger.DebugOnly($"[LootedItemsTracker] Built filter cache with {_filteredCategoryItems.Count} items");
|
||||
}
|
||||
|
||||
if (item.ItemUICategory.RowId == 62)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return _filteredCategoryItems.Contains(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,13 @@ public abstract class InventoryStateBase
|
||||
bool allaganCategoriesEnabled = config.Categories.AllaganToolsCategoriesEnabled && categoriesEnabled;
|
||||
bool bisCategoriesEnabled = config.Categories.BisBuddyEnabled && categoriesEnabled;
|
||||
// TODO: Cache this when config changes
|
||||
var userCategories = config.Categories.UserCategories.Where(c => c.Enabled).ToList();
|
||||
UserCategoriesSortedScratch.Clear();
|
||||
foreach (var cat in config.Categories. UserCategories)
|
||||
{
|
||||
if (cat.Enabled)
|
||||
UserCategoriesSortedScratch.Add(cat);
|
||||
}
|
||||
var userCategories = UserCategoriesSortedScratch;
|
||||
|
||||
if (userCategoriesEnabled && userCategories.Count > 0)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using AetherBags.Inventory.Items;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
using FFXIVClientStructs.FFXIV.Common.Math;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
@@ -42,17 +43,28 @@ public sealed unsafe class LootedItemDisplayNode : SimpleComponentNode
|
||||
_quantityTextNode.AttachNode(this);
|
||||
}
|
||||
|
||||
public LootedItemInfo LootedItem
|
||||
public LootedItemInfo? LootedItem
|
||||
{
|
||||
get;
|
||||
set
|
||||
{
|
||||
bool needsCollisionUpdate = field is null && value is not null;
|
||||
field = value;
|
||||
var item = value.Item;
|
||||
|
||||
if (value is not null)
|
||||
{
|
||||
InventoryItem item = value.Item;
|
||||
_iconNode.IconId = item.IconId;
|
||||
_iconNode.ItemTooltip = item.ItemId;
|
||||
_quantityTextNode.String = value.Quantity > 1 ? value.Quantity.ToString() : string.Empty;
|
||||
_iconNode.IsVisible = true;
|
||||
_quantityTextNode.IsVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_iconNode.IsVisible = false;
|
||||
_quantityTextNode.String = string.Empty;
|
||||
}
|
||||
|
||||
if (needsCollisionUpdate)
|
||||
{
|
||||
@@ -61,7 +73,7 @@ public sealed unsafe class LootedItemDisplayNode : SimpleComponentNode
|
||||
addon->UpdateCollisionNodeList(false);
|
||||
}
|
||||
}
|
||||
} = null!;
|
||||
} = null;
|
||||
|
||||
private void OnMouseClick(AtkEventListener* thisPtr, AtkEventType eventType, int eventParam, AtkEvent* atkEvent, AtkEventData* atkEventData)
|
||||
{
|
||||
|
||||
@@ -180,6 +180,7 @@ public abstract class DeferrableLayoutListNode : SimpleComponentNode
|
||||
private List<NodeBase>? _desiredScratch;
|
||||
private List<NodeBase>? _toRemoveScratch;
|
||||
private HashSet<object>? _dataKeysScratch;
|
||||
private Dictionary<object, NodeBase>? _byKeyScratch;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private List<NodeBase> RentExistingList(int capacity)
|
||||
@@ -308,8 +309,17 @@ public abstract class DeferrableLayoutListNode : SimpleComponentNode
|
||||
|
||||
Dictionary<TKey, TU>? byKey = null;
|
||||
if (existing.Count > 0)
|
||||
{
|
||||
if (_byKeyScratch is Dictionary<TKey, TU> reusable)
|
||||
{
|
||||
byKey = reusable;
|
||||
byKey.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
byKey = new Dictionary<TKey, TU>(existing.Count, keyComparer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < existing.Count; i++)
|
||||
{
|
||||
var tu = (TU)existing[i];
|
||||
@@ -407,6 +417,12 @@ public abstract class DeferrableLayoutListNode : SimpleComponentNode
|
||||
RecalculateLayout();
|
||||
}
|
||||
|
||||
if (byKey != null)
|
||||
{
|
||||
byKey.Clear();
|
||||
_byKeyScratch = byKey as Dictionary<object, NodeBase>;
|
||||
}
|
||||
|
||||
return structureChanged || orderChanged;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user