diff --git a/packages/org.gamecult.eve.unity-scene/Runtime/CultMesh/EveUnityCultMeshLiveProviderTransport.cs b/packages/org.gamecult.eve.unity-scene/Runtime/CultMesh/EveUnityCultMeshLiveProviderTransport.cs index df20364..00d567f 100644 --- a/packages/org.gamecult.eve.unity-scene/Runtime/CultMesh/EveUnityCultMeshLiveProviderTransport.cs +++ b/packages/org.gamecult.eve.unity-scene/Runtime/CultMesh/EveUnityCultMeshLiveProviderTransport.cs @@ -63,6 +63,7 @@ namespace GameCult.Eve.UnityScene private CultNetShardDescriptor? _replicaShard; private CultNetDatabaseSubscriptionClient? _subscriptions; private CultNetDatabaseSubscriptionClient? _entitySubscriptions; + private CultNetLiveValue? _inputCapability; private CultMeshClient? _meshClient; private CultMeshContentTransferService? _contentTransfer; private CultMeshVerifiedBodyMappingBroker? _assetBodyMappings; @@ -172,28 +173,10 @@ namespace GameCult.Eve.UnityScene ResolveAdvertisement(forceRefresh: true); RefreshSurface(); - RefreshInputCapability(); RefreshAssetCatalog(); _bootstrapped = true; } - private void RefreshInputCapability() - { - var recordRef = FindComponentProp( - CurrentSurfaceDocument.SurfaceDocument.Surface.Root, - "inputCapability"); - if (string.IsNullOrWhiteSpace(recordRef)) - throw new InvalidOperationException("The advertised playable world does not publish an input capability record."); - CurrentInputCapability = _snapshot! - .FetchDocumentsAsync( - recordKeys: new[] { recordRef }, - schemaIds: new[] { EveInputCapabilityDocument.SchemaId }) - .GetAwaiter() - .GetResult() - .FirstOrDefault() - ?? throw new InvalidOperationException($"The advertised input capability '{recordRef}' was not available."); - } - private static string FindComponentProp(EveSurfaceComponent component, string key) { var value = component.GetProp(key); @@ -231,6 +214,8 @@ namespace GameCult.Eve.UnityScene PublishAssetCatalog(assetCatalog); else if (document is EveCommandReceiptDocument receipt) PublishReceipt(receipt); + else if (document is Exception error) + throw error; } PumpMappedEntityFrame(); } @@ -386,6 +371,8 @@ namespace GameCult.Eve.UnityScene _mappedEntityFrameCursor?.Dispose(); _mappedEntityFrameCursor = null; _mappedEntityFrameContract = null; + _inputCapability?.Dispose(); + _inputCapability = null; _subscriptions?.Dispose(); _entitySubscriptions?.Dispose(); _node?.Dispose(); @@ -819,6 +806,8 @@ namespace GameCult.Eve.UnityScene private void EnsureLiveSubscriptions() { if (_subscriptions != null && _entitySubscriptions != null) return; + _inputCapability?.Dispose(); + _inputCapability = null; _subscriptions?.Dispose(); _entitySubscriptions?.Dispose(); _subscriptions = null; @@ -830,6 +819,8 @@ namespace GameCult.Eve.UnityScene } catch { + _inputCapability?.Dispose(); + _inputCapability = null; _subscriptions?.Dispose(); _entitySubscriptions?.Dispose(); _subscriptions = null; @@ -926,13 +917,15 @@ namespace GameCult.Eve.UnityScene "inputCapability"); if (!string.IsNullOrWhiteSpace(inputCapabilityRef)) { - _subscriptions.SubscribeAsync( + _inputCapability = _subscriptions + .SubscribeLiveValueAsync( "eve-unity-input-capability", - recordKeys: new[] { inputCapabilityRef }, - schemaIds: new[] { EveInputCapabilityDocument.SchemaId }, - includeSnapshot: false, - deliveryMode: CultNetDatabaseSubscriptionDeliveryMode.Live) + inputCapabilityRef) .GetAwaiter().GetResult(); + CurrentInputCapability = _inputCapability.Current; + _inputCapability.Changed += document => _liveDocuments.Enqueue(document); + _inputCapability.Removed += () => _liveDocuments.Enqueue(new InvalidOperationException( + $"The provider withdrew required input capability '{inputCapabilityRef}'.")); } var assetCatalogRef = RequireWorldInteraction().AssetManifestRecordRef; if (!string.IsNullOrWhiteSpace(assetCatalogRef)) @@ -977,8 +970,8 @@ namespace GameCult.Eve.UnityScene QueueBodyPublication(publication); else if (change.Document is EveSurfaceDocument surface) _liveDocuments.Enqueue(new PendingSurfaceDocument(change.RecordKey, surface)); - else if (change.Document is EveInputCapabilityDocument or - EveAssetCatalogDocument or EveCommandReceiptDocument or EveFieldsSplatsDocument) + else if (change.Document is EveAssetCatalogDocument or + EveCommandReceiptDocument or EveFieldsSplatsDocument) _liveDocuments.Enqueue(change.Document); } diff --git a/packages/org.gamecult.eve.unity-scene/package.json b/packages/org.gamecult.eve.unity-scene/package.json index c387d69..7b087e2 100644 --- a/packages/org.gamecult.eve.unity-scene/package.json +++ b/packages/org.gamecult.eve.unity-scene/package.json @@ -1,11 +1,11 @@ { "name": "org.gamecult.eve.unity-scene", "displayName": "Eve Unity Scene Lowering", - "version": "0.3.84", + "version": "0.3.85", "unity": "6000.0", "description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.", "dependencies": { - "org.gamecult.cultlib": "1.0.26", + "org.gamecult.cultlib": "1.0.27", "org.gamecult.eve.plugin-fields": "0.2.3", "org.gamecult.eve.surface": "0.2.4", "com.unity.mathematics": "1.3.2",