feat(headless): hydrate isolated collision worlds
This commit is contained in:
parent
9569dadb57
commit
b6547ff38c
20 changed files with 1960 additions and 101 deletions
|
|
@ -6,6 +6,7 @@ using AcDream.Headless.Credentials;
|
|||
using AcDream.Headless.Diagnostics;
|
||||
using AcDream.Headless.Hosting;
|
||||
using AcDream.Headless.Platform;
|
||||
using AcDream.Headless.Policies;
|
||||
using AcDream.Runtime;
|
||||
using AcDream.Runtime.Session;
|
||||
|
||||
|
|
@ -186,11 +187,60 @@ public sealed class HeadlessProcessSchedulerTests
|
|||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowingPolicyQuarantinesOnlyItsOwnSession()
|
||||
{
|
||||
var time = new ManualTimeProvider();
|
||||
var operations = new FixtureSessionOperations();
|
||||
var throwing = new ThrowingPolicy();
|
||||
var healthy = new CountingPolicy();
|
||||
using HeadlessSessionHost first =
|
||||
CreateSession(
|
||||
"fault",
|
||||
time,
|
||||
operations,
|
||||
policyOverride: throwing);
|
||||
using HeadlessSessionHost second =
|
||||
CreateSession(
|
||||
"healthy",
|
||||
time,
|
||||
operations,
|
||||
policyOverride: healthy);
|
||||
Assert.Equal(
|
||||
RuntimeSessionStartStatus.Connected,
|
||||
first.Start().Status);
|
||||
Assert.Equal(
|
||||
RuntimeSessionStartStatus.Connected,
|
||||
second.Start().Status);
|
||||
var scheduler = new HeadlessProcessScheduler(
|
||||
[first, second],
|
||||
time);
|
||||
|
||||
time.Advance(TimeSpan.FromMilliseconds(15));
|
||||
Assert.True(scheduler.DispatchDue(time.GetTimestamp()));
|
||||
|
||||
Assert.True(first.IsFaulted);
|
||||
Assert.IsType<InvalidOperationException>(first.Fault);
|
||||
Assert.False(second.IsFaulted);
|
||||
Assert.Equal(1, healthy.TickCount);
|
||||
HeadlessSchedulerSnapshot snapshot =
|
||||
scheduler.CaptureSnapshot();
|
||||
Assert.Equal(1, snapshot.FaultedSessionCount);
|
||||
Assert.Equal(1, snapshot.ActiveSessionCount);
|
||||
|
||||
time.Advance(TimeSpan.FromMilliseconds(15));
|
||||
Assert.True(scheduler.DispatchDue(time.GetTimestamp()));
|
||||
Assert.Equal(2, healthy.TickCount);
|
||||
Assert.Equal(1UL, first.Runtime.Clock.FrameNumber);
|
||||
Assert.Equal(2UL, second.Runtime.Clock.FrameNumber);
|
||||
}
|
||||
|
||||
private static HeadlessSessionHost CreateSession(
|
||||
string id,
|
||||
TimeProvider time,
|
||||
ILiveSessionOperations operations,
|
||||
TimeSpan? reconnectQuiescence = null)
|
||||
TimeSpan? reconnectQuiescence = null,
|
||||
IHeadlessBotPolicy? policyOverride = null)
|
||||
{
|
||||
var credential = new HeadlessCredentialSecret(
|
||||
$"{id}-credential",
|
||||
|
|
@ -203,7 +253,8 @@ public sealed class HeadlessProcessSchedulerTests
|
|||
new HeadlessDiagnosticWriter(TextWriter.Null),
|
||||
operations,
|
||||
time,
|
||||
reconnectQuiescence);
|
||||
reconnectQuiescence,
|
||||
policyOverride: policyOverride);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -304,4 +355,67 @@ public sealed class HeadlessProcessSchedulerTests
|
|||
session.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class FixturePolicy : IHeadlessBotPolicy
|
||||
{
|
||||
public virtual bool IsComplete => false;
|
||||
|
||||
public abstract void Tick(
|
||||
IGameRuntimeView view,
|
||||
IGameRuntimeCommands commands);
|
||||
|
||||
public void OnLifecycle(in RuntimeLifecycleDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCommand(in RuntimeCommandDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnEntity(in RuntimeEntityDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnInventory(in RuntimeInventoryDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnChat(in RuntimeChatDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnMovement(in RuntimeMovementDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnPortal(in RuntimePortalDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCombat(in RuntimeCombatDelta delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ThrowingPolicy : FixturePolicy
|
||||
{
|
||||
public override void Tick(
|
||||
IGameRuntimeView view,
|
||||
IGameRuntimeCommands commands) =>
|
||||
throw new InvalidOperationException("injected policy fault");
|
||||
}
|
||||
|
||||
private sealed class CountingPolicy : FixturePolicy
|
||||
{
|
||||
public int TickCount { get; private set; }
|
||||
|
||||
public override void Tick(
|
||||
IGameRuntimeView view,
|
||||
IGameRuntimeCommands commands) =>
|
||||
TickCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue