fix(runtime): close Campaign LA7b review findings
This commit is contained in:
parent
0e82cbf700
commit
1b9e7e41f9
11 changed files with 700 additions and 28 deletions
|
|
@ -211,6 +211,74 @@ public sealed class CurrentGameRuntimeAdapterTests
|
|||
Assert.Equal(Harness.PlayerGuid, harness.Identity.ServerGuid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisposedAdapterMakesRetainedSelectionRoutesInertWhileRuntimeLives()
|
||||
{
|
||||
using var harness = new Harness(awaitCharacterSelection: true);
|
||||
using CurrentGameRuntimeAdapter survivor =
|
||||
harness.CreateAdditionalAdapter();
|
||||
Assert.Equal(
|
||||
RuntimeSessionStartStatus.AwaitingCharacterSelection,
|
||||
harness.Runtime.Session.Start(harness.Runtime.Generation).Status);
|
||||
|
||||
RuntimeGenerationToken generation = harness.Runtime.Generation;
|
||||
IRuntimeCharacterSelectionView retainedView =
|
||||
harness.Runtime.CharacterSelection;
|
||||
IRuntimeCharacterSelectionCommands publicCommands =
|
||||
harness.Runtime.CharacterSelectionCommands;
|
||||
IRuntimeCharacterSelectionCommands interfaceCommands =
|
||||
((IGameRuntimeCommands)harness.Runtime).CharacterSelection;
|
||||
var observer = new CharacterSelectionObserver();
|
||||
using IDisposable subscription = retainedView.Subscribe(observer);
|
||||
RuntimeCharacterSelectionSnapshot before =
|
||||
survivor.CharacterSelection.Snapshot;
|
||||
|
||||
harness.Runtime.Dispose();
|
||||
|
||||
Assert.False(harness.Runtime.Lifecycle.HasTransport);
|
||||
Assert.Equal(
|
||||
RuntimeCharacterSelectionLifecycle.Inactive,
|
||||
retainedView.Snapshot.Lifecycle);
|
||||
Assert.Equal(0, retainedView.Snapshot.RosterCount);
|
||||
Assert.False(retainedView.TryGetAt(0, out _));
|
||||
Assert.False(retainedView.TryGet(Harness.PlayerGuid, out _));
|
||||
var visitor = new CharacterSelectionVisitor();
|
||||
retainedView.Visit(visitor);
|
||||
Assert.Empty(visitor.Entries);
|
||||
Assert.Throws<ObjectDisposedException>(() =>
|
||||
retainedView.Subscribe(new CharacterSelectionObserver()));
|
||||
|
||||
RuntimeCommandStatus[] statuses =
|
||||
[
|
||||
publicCommands.Highlight(generation, 0x50000001u).Status,
|
||||
publicCommands.Enter(generation).Status,
|
||||
publicCommands.RequestDelete(generation).Status,
|
||||
interfaceCommands.ConfirmDelete(generation).Status,
|
||||
interfaceCommands.Restore(generation).Status,
|
||||
interfaceCommands.Cancel(generation).Status,
|
||||
];
|
||||
Assert.All(statuses, status =>
|
||||
Assert.Equal(RuntimeCommandStatus.Inactive, status));
|
||||
|
||||
RuntimeCharacterSelectionSnapshot after =
|
||||
survivor.CharacterSelection.Snapshot;
|
||||
Assert.Equal(before.Revision, after.Revision);
|
||||
Assert.Equal(before.HighlightedCharacterId, after.HighlightedCharacterId);
|
||||
Assert.Equal(before.Operation, after.Operation);
|
||||
|
||||
// The second lease proves the canonical Runtime is still live, while
|
||||
// the disposed adapter's already-returned observer stays detached.
|
||||
Assert.True(survivor.CharacterSelectionCommands.Highlight(
|
||||
generation,
|
||||
0x50000001u).Accepted);
|
||||
Assert.Equal(0x50000001u,
|
||||
survivor.CharacterSelection.Snapshot.HighlightedCharacterId);
|
||||
Assert.Empty(observer.Deltas);
|
||||
Assert.Equal(
|
||||
RuntimeCharacterSelectionLifecycle.Inactive,
|
||||
harness.Runtime.CharacterSelection.Snapshot.Lifecycle);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GenerationGateRejectsStaleCommandsAndStopAcknowledgesTeardown()
|
||||
{
|
||||
|
|
@ -735,6 +803,7 @@ public sealed class CurrentGameRuntimeAdapterTests
|
|||
private readonly LiveSessionController _session;
|
||||
private readonly IDisposable _combatModeBinding;
|
||||
private readonly GameRuntime _gameRuntime;
|
||||
private readonly SelectionInteractionController _selectionController;
|
||||
|
||||
public Harness(bool awaitCharacterSelection = false)
|
||||
{
|
||||
|
|
@ -789,7 +858,7 @@ public sealed class CurrentGameRuntimeAdapterTests
|
|||
sendWield: null,
|
||||
sendDrop: null);
|
||||
var query = new SelectionQuery(TargetGuid);
|
||||
var selectionController = new SelectionInteractionController(
|
||||
_selectionController = new SelectionInteractionController(
|
||||
Selection,
|
||||
query,
|
||||
_items,
|
||||
|
|
@ -805,7 +874,7 @@ public sealed class CurrentGameRuntimeAdapterTests
|
|||
_gameRuntime,
|
||||
Host,
|
||||
Commands,
|
||||
selectionController);
|
||||
_selectionController);
|
||||
}
|
||||
|
||||
public RuntimeOptions Options { get; }
|
||||
|
|
@ -842,6 +911,13 @@ public sealed class CurrentGameRuntimeAdapterTests
|
|||
public LiveSessionHost Host { get; }
|
||||
public CurrentGameRuntimeAdapter Runtime { get; }
|
||||
|
||||
public CurrentGameRuntimeAdapter CreateAdditionalAdapter() =>
|
||||
new(
|
||||
_gameRuntime,
|
||||
Host,
|
||||
Commands,
|
||||
_selectionController);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Runtime.Dispose();
|
||||
|
|
@ -853,6 +929,25 @@ public sealed class CurrentGameRuntimeAdapterTests
|
|||
}
|
||||
}
|
||||
|
||||
private sealed class CharacterSelectionVisitor
|
||||
: IRuntimeCharacterSelectionVisitor
|
||||
{
|
||||
public List<RuntimeCharacterSelectionEntry> Entries { get; } = [];
|
||||
|
||||
public void Visit(in RuntimeCharacterSelectionEntry character) =>
|
||||
Entries.Add(character);
|
||||
}
|
||||
|
||||
private sealed class CharacterSelectionObserver
|
||||
: IRuntimeCharacterSelectionObserver
|
||||
{
|
||||
public List<RuntimeCharacterSelectionDelta> Deltas { get; } = [];
|
||||
|
||||
public void OnCharacterSelectionChanged(
|
||||
in RuntimeCharacterSelectionDelta delta) =>
|
||||
Deltas.Add(delta);
|
||||
}
|
||||
|
||||
private static void PrepareCombatAndMagic(Harness harness)
|
||||
{
|
||||
harness.Actions.Combat.SetCombatMode(AcDream.Core.Combat.CombatMode.Melee);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue