perf(ui): retain shaped report text

This commit is contained in:
Erik 2026-07-25 05:11:12 +02:00
parent c0bec56dfe
commit f2a015be8e
11 changed files with 525 additions and 38 deletions

View file

@ -78,6 +78,17 @@ public sealed class CharacterSheetProvider
_sendTrainSkill = sendTrainSkill;
}
/// <summary>
/// Subscribe to semantic inputs used by <see cref="BuildSheet"/>. The
/// returned binding owns every event registration and filters object-table
/// notices to the current player GUID.
/// </summary>
public IDisposable SubscribeChanged(Action changed)
{
ArgumentNullException.ThrowIfNull(changed);
return new ChangeBinding(this, changed);
}
// ── Sheet assembly ─────────────────────────────────────────────────────
/// <summary>Best display name: active toon key, else the live object's name, else "Player".</summary>
@ -181,6 +192,52 @@ public sealed class CharacterSheetProvider
: _localPlayer.Properties;
}
private sealed class ChangeBinding : IDisposable
{
private CharacterSheetProvider? _owner;
private readonly Action _changed;
public ChangeBinding(CharacterSheetProvider owner, Action changed)
{
_owner = owner;
_changed = changed;
owner._objects.ObjectAdded += OnObjectChanged;
owner._objects.ObjectUpdated += OnObjectChanged;
owner._objects.ObjectRemoved += OnObjectChanged;
owner._objects.Cleared += OnCleared;
owner._localPlayer.AttributeChanged += OnAttributeChanged;
owner._localPlayer.CharacterChanged += OnCharacterChanged;
}
private void OnObjectChanged(ClientObject value)
{
CharacterSheetProvider? owner = _owner;
if (owner is not null && value.ObjectId == owner._playerGuid())
_changed();
}
private void OnCleared() => _changed();
private void OnAttributeChanged(LocalPlayerState.AttributeKind _) =>
_changed();
private void OnCharacterChanged() => _changed();
public void Dispose()
{
CharacterSheetProvider? owner = Interlocked.Exchange(ref _owner, null);
if (owner is null)
return;
owner._objects.ObjectAdded -= OnObjectChanged;
owner._objects.ObjectUpdated -= OnObjectChanged;
owner._objects.ObjectRemoved -= OnObjectChanged;
owner._objects.Cleared -= OnCleared;
owner._localPlayer.AttributeChanged -= OnAttributeChanged;
owner._localPlayer.CharacterChanged -= OnCharacterChanged;
}
}
/// <summary>
/// Load the portal ExperienceTable (0x0E000018), falling back to a
/// type scan for older or odd dat collections. Failures are logged —