Route EveUnity live providers through generic client
This commit is contained in:
parent
f6c44d9d65
commit
d21cfecaf5
6 changed files with 93 additions and 6 deletions
|
|
@ -1021,7 +1021,13 @@ Recently cut:
|
|||
`AetheriaRuntimeVerseRecordKeys.DaemonAssetManifest` record, submits movement
|
||||
through the advertised `gamecult.eve.command.v1` boundary, observes
|
||||
provider-owned receipts, and refreshes from daemon snapshots without
|
||||
importing Aetheria product authority into EveUnity. Aetheria also proves the
|
||||
importing Aetheria product authority into EveUnity. The generic Unity
|
||||
document-source wrapper now connects live provider sources through
|
||||
`IEveUnitySceneProviderSurfaceDocumentConnection`, delegates provider refresh
|
||||
through `IEveUnityProviderRefreshSource`, `Connect()` is idempotent for the
|
||||
current snapshot, and `EveUnitySceneLiveProviderBridge` forwards receipts
|
||||
while `EveUnityPlayableWorldLiveClient` owns refresh-on-terminal receipt
|
||||
policy. Aetheria also proves the
|
||||
generic Unity scene body, not only a recording sink:
|
||||
`GenericEveUnityClientHostInstantiatesAetheriaDaemonWorldThroughProviderComponent`
|
||||
mounts the public provider component through `EveUnityPlayableWorldClientHost`,
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ namespace GameCult.Eve.UnityScene
|
|||
public sealed class EveUnitySceneLiveProviderBridgeComponent :
|
||||
MonoBehaviour,
|
||||
IEveUnitySceneProviderSurfaceDocumentSource,
|
||||
IEveUnitySceneProviderSurfaceDocumentConnection,
|
||||
IEveUnityPlayableWorldAssetManifestDocumentSource,
|
||||
IEveUnitySceneCommandSink,
|
||||
IEveUnitySceneCommandReceiptSource,
|
||||
|
|
@ -179,6 +180,7 @@ namespace GameCult.Eve.UnityScene
|
|||
|
||||
public sealed class EveUnitySceneLiveProviderBridge :
|
||||
IEveUnitySceneProviderSurfaceDocumentSource,
|
||||
IEveUnitySceneProviderSurfaceDocumentConnection,
|
||||
IEveUnityPlayableWorldAssetManifestDocumentSource,
|
||||
IEveUnitySceneCommandSink,
|
||||
IEveUnitySceneCommandReceiptSource,
|
||||
|
|
@ -282,8 +284,6 @@ namespace GameCult.Eve.UnityScene
|
|||
private void OnCommandReceiptAvailable(EveUnitySceneCommandReceipt receipt)
|
||||
{
|
||||
if (receipt == null) throw new ArgumentNullException(nameof(receipt));
|
||||
if (receipt.ShouldRefreshProviderSurface)
|
||||
_transport.Refresh();
|
||||
ReceiptAvailable?.Invoke(receipt);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ namespace GameCult.Eve.UnityScene
|
|||
|
||||
void Connect();
|
||||
|
||||
void Refresh();
|
||||
|
||||
void Disconnect();
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +38,13 @@ namespace GameCult.Eve.UnityScene
|
|||
event Action<EveUnitySceneProviderSurfaceDocument> DocumentAvailable;
|
||||
}
|
||||
|
||||
public interface IEveUnitySceneProviderSurfaceDocumentConnection
|
||||
{
|
||||
void Connect();
|
||||
|
||||
void Disconnect();
|
||||
}
|
||||
|
||||
public sealed class EveUnitySceneProviderSurfaceDocument
|
||||
{
|
||||
public EveUnitySceneProviderSurfaceDocument(
|
||||
|
|
@ -71,12 +80,16 @@ namespace GameCult.Eve.UnityScene
|
|||
public sealed class EveUnitySceneProviderSurfaceDocumentSource : IEveUnitySceneProviderSurfaceSource, IDisposable
|
||||
{
|
||||
private readonly IEveUnitySceneProviderSurfaceDocumentSource _documentSource;
|
||||
private readonly IEveUnitySceneProviderSurfaceDocumentConnection? _documentConnection;
|
||||
private readonly IEveUnityProviderRefreshSource? _refreshSource;
|
||||
private bool _connected;
|
||||
|
||||
public EveUnitySceneProviderSurfaceDocumentSource(
|
||||
IEveUnitySceneProviderSurfaceDocumentSource documentSource)
|
||||
{
|
||||
_documentSource = documentSource ?? throw new ArgumentNullException(nameof(documentSource));
|
||||
_documentConnection = documentSource as IEveUnitySceneProviderSurfaceDocumentConnection;
|
||||
_refreshSource = documentSource as IEveUnityProviderRefreshSource;
|
||||
CurrentSnapshot = _documentSource.CurrentDocument.ToSnapshot();
|
||||
}
|
||||
|
||||
|
|
@ -96,14 +109,21 @@ namespace GameCult.Eve.UnityScene
|
|||
return;
|
||||
|
||||
_documentSource.DocumentAvailable += OnDocumentAvailable;
|
||||
_documentConnection?.Connect();
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
_refreshSource?.Refresh();
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
if (!_connected)
|
||||
return;
|
||||
|
||||
_documentConnection?.Disconnect();
|
||||
_documentSource.DocumentAvailable -= OnDocumentAvailable;
|
||||
_connected = false;
|
||||
}
|
||||
|
|
@ -166,11 +186,18 @@ namespace GameCult.Eve.UnityScene
|
|||
_connected = true;
|
||||
}
|
||||
|
||||
if (HasAppliedCurrentSnapshot())
|
||||
return _session.ActiveProjection!;
|
||||
|
||||
return ApplySnapshot(_surfaceSource.CurrentSnapshot);
|
||||
}
|
||||
|
||||
public EveUnitySceneProjection Refresh()
|
||||
{
|
||||
_surfaceSource.Refresh();
|
||||
if (HasAppliedCurrentSnapshot())
|
||||
return _session.ActiveProjection!;
|
||||
|
||||
return ApplySnapshot(_surfaceSource.CurrentSnapshot);
|
||||
}
|
||||
|
||||
|
|
@ -245,6 +272,17 @@ namespace GameCult.Eve.UnityScene
|
|||
return projection;
|
||||
}
|
||||
|
||||
private bool HasAppliedCurrentSnapshot()
|
||||
{
|
||||
var projection = _session.ActiveProjection;
|
||||
if (projection == null)
|
||||
return false;
|
||||
|
||||
var snapshot = _surfaceSource.CurrentSnapshot;
|
||||
return _session.ActiveVersion == snapshot.Version &&
|
||||
string.Equals(_session.ActiveSourcePointer, snapshot.SourcePointer, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private void OnSnapshotAvailable(EveUnitySceneProviderSurfaceSnapshot snapshot)
|
||||
{
|
||||
ApplySnapshot(snapshot);
|
||||
|
|
|
|||
|
|
@ -372,7 +372,6 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
using var bridge = new EveUnitySceneLiveProviderBridge(transport);
|
||||
var sceneSink = new FakePlayableWorldSceneSink();
|
||||
|
||||
bridge.Connect();
|
||||
using var runtime = new EveUnityPlayableWorldRuntime(
|
||||
bridge,
|
||||
bridge,
|
||||
|
|
@ -1407,6 +1406,10 @@ namespace GameCult.Eve.UnityScene.Tests
|
|||
{
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ $aetheriaGameSurfaceBuilder = Join-Path $AetheriaRoot "Packages\org.gamecult.aet
|
|||
$aetheriaDaemonOperationsClient = Join-Path $AetheriaRoot "Packages\org.gamecult.aetheria.state\Runtime\AetheriaRuntimeDaemonOperationsClient.cs"
|
||||
$aetheriaDaemonDocuments = Join-Path $AetheriaRoot "Packages\org.gamecult.aetheria.state\Runtime\AetheriaRuntimeDaemonDocuments.cs"
|
||||
$aetheriaRuntimeVerseClient = Join-Path $AetheriaRoot "Packages\org.gamecult.aetheria.state\Runtime\AetheriaRuntimeVerseClient.cs"
|
||||
$eveUnitySceneProviderConnection = Join-Path $eveRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnitySceneProviderConnection.cs"
|
||||
$eveUnitySceneLiveProviderBridge = Join-Path $eveRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnitySceneLiveProviderBridge.cs"
|
||||
if (-not (Test-Path $manifestPath)) {
|
||||
throw "Aetheria Unity package manifest not found: $manifestPath"
|
||||
}
|
||||
|
|
@ -69,6 +71,12 @@ if (-not (Test-Path $aetheriaDaemonDocuments)) {
|
|||
if (-not (Test-Path $aetheriaRuntimeVerseClient)) {
|
||||
throw "Aetheria runtime Verse client not found: $aetheriaRuntimeVerseClient"
|
||||
}
|
||||
if (-not (Test-Path $eveUnitySceneProviderConnection)) {
|
||||
throw "EveUnity scene provider connection not found: $eveUnitySceneProviderConnection"
|
||||
}
|
||||
if (-not (Test-Path $eveUnitySceneLiveProviderBridge)) {
|
||||
throw "EveUnity scene live provider bridge not found: $eveUnitySceneLiveProviderBridge"
|
||||
}
|
||||
|
||||
$manifest = Get-Content -Raw -LiteralPath $manifestPath | ConvertFrom-Json
|
||||
$requiredDependencies = @{
|
||||
|
|
@ -120,6 +128,35 @@ foreach ($compileItem in $requiredSceneCompileItems) {
|
|||
}
|
||||
}
|
||||
|
||||
$sceneProviderConnection = Get-Content -Raw -LiteralPath $eveUnitySceneProviderConnection
|
||||
foreach ($symbol in @(
|
||||
"IEveUnitySceneProviderSurfaceDocumentConnection",
|
||||
"_documentConnection?.Connect();",
|
||||
"_documentConnection?.Disconnect();",
|
||||
"_refreshSource?.Refresh();",
|
||||
"HasAppliedCurrentSnapshot()",
|
||||
"_session.ActiveSourcePointer"
|
||||
)) {
|
||||
if (-not $sceneProviderConnection.Contains($symbol)) {
|
||||
throw "EveUnity scene provider connection missing live-source lifecycle symbol: $symbol"
|
||||
}
|
||||
}
|
||||
|
||||
$sceneLiveProviderBridge = Get-Content -Raw -LiteralPath $eveUnitySceneLiveProviderBridge
|
||||
foreach ($symbol in @(
|
||||
"IEveUnitySceneProviderSurfaceDocumentConnection",
|
||||
"IEveUnitySceneLiveProviderTransport",
|
||||
"CommandReceiptAvailable += OnCommandReceiptAvailable",
|
||||
"ReceiptAvailable?.Invoke(receipt);"
|
||||
)) {
|
||||
if (-not $sceneLiveProviderBridge.Contains($symbol)) {
|
||||
throw "EveUnity scene live provider bridge missing transport receipt/lifecycle symbol: $symbol"
|
||||
}
|
||||
}
|
||||
if ($sceneLiveProviderBridge.Contains("if (receipt.ShouldRefreshProviderSurface)")) {
|
||||
throw "EveUnity scene live provider bridge must forward receipts; playable-world live client owns refresh policy"
|
||||
}
|
||||
|
||||
$runtimePackage = Get-Content -Raw -LiteralPath $aetheriaEveRuntimePackage
|
||||
foreach ($dependency in @(
|
||||
'"org.gamecult.eve.unity-scene": "0.1.0"',
|
||||
|
|
|
|||
|
|
@ -106,14 +106,14 @@ foreach ($symbol in @("EveUnitySceneClientSession", "EveUnitySceneProviderSurfac
|
|||
}
|
||||
|
||||
$providerConnectionSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnitySceneProviderConnection.cs") -Raw
|
||||
foreach ($symbol in @("IEveUnitySceneProviderSurfaceSource", "IEveUnitySceneCommandSink", "IEveUnitySceneProviderSurfaceDocumentSource", "EveUnitySceneProviderSurfaceDocument", "EveUnitySceneProviderSurfaceDocumentSource", "ToSnapshot", "DocumentAvailable", "EveUnitySceneProviderConnection", "SnapshotAvailable", "CurrentSnapshot", "Connect", "Refresh", "SubmitMoveIntent", "SubmitMoveVectorIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Disconnect")) {
|
||||
foreach ($symbol in @("IEveUnitySceneProviderSurfaceSource", "IEveUnitySceneCommandSink", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnitySceneProviderSurfaceDocumentConnection", "IEveUnityProviderRefreshSource", "EveUnitySceneProviderSurfaceDocument", "EveUnitySceneProviderSurfaceDocumentSource", "ToSnapshot", "DocumentAvailable", "EveUnitySceneProviderConnection", "SnapshotAvailable", "CurrentSnapshot", "Connect", "Refresh", "_refreshSource?.Refresh();", "SubmitMoveIntent", "SubmitMoveVectorIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Disconnect", "HasAppliedCurrentSnapshot")) {
|
||||
if (-not $providerConnectionSource.Contains($symbol)) {
|
||||
throw "EveUnity scene provider connection missing symbol: $symbol"
|
||||
}
|
||||
}
|
||||
|
||||
$liveProviderBridgeSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnitySceneLiveProviderBridge.cs") -Raw
|
||||
foreach ($symbol in @("IEveUnitySceneLiveProviderTransport", "EveUnitySceneLiveProviderTransportBehaviour", "EveUnitySceneLiveProviderBridgeComponent", "EveUnitySceneLiveProviderBridge", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnityPlayableWorldAssetManifestDocumentSource", "IEveUnitySceneCommandSink", "IEveUnitySceneCommandReceiptSource", "IEveUnityProviderRefreshSource", "SubmitCommand", "CommandReceiptAvailable", "ShouldRefreshProviderSurface", "transportBehaviour")) {
|
||||
foreach ($symbol in @("IEveUnitySceneLiveProviderTransport", "EveUnitySceneLiveProviderTransportBehaviour", "EveUnitySceneLiveProviderBridgeComponent", "EveUnitySceneLiveProviderBridge", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnitySceneProviderSurfaceDocumentConnection", "IEveUnityPlayableWorldAssetManifestDocumentSource", "IEveUnitySceneCommandSink", "IEveUnitySceneCommandReceiptSource", "IEveUnityProviderRefreshSource", "SubmitCommand", "CommandReceiptAvailable", "ReceiptAvailable?.Invoke(receipt);", "transportBehaviour")) {
|
||||
if (-not $liveProviderBridgeSource.Contains($symbol)) {
|
||||
throw "EveUnity scene live provider bridge missing symbol: $symbol"
|
||||
}
|
||||
|
|
@ -121,6 +121,9 @@ foreach ($symbol in @("IEveUnitySceneLiveProviderTransport", "EveUnitySceneLiveP
|
|||
if ($liveProviderBridgeSource.Contains("Aetheria")) {
|
||||
throw "EveUnity scene live provider bridge must remain provider-agnostic and cannot reference Aetheria"
|
||||
}
|
||||
if ($liveProviderBridgeSource.Contains("if (receipt.ShouldRefreshProviderSurface)")) {
|
||||
throw "EveUnity scene live provider bridge must forward receipts; playable-world live client owns refresh policy"
|
||||
}
|
||||
|
||||
$liveClientSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldLiveClient.cs") -Raw
|
||||
foreach ($symbol in @("EveUnityPlayableWorldLiveClient", "IEveUnitySceneCommandReceiptSource", "EveUnitySceneCommandReceipt", "EveUnitySceneProviderConnection", "EveUnityPlayableWorldPresenter", "ActiveWorld", "LastPresentation", "LastReceipt", "ReceiptAvailable", "Connect", "Refresh", "SubmitMoveIntent", "SubmitMoveVectorIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "ProjectionUpdated", "ShouldRefreshProviderSurface", "IsProviderOwned", "Disconnect")) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue