feat(headless): hydrate isolated collision worlds
This commit is contained in:
parent
9569dadb57
commit
b6547ff38c
20 changed files with 1960 additions and 101 deletions
|
|
@ -124,6 +124,8 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
private bool _reconnectPending;
|
||||
private ulong _stoppedGeneration;
|
||||
private string _accountName = string.Empty;
|
||||
private Exception? _fault;
|
||||
private bool _faulted;
|
||||
private bool _disposed;
|
||||
|
||||
internal HeadlessSessionHost(
|
||||
|
|
@ -134,7 +136,8 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
TimeProvider? timeProvider = null,
|
||||
TimeSpan? reconnectQuiescence = null,
|
||||
HeadlessProcessContentOwner.HeadlessProcessContentLease?
|
||||
contentLease = null)
|
||||
contentLease = null,
|
||||
IHeadlessBotPolicy? policyOverride = null)
|
||||
{
|
||||
_descriptor = descriptor
|
||||
?? throw new ArgumentNullException(nameof(descriptor));
|
||||
|
|
@ -235,8 +238,8 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
|
||||
hostLease = runtime.AcquireHostLease(
|
||||
$"headless:{descriptor.Id}");
|
||||
policy =
|
||||
HeadlessBotPolicyFactory.Create(descriptor.Policy.Id);
|
||||
policy = policyOverride
|
||||
?? HeadlessBotPolicyFactory.Create(descriptor.Policy.Id);
|
||||
policySubscription = runtime.Subscribe(policy);
|
||||
diagnostics.Lifecycle(
|
||||
descriptor.Id,
|
||||
|
|
@ -264,7 +267,10 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
internal string SessionId => _descriptor.Id;
|
||||
internal string ActiveCharacterName { get; private set; } =
|
||||
string.Empty;
|
||||
internal bool IsPolicyComplete => _policy.IsComplete;
|
||||
internal bool IsPolicyComplete =>
|
||||
_faulted || _policy.IsComplete;
|
||||
internal bool IsFaulted => _faulted;
|
||||
internal Exception? Fault => _fault;
|
||||
internal bool IsReconnectPending => _reconnectPending;
|
||||
internal HeadlessProcessContentOwner.HeadlessProcessContentLease?
|
||||
Content => _contentLease;
|
||||
|
|
@ -296,6 +302,42 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
internal RuntimeTeardownAcknowledgement Stop() =>
|
||||
Commands.Session.Stop(Runtime.Generation);
|
||||
|
||||
internal void Quarantine(Exception error)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(error);
|
||||
if (_faulted)
|
||||
return;
|
||||
|
||||
_faulted = true;
|
||||
_fault = error;
|
||||
_reconnectPending = false;
|
||||
_reconnectDeadline = 0L;
|
||||
_diagnostics.Failure(
|
||||
_descriptor.Id,
|
||||
"quarantined",
|
||||
error);
|
||||
try
|
||||
{
|
||||
// A policy may have faulted from an event callback. Detach it
|
||||
// before Runtime publishes teardown deltas so the quarantined
|
||||
// observer cannot poison the canonical stop transaction.
|
||||
_policySubscription.Dispose();
|
||||
RuntimeTeardownAcknowledgement stopped = Stop();
|
||||
if (!stopped.IsComplete)
|
||||
{
|
||||
_fault = new AggregateException(
|
||||
error,
|
||||
stopped.Error
|
||||
?? new InvalidOperationException(
|
||||
$"Headless session '{_descriptor.Id}' did not quiesce after a fault."));
|
||||
}
|
||||
}
|
||||
catch (Exception teardownError)
|
||||
{
|
||||
_fault = new AggregateException(error, teardownError);
|
||||
}
|
||||
}
|
||||
|
||||
internal RuntimeSessionStartResult CompletePendingReconnect(
|
||||
long nowTimestamp)
|
||||
{
|
||||
|
|
@ -482,13 +524,18 @@ internal sealed class HeadlessSessionHost : IDisposable
|
|||
private LiveSessionEventRouter CreateEventRoute(
|
||||
AcDream.Core.Net.WorldSession session)
|
||||
{
|
||||
IRuntimeDirectWorldProjection? worldProjection =
|
||||
_contentLease is { } content
|
||||
? new HeadlessSessionWorldProjection(Runtime, content)
|
||||
: null;
|
||||
var entities = new RuntimeLiveEntitySessionController(
|
||||
Runtime,
|
||||
session,
|
||||
message => _diagnostics.Message(
|
||||
_descriptor.Id,
|
||||
message,
|
||||
Runtime.Generation.Value));
|
||||
Runtime.Generation.Value),
|
||||
worldProjection);
|
||||
return new LiveSessionEventRouter(
|
||||
session,
|
||||
entities.CreateSink(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue