Keep navigation connections bound through presentation teardown

This commit is contained in:
Meta Vens 2026-08-19 02:17:56 +02:00
commit abfbb122ee
4 changed files with 33 additions and 3 deletions

View file

@ -38,6 +38,11 @@ main thread applies completed typed documents and assets; it never waits for a
CultMesh task, keeping Play, Pause, input, inspection, and rendering responsive
while a provider is slow or temporarily unreachable.
Navigation keeps the outgoing presentation quiesced until the candidate route
is ready, then commits the provider route before activating the candidate.
Presentation connections are provider-owned leases: disposing the outgoing
host releases only its lease and cannot disconnect the newly committed Verse.
The package never imports provider product assemblies.
Add `EveUnityRendererFeature` to the Universal Renderer used by Eve cameras.

View file

@ -49,6 +49,7 @@ namespace GameCult.Eve.UnityScene
private EveUnitySceneLiveProviderBridge? _bridge;
private PreviousProvider? _previousProvider;
private bool _navigationRouteCommitted;
private int _connectionLeaseCount;
private Task? _preparation;
private CancellationTokenSource? _preparationLifetime;
private readonly ConcurrentQueue<EntityViewLease> _pendingEntityViews = new ConcurrentQueue<EntityViewLease>();
@ -114,7 +115,10 @@ namespace GameCult.Eve.UnityScene
public void Connect()
{
// During navigation the candidate presentation connects before the route
// becomes canonical, so every new lease must connect its selected bridge.
Bridge.Connect();
checked { _connectionLeaseCount++; }
}
public Task PrepareAsync()
@ -132,7 +136,11 @@ namespace GameCult.Eve.UnityScene
public void Disconnect()
{
_bridge?.Disconnect();
if (_connectionLeaseCount <= 0)
return;
_connectionLeaseCount--;
if (_connectionLeaseCount == 0)
_bridge?.Disconnect();
}
public async Task NavigateAsync(EveUnitySceneNavigationTarget target)
@ -289,6 +297,7 @@ namespace GameCult.Eve.UnityScene
_previousProvider?.Transport?.Dispose();
_previousProvider = null;
_navigationRouteCommitted = false;
_connectionLeaseCount = 0;
while (_pendingEntityViews.TryDequeue(out var pending)) pending.Lease.Dispose();
while (_pendingFields.TryDequeue(out _)) { }
_bridge = null;

View file

@ -1222,6 +1222,8 @@ namespace GameCult.Eve.UnityScene.Tests
Assert.That(provider.CommitNavigationCount, Is.EqualTo(2));
Assert.That(provider.FinalizeNavigationCount, Is.EqualTo(2));
Assert.That(provider.ActiveConnectionLeases, Is.EqualTo(1),
"disposing superseded presentations must leave the committed Verse connected");
Assert.That(hostObject.transform.Cast<Transform>()
.Count(child => child.name == "Eve Unity Candidate Presentation"), Is.EqualTo(1));
}
@ -3433,6 +3435,7 @@ namespace GameCult.Eve.UnityScene.Tests
IEveUnitySceneCommandReceiptSource,
IEveUnityProviderRefreshSource,
IEveUnityInputCapabilitySource,
IEveUnitySceneProviderSurfaceDocumentConnection,
IEveUnityNavigableProvider
{
public List<EveSurfaceCommandRequest> Submitted { get; } = new List<EveSurfaceCommandRequest>();
@ -3451,6 +3454,8 @@ namespace GameCult.Eve.UnityScene.Tests
public bool FailNextNavigationFinalize { get; set; }
public int ActiveConnectionLeases { get; private set; }
public string ActiveRoute { get; private set; } = "original";
public List<string> RoutesObservedDuringReactivation { get; } = new List<string>();
@ -3529,6 +3534,17 @@ namespace GameCult.Eve.UnityScene.Tests
return Task.CompletedTask;
}
public void Connect()
{
ActiveConnectionLeases++;
}
public void Disconnect()
{
if (ActiveConnectionLeases > 0)
ActiveConnectionLeases--;
}
public void CommitNavigation()
{
CommitNavigationCount++;

View file

@ -1,11 +1,11 @@
{
"name": "org.gamecult.eve.unity-scene",
"displayName": "Eve Unity Scene Lowering",
"version": "0.3.117",
"version": "0.3.118",
"unity": "6000.0",
"description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.",
"dependencies": {
"org.gamecult.cultlib": "1.0.54",
"org.gamecult.cultlib": "1.0.55",
"org.gamecult.eve.plugin-fields": "0.2.3",
"org.gamecult.eve.surface": "0.3.3",
"org.gamecult.eve.unity-uitoolkit": "0.1.6",