Hide raw reactive docs behind Unity handles

This commit is contained in:
Meta Vens 2026-06-29 13:12:23 +01:00
commit 932cc9f906
3 changed files with 43 additions and 31 deletions

View file

@ -16283,6 +16283,10 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
var unityDaemonRenderDocuments = File.Exists(unityDaemonRenderDocumentsPath)
? File.ReadAllText(unityDaemonRenderDocumentsPath)
: throw new InvalidOperationException("Cannot verify daemon state acquisition; AetheriaUnityDaemonRenderDocuments.cs is missing.");
var unityRtsViewportDocumentsPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityRtsViewportDocuments.cs");
var unityRtsViewportDocuments = File.Exists(unityRtsViewportDocumentsPath)
? File.ReadAllText(unityRtsViewportDocumentsPath)
: throw new InvalidOperationException("Cannot verify daemon state acquisition; AetheriaUnityRtsViewportDocuments.cs is missing.");
var zoneRendererPath = Path.Combine(root, "Assets", "Scripts", "Zone Display", "ZoneRenderer.cs");
var zoneRenderer = File.Exists(zoneRendererPath)
? File.ReadAllText(zoneRendererPath)
@ -16543,9 +16547,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
!observedDaemonState.Contains("var currentZoneRender = zoneRender?.Current;", StringComparison.Ordinal) ||
!observedDaemonState.Contains("new AetheriaRuntimeDaemonRenderView(currentFrame, currentSoaView, currentZoneRender)", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public sealed class AetheriaUnityDaemonRenderDocuments : IDisposable", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> Frame { get; }", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> SoaView { get; }", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> ZoneRender { get; }", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("private readonly CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> _frame;", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("private readonly CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> _soaView;", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("private readonly CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> _zoneRender;", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public AetheriaRuntimeDaemonRenderView Current", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("AetheriaRuntimeDaemonRenderView.TryCreateCurrent(", StringComparison.Ordinal) ||
!daemonObserver.Contains("private AetheriaUnityDaemonRenderDocuments _renderDocuments;", StringComparison.Ordinal) ||
@ -16556,6 +16560,13 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
"Observed zone-render state acquisition must sample managed typed zone-render documents directly.");
}
if (unityDaemonRenderDocuments.Contains("public CultMeshReactiveDocument<", StringComparison.Ordinal) ||
unityRtsViewportDocuments.Contains("public CultMeshReactiveDocument<", StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Unity managed document holders must not leak raw CultMesh reactive documents through their public surface.");
}
var requiredDaemonStateFacadeSymbols = new[]
{
"public CultMeshDocumentHandle<AetheriaRuntimeDaemonProviderAdvertisementDocument> ProviderAdvertisement { get; }",
@ -16914,9 +16925,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
!daemonObserver.Contains("_renderDocuments?.Current", StringComparison.Ordinal) ||
!daemonObserver.Contains("AetheriaUnityRuntimeClientProvider.DaemonRenderDocuments(stateBoot, clientId)", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public AetheriaRuntimeDaemonRenderView Current", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> Frame { get; }", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> SoaView { get; }", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("public CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> ZoneRender { get; }", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("private readonly CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> _frame;", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("private readonly CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> _soaView;", StringComparison.Ordinal) ||
!unityDaemonRenderDocuments.Contains("private readonly CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> _zoneRender;", StringComparison.Ordinal) ||
!daemonObserver.Contains("DisposeRenderViewDocuments()", StringComparison.Ordinal))
{
throw new InvalidOperationException(

View file

@ -4,20 +4,20 @@ using GameCult.Mesh;
public sealed class AetheriaUnityDaemonRenderDocuments : IDisposable
{
private readonly CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> _frame;
private readonly CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> _soaView;
private readonly CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> _zoneRender;
private AetheriaUnityDaemonRenderDocuments(AetheriaClientState state)
{
if (state == null)
throw new ArgumentNullException(nameof(state));
Frame = state.ReactiveDaemonFrame();
SoaView = state.ReactiveDaemonSoaView();
ZoneRender = state.ReactiveZoneRender();
_frame = state.ReactiveDaemonFrame();
_soaView = state.ReactiveDaemonSoaView();
_zoneRender = state.ReactiveZoneRender();
}
public CultMeshReactiveDocument<AetheriaRuntimeDaemonFrameDocument> Frame { get; }
public CultMeshReactiveDocument<AetheriaRuntimeDaemonSoaViewDocument> SoaView { get; }
public CultMeshReactiveDocument<AetheriaRuntimeZoneRenderDocument> ZoneRender { get; }
public AetheriaRuntimeDaemonRenderView Current =>
TryRead(out var observed) ? observed : null;
@ -29,16 +29,16 @@ public sealed class AetheriaUnityDaemonRenderDocuments : IDisposable
public bool TryRead(out AetheriaRuntimeDaemonRenderView observed)
{
return AetheriaRuntimeDaemonRenderView.TryCreateCurrent(
Frame,
SoaView,
ZoneRender,
_frame,
_soaView,
_zoneRender,
out observed);
}
public void Dispose()
{
Frame?.Dispose();
SoaView?.Dispose();
ZoneRender?.Dispose();
_frame?.Dispose();
_soaView?.Dispose();
_zoneRender?.Dispose();
}
}

View file

@ -4,6 +4,10 @@ using GameCult.Mesh;
public sealed class AetheriaUnityRtsViewportDocuments : IDisposable
{
private readonly CultMeshReactiveDocument<AetheriaRuntimeZoneContactsDocument> _contacts;
private readonly CultMeshReactiveDocument<AetheriaRuntimeObjectsViewportDocument> _objectsViewport;
private readonly CultMeshReactiveDocument<AetheriaRuntimeRenderSplatsViewportDocument> _renderSplatsViewport;
private AetheriaUnityRtsViewportDocuments(
AetheriaClientState state,
AetheriaRuntimeRtsViewportBounds viewport,
@ -17,19 +21,16 @@ public sealed class AetheriaUnityRtsViewportDocuments : IDisposable
throw new ArgumentNullException(nameof(viewport));
Viewport = viewport;
Contacts = bindContacts ? state.ReactiveZoneContacts() : null;
ObjectsViewport = bindObjects ? state.ReactiveObjectsViewport(viewport) : null;
RenderSplatsViewport = bindRenderSplats ? state.ReactiveRenderSplatsViewport(viewport) : null;
_contacts = bindContacts ? state.ReactiveZoneContacts() : null;
_objectsViewport = bindObjects ? state.ReactiveObjectsViewport(viewport) : null;
_renderSplatsViewport = bindRenderSplats ? state.ReactiveRenderSplatsViewport(viewport) : null;
}
public AetheriaRuntimeRtsViewportBounds Viewport { get; }
public CultMeshReactiveDocument<AetheriaRuntimeZoneContactsDocument> Contacts { get; }
public CultMeshReactiveDocument<AetheriaRuntimeObjectsViewportDocument> ObjectsViewport { get; }
public CultMeshReactiveDocument<AetheriaRuntimeRenderSplatsViewportDocument> RenderSplatsViewport { get; }
public AetheriaRuntimeZoneContactsDocument CurrentContacts => Contacts?.Current;
public AetheriaRuntimeObjectsViewportDocument CurrentObjectsViewport => ObjectsViewport?.Current;
public AetheriaRuntimeRenderSplatsViewportDocument CurrentRenderSplatsViewport => RenderSplatsViewport?.Current;
public AetheriaRuntimeZoneContactsDocument CurrentContacts => _contacts?.Current;
public AetheriaRuntimeObjectsViewportDocument CurrentObjectsViewport => _objectsViewport?.Current;
public AetheriaRuntimeRenderSplatsViewportDocument CurrentRenderSplatsViewport => _renderSplatsViewport?.Current;
public static AetheriaUnityRtsViewportDocuments OpenMap(
AetheriaClientState state,
@ -74,9 +75,9 @@ public sealed class AetheriaUnityRtsViewportDocuments : IDisposable
public void Dispose()
{
Contacts?.Dispose();
ObjectsViewport?.Dispose();
RenderSplatsViewport?.Dispose();
_contacts?.Dispose();
_objectsViewport?.Dispose();
_renderSplatsViewport?.Dispose();
}
public static bool SameViewport(