refactor(runtime): cut graphical host over to canonical root

Make every App composition phase borrow one GameRuntime, retire the duplicate view/event adapters, and dispose the root only after its graphical borrowers release. This preserves synchronous UI commands while giving shutdown one exact ownership ledger.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-26 19:06:09 +02:00
parent ecb9f79444
commit ce41efb9e5
29 changed files with 613 additions and 778 deletions

View file

@ -30,25 +30,25 @@ internal sealed class CurrentGameRuntimeCommandAdapter
private readonly LiveSessionController _session;
private readonly LiveSessionHost _sessionHost;
private readonly ICommandBus _commands;
private readonly CurrentGameRuntimeViewAdapter _view;
private readonly IGameRuntimeView _view;
private readonly RuntimeInventoryState _inventory;
private readonly RuntimeCharacterState _character;
private readonly RuntimeActionState _actions;
private readonly RuntimeLocalPlayerMovementState _movement;
private readonly SelectionInteractionController _selection;
private readonly ICurrentGameRuntimeEventSink _events;
private readonly IGameRuntimeEventSink _events;
public CurrentGameRuntimeCommandAdapter(
LiveSessionController session,
LiveSessionHost sessionHost,
ICommandBus commands,
CurrentGameRuntimeViewAdapter view,
IGameRuntimeView view,
RuntimeInventoryState inventory,
RuntimeCharacterState character,
RuntimeActionState actions,
RuntimeLocalPlayerMovementState movement,
SelectionInteractionController selection,
ICurrentGameRuntimeEventSink events)
IGameRuntimeEventSink events)
{
_session = session ?? throw new ArgumentNullException(nameof(session));
_sessionHost = sessionHost ?? throw new ArgumentNullException(nameof(sessionHost));
@ -80,7 +80,7 @@ internal sealed class CurrentGameRuntimeCommandAdapter
ToCommandStatus(result.Status),
result.CharacterId,
result.CharacterName);
_events.EmitLifecycle(previous);
_events.EmitLifecycle(previous, _view.Lifecycle.State);
return result;
}
@ -100,7 +100,7 @@ internal sealed class CurrentGameRuntimeCommandAdapter
ToCommandStatus(result.Status),
result.CharacterId,
result.CharacterName);
_events.EmitLifecycle(previous);
_events.EmitLifecycle(previous, _view.Lifecycle.State);
return result;
}
@ -125,7 +125,7 @@ internal sealed class CurrentGameRuntimeCommandAdapter
operation: 2,
acknowledgement.Status,
text: acknowledgement.Error?.GetType().Name ?? string.Empty);
_events.EmitLifecycle(previous);
_events.EmitLifecycle(previous, _view.Lifecycle.State);
return acknowledgement;
}
@ -674,7 +674,7 @@ internal sealed class CurrentGameRuntimeCommandAdapter
RuntimeGenerationToken expectedGeneration,
bool requireWorld)
{
if (!_view.IsActive)
if (_view.Lifecycle.State == RuntimeLifecycleState.Disposed)
return RuntimeCommandStatus.Inactive;
if (expectedGeneration != _view.Generation)
return RuntimeCommandStatus.StaleGeneration;