perf(ui): cache auto-tell tab tint and icon per tab

This commit is contained in:
2026-05-07 22:06:18 +02:00
parent 36b92f0520
commit 1ffc41f97d
4 changed files with 48 additions and 2 deletions
+10
View File
@@ -482,6 +482,16 @@ public class Tab
// session. NonSerialized because the temp tab itself is session-only.
[NonSerialized] public bool IsGreeted;
// v1.4.2 — TabTintCache uses separate validation keys per cache so a
// TellTarget change picked up by GetTint can't strand GetIcon (or vice
// versa) with a stale entry that looks fresh on the shared key.
[NonSerialized] internal string? _cachedTintTellName;
[NonSerialized] internal uint _cachedTintTellWorld;
[NonSerialized] internal uint _cachedTellTint;
[NonSerialized] internal string? _cachedIconTellName;
[NonSerialized] internal uint _cachedIconTellWorld;
[NonSerialized] internal string? _cachedTellIcon;
public bool Matches(Message message)
{
if (!message.Matches(SelectedChannels, ExtraChatAll, ExtraChatChannels))
+1 -1
View File
@@ -1571,7 +1571,7 @@ public sealed class ChatLogWindow : Window
{
// v1.2.0 — Hash-Color-Tint differenziert parallele Auto-Tell-Tabs
// visuell ohne dass User pro Tab manuell ein Custom-Icon setzen muss.
iconColor = AutoTellTabTint.For(tab.TellTarget.Name, tab.TellTarget.World);
iconColor = TabTintCache.GetTint(tab);
}
else
{
+1 -1
View File
@@ -61,7 +61,7 @@ internal static class TabIconMapping
string? autoTellGlyph = null;
if (tab.IsTempTab && tab.TellTarget != null && tab.TellTarget.IsSet())
{
autoTellGlyph = AutoTellTabTint.IconFor(tab.TellTarget.Name, tab.TellTarget.World);
autoTellGlyph = TabTintCache.GetIcon(tab);
}
var glyph = TabIconGlyphResolver.ResolveGlyphName(tab, autoTellGlyph);
+36
View File
@@ -0,0 +1,36 @@
namespace HellionChat.Ui;
// Per-Tab cache wrapper around the pure AutoTellTabTint hash helpers.
// Each cache (tint, icon) carries its own name+world validation key so
// neither read path mutates the other's state — refilling one never
// invalidates the other. No string allocation in the steady-state lookup.
internal static class TabTintCache
{
public static uint GetTint(Tab tab)
{
var name = tab.TellTarget.Name;
var world = tab.TellTarget.World;
if (tab._cachedTintTellName != name || tab._cachedTintTellWorld != world)
{
tab._cachedTintTellName = name;
tab._cachedTintTellWorld = world;
tab._cachedTellTint = AutoTellTabTint.For(name, world);
}
return tab._cachedTellTint;
}
public static string GetIcon(Tab tab)
{
var name = tab.TellTarget.Name;
var world = tab.TellTarget.World;
if (tab._cachedTellIcon is null
|| tab._cachedIconTellName != name
|| tab._cachedIconTellWorld != world)
{
tab._cachedIconTellName = name;
tab._cachedIconTellWorld = world;
tab._cachedTellIcon = AutoTellTabTint.IconFor(name, world);
}
return tab._cachedTellIcon;
}
}