refactor(app): compose live presentation startup

This commit is contained in:
Erik 2026-07-22 17:55:15 +02:00
parent aa6ffa5176
commit 88f32dc4e2
23 changed files with 1767 additions and 626 deletions

View file

@ -58,6 +58,31 @@ internal sealed class AnimationHookRegistrationSet : IDisposable,
_entries.Add(new Entry(sink));
}
public IDisposable RegisterOwned(IAnimationHookSink sink)
{
ArgumentNullException.ThrowIfNull(sink);
ObjectDisposedException.ThrowIf(_closed, this);
if (_entries.Any(entry =>
!entry.Removed && ReferenceEquals(entry.Sink, sink)))
{
throw new InvalidOperationException(
"The animation-hook sink is already registered and cannot be adopted twice.");
}
_register(sink);
_entries.Add(new Entry(sink));
return new Binding(this, sink);
}
private void UnregisterOwned(IAnimationHookSink sink)
{
Entry? entry = _entries.LastOrDefault(candidate =>
!candidate.Removed && ReferenceEquals(candidate.Sink, sink));
if (entry is null)
return;
_unregister(entry.Sink);
entry.Removed = true;
}
public void Dispose()
{
_closed = true;
@ -102,4 +127,25 @@ internal sealed class AnimationHookRegistrationSet : IDisposable,
"Animation-hook registration cleanup remains incomplete.",
failures);
}
private sealed class Binding : IDisposable
{
private AnimationHookRegistrationSet? _owner;
private readonly IAnimationHookSink _sink;
public Binding(AnimationHookRegistrationSet owner, IAnimationHookSink sink)
{
_owner = owner;
_sink = sink;
}
public void Dispose()
{
AnimationHookRegistrationSet? owner = _owner;
if (owner is null)
return;
owner.UnregisterOwned(_sink);
_owner = null;
}
}
}