perf(ui): cache auto-tell tab tint and icon per tab
This commit is contained in:
@@ -482,6 +482,16 @@ public class Tab
|
|||||||
// session. NonSerialized because the temp tab itself is session-only.
|
// session. NonSerialized because the temp tab itself is session-only.
|
||||||
[NonSerialized] public bool IsGreeted;
|
[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)
|
public bool Matches(Message message)
|
||||||
{
|
{
|
||||||
if (!message.Matches(SelectedChannels, ExtraChatAll, ExtraChatChannels))
|
if (!message.Matches(SelectedChannels, ExtraChatAll, ExtraChatChannels))
|
||||||
|
|||||||
@@ -1571,7 +1571,7 @@ public sealed class ChatLogWindow : Window
|
|||||||
{
|
{
|
||||||
// v1.2.0 — Hash-Color-Tint differenziert parallele Auto-Tell-Tabs
|
// v1.2.0 — Hash-Color-Tint differenziert parallele Auto-Tell-Tabs
|
||||||
// visuell ohne dass User pro Tab manuell ein Custom-Icon setzen muss.
|
// 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
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ internal static class TabIconMapping
|
|||||||
string? autoTellGlyph = null;
|
string? autoTellGlyph = null;
|
||||||
if (tab.IsTempTab && tab.TellTarget != null && tab.TellTarget.IsSet())
|
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);
|
var glyph = TabIconGlyphResolver.ResolveGlyphName(tab, autoTellGlyph);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user