From 5299dcb184af9733ca28c0daf05a7cfbddb99bfe Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 29 Jun 2026 03:09:13 +0100 Subject: [PATCH] Use CultMesh state refs for Eve surfaces --- Aetheria.State.Verify/Program.cs | 24 +++++++-------- .../Tests/DaemonRuntimeDocumentTests.cs | 16 +++++----- .../Runtime/AetheriaEveSurfacePresenter.cs | 4 +-- .../Runtime/AetheriaEveUnitySurfaceHost.cs | 11 +++---- .../Runtime/AetheriaClientState.cs | 5 ---- .../AetheriaRuntimeEveSurfaceAdapter.cs | 29 ++++++++++--------- 6 files changed, 44 insertions(+), 45 deletions(-) diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 16e7b6c99..be501a9ee 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -5239,15 +5239,15 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root) !daemonItemStatQueries.Contains("public static bool TryReadItemStatRef(", StringComparison.Ordinal) || !daemonItemStatQueries.Contains("public string ValueRef =>", StringComparison.Ordinal) || !unityProject.Contains("AetheriaRuntimeDaemonItemStatQueries.cs", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("Func stateRefResolver", StringComparison.Ordinal) || + !eveUnitySurfaceHost.Contains("CultMeshStateRefResolver stateRefResolver", StringComparison.Ordinal) || !eveUnitySurfaceHost.Contains("ContainsStateRefs(surface)", StringComparison.Ordinal) || !eveUnitySurfaceHost.Contains("prop.Key.EndsWith(\"Ref\", StringComparison.Ordinal)", StringComparison.Ordinal) || !eveUnitySurfaceHost.Contains("CreateDefaultStateRefResolver()", StringComparison.Ordinal) || !eveUnitySurfaceHost.Contains("AetheriaUnityRuntimeClientProvider", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains(".CreateEveSurfaceStateRefResolver()", StringComparison.Ordinal) || + !eveUnitySurfaceHost.Contains(".CreateEveSurfaceCultMeshStateRefResolver()", StringComparison.Ordinal) || !runtimeEveSurfaceAdapter.Contains("public static EveSurfaceDocument ResolveStateRefs(", StringComparison.Ordinal) || - !runtimeEveSurfaceAdapter.Contains("ResolvePropRefs(props, stateRefResolver)", StringComparison.Ordinal) || - !runtimeEveSurfaceAdapter.Contains("ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", stateRefResolver)", StringComparison.Ordinal) || + !runtimeEveSurfaceAdapter.Contains("ResolvePropRefs(props, resolveStateRef)", StringComparison.Ordinal) || + !runtimeEveSurfaceAdapter.Contains("ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", resolveStateRef)", StringComparison.Ordinal) || !runtimeEveSurfaceAdapter.Contains("IsStatePointerProp(prop.Key)", StringComparison.Ordinal) || !runtimeEveSurfaceAdapter.Contains("ResolvePointerValueKey(refProp.Key)", StringComparison.Ordinal) || !cargoItemSurfaceBuilder.Contains("public string ValueRef { get; }", StringComparison.Ordinal) || @@ -11954,7 +11954,6 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) var requiredClientStateSymbols = new[] { - "public Func CreateEveSurfaceStateRefResolver()", "public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()", "public sealed class AetheriaClientState : IDisposable", "CultMeshReactiveDocument? _eveStateRefFrame", @@ -15789,8 +15788,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "public static class AetheriaRuntimeEveSurfaceAdapter", "public static EveSurfaceDocument ToEveSurfaceDocument(AetheriaRuntimeSurfaceDocument document)", "public static EveSurfaceDocument ResolveStateRefs(", - "ResolvePropRefs(props, stateRefResolver)", - "ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", stateRefResolver)", + "CultMeshStateRefResolver? stateRefResolver", + "ResolvePropRefs(props, resolveStateRef)", + "ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", resolveStateRef)", "IsStatePointerProp(prop.Key)", "ResolvePointerValueKey(refProp.Key)", "public static EveSurfaceDocument EmptySurface(string surfaceId)", @@ -16356,7 +16356,6 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "public async Task DaemonGameTuiSurfaceAsync()", "public async Task DaemonEditorSurfaceAsync()", "public async Task DaemonEditorTuiSurfaceAsync()", - "public Func CreateEveSurfaceStateRefResolver()", "public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()", "public CultMeshDocumentHandle Document()", "public Observable Watch()", @@ -16521,8 +16520,8 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "Aetheria Eve surface presenter no longer routes daemon surface lookup through the shared AetheriaClient facade."); } - if (!eveSurfacePresenter.Contains("client.State.CreateEveSurfaceStateRefResolver()", StringComparison.Ordinal) || - !eveSurfacePresenter.Contains("ResolveClient(statePath).State.CreateEveSurfaceStateRefResolver()", StringComparison.Ordinal)) + if (!eveSurfacePresenter.Contains("client.State.CreateEveSurfaceCultMeshStateRefResolver()", StringComparison.Ordinal) || + !eveSurfacePresenter.Contains("ResolveClient(statePath).State.CreateEveSurfaceCultMeshStateRefResolver()", StringComparison.Ordinal)) { throw new InvalidOperationException( "Aetheria Eve surface presenter no longer resolves provider state refs through managed AetheriaClientState documents."); @@ -16547,10 +16546,11 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) } if (aetheriaClientState.Contains("AetheriaRuntimeStateReader.CreateEveSurfaceCultMeshStateRefResolver", StringComparison.Ordinal) || - aetheriaClientState.Contains("AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver", StringComparison.Ordinal)) + aetheriaClientState.Contains("AetheriaRuntimeStateReader.CreateEveSurfaceStateRefResolver", StringComparison.Ordinal) || + aetheriaClientState.Contains("public Func CreateEveSurfaceStateRefResolver()", StringComparison.Ordinal)) { throw new InvalidOperationException( - "Managed client state still routes Eve state-ref resolution through the file-backed compatibility reader."); + "Managed client state still routes or exposes Eve state-ref resolution through file-backed/delegate compatibility."); } var forbiddenDirectStoreSymbols = new Dictionary diff --git a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs index 413661609..4cfe5e6d0 100644 --- a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs +++ b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs @@ -601,7 +601,7 @@ public class DaemonRuntimeDocumentTests var unityGameTuiSurfaceState = ReadLatest(client.State.Document(AetheriaClientEveSurface.GameTui)); var unityEditorSurfaceState = ReadLatest(client.State.Document(AetheriaClientEveSurface.Editor)); var unityEditorTuiSurfaceState = ReadLatest(client.State.Document(AetheriaClientEveSurface.EditorTui)); - var surfaceResolver = client.State.CreateEveSurfaceStateRefResolver(); + var surfaceResolver = client.State.CreateEveSurfaceCultMeshStateRefResolver(); var unityGameSurface = AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument( unityGameSurfaceState, surfaceResolver); @@ -690,9 +690,10 @@ public class DaemonRuntimeDocumentTests Array.Empty()), Array.Empty()); - var resolved = AetheriaRuntimeEveSurfaceAdapter.ResolveStateRefs( - surface, - stateRef => stateRef == AetheriaRuntimeDaemonStateRefs.CurrentTargetName ? "Live Target" : ""); + var resolver = CultMesh.StateRefResolver( + "aetheria.tests.refs", + (stateRef, _context) => stateRef == AetheriaRuntimeDaemonStateRefs.CurrentTargetName ? "Live Target" : ""); + var resolved = AetheriaRuntimeEveSurfaceAdapter.ResolveStateRefs(surface, resolver); Assert.IsTrue(ContainsEveSurfaceMetric(resolved.Surface.Root, "Target", "Live Target")); Assert.IsTrue(ContainsEveSurfaceProp( @@ -728,9 +729,10 @@ public class DaemonRuntimeDocumentTests Array.Empty()), Array.Empty()); - var resolved = AetheriaRuntimeEveSurfaceAdapter.ResolveStateRefs( - surface, - stateRef => stateRef == AetheriaRuntimeDaemonStateRefs.CurrentTargetName ? "Live Target" : ""); + var resolver = CultMesh.StateRefResolver( + "aetheria.tests.refs", + (stateRef, _context) => stateRef == AetheriaRuntimeDaemonStateRefs.CurrentTargetName ? "Live Target" : ""); + var resolved = AetheriaRuntimeEveSurfaceAdapter.ResolveStateRefs(surface, resolver); Assert.IsTrue(ContainsEveSurfaceProp(resolved.Surface.Root, "description", "Live Target")); Assert.IsTrue(ContainsEveSurfaceProp(resolved.Surface.Root, "descriptionRef", AetheriaRuntimeDaemonStateRefs.CurrentTargetName)); diff --git a/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs b/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs index d35bd3f19..4a42633f3 100644 --- a/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs +++ b/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveSurfacePresenter.cs @@ -135,7 +135,7 @@ namespace GameCult.Aetheria.EveRuntime ? null : AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument( surface, - client.State.CreateEveSurfaceStateRefResolver()); + client.State.CreateEveSurfaceCultMeshStateRefResolver()); } private global::Aetheria.State.Documents.EveSurfaceState? ReadDaemonSurfaceState(AetheriaClient client) @@ -231,7 +231,7 @@ namespace GameCult.Aetheria.EveRuntime surface, request => EmitCommand(statePath, request), RootOnlyChrome, - ResolveClient(statePath).State.CreateEveSurfaceStateRefResolver()); + ResolveClient(statePath).State.CreateEveSurfaceCultMeshStateRefResolver()); _mountedStatePath = statePath; _mountedSurfaceId = surface.Surface.Id; _mountedSurfaceVersion = surface.Version; diff --git a/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveUnitySurfaceHost.cs b/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveUnitySurfaceHost.cs index b6af78dbe..42ffe1e7d 100644 --- a/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveUnitySurfaceHost.cs +++ b/Packages/org.gamecult.aetheria.eve-runtime/Runtime/AetheriaEveUnitySurfaceHost.cs @@ -4,6 +4,7 @@ using System.Linq; using GameCult.Aetheria.State.Verse; using GameCult.Eve.Surface; using GameCult.Eve.UnityUIToolkit; +using GameCult.Mesh; using UnityEngine; using UnityEngine.UIElements; @@ -47,7 +48,7 @@ namespace GameCult.Aetheria.EveRuntime EveSurfaceDocument surface, Action commandHandler, AetheriaEveUnitySurfaceChrome chrome, - Func stateRefResolver = null, + CultMeshStateRefResolver stateRefResolver = null, int sortingOrder = 1000) { if (owner == null) @@ -90,7 +91,7 @@ namespace GameCult.Aetheria.EveRuntime AetheriaRuntimeSurfaceDocument surface, Action commandHandler, AetheriaEveUnitySurfaceChrome chrome, - Func stateRefResolver = null, + CultMeshStateRefResolver stateRefResolver = null, int sortingOrder = 1000) { if (surface == null) @@ -219,16 +220,16 @@ namespace GameCult.Aetheria.EveRuntime return false; } - private static Func CreateDefaultStateRefResolver() + private static CultMeshStateRefResolver CreateDefaultStateRefResolver() { var stateBoot = AetheriaRuntimeStateBoot.Inspect(AetheriaUnityRuntimePaths.GameDataDirectory, ""); if (!stateBoot.SupportsLocalStateFileRead || !stateBoot.StateFileExists) - return _ => ""; + return null; return AetheriaUnityRuntimeClientProvider .ResolveClient(stateBoot, "unity-eve-surface-host") .State - .CreateEveSurfaceStateRefResolver(); + .CreateEveSurfaceCultMeshStateRefResolver(); } } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs index ed86a4cff..99b919f4e 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs @@ -249,11 +249,6 @@ namespace GameCult.Aetheria.State.Verse return (CultMeshDocumentHandle)(object)_starbridgePlayerSeat(seatId); } - public Func CreateEveSurfaceStateRefResolver() - { - return CreateEveSurfaceCultMeshStateRefResolver().AsFunc(); - } - public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver() { _eveStateRefFrame ??= Document().Reactive(); diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs index 86b245ef1..52d755b4f 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeEveSurfaceAdapter.cs @@ -23,7 +23,7 @@ namespace GameCult.Aetheria.State.Verse public static EveSurfaceDocument ToEveSurfaceDocument( EveSurfaceState state, - Func? stateRefResolver) + CultMeshStateRefResolver? stateRefResolver) { if (state == null) throw new ArgumentNullException(nameof(state)); @@ -51,7 +51,7 @@ namespace GameCult.Aetheria.State.Verse public static EveSurfaceDocument ToEveSurfaceDocument( AetheriaRuntimeSurfaceDocument document, - Func? stateRefResolver) + CultMeshStateRefResolver? stateRefResolver) { if (document == null) throw new ArgumentNullException(nameof(document)); @@ -78,12 +78,13 @@ namespace GameCult.Aetheria.State.Verse public static EveSurfaceDocument ResolveStateRefs( EveSurfaceDocument surface, - Func? stateRefResolver) + CultMeshStateRefResolver? stateRefResolver) { if (surface == null) throw new ArgumentNullException(nameof(surface)); if (stateRefResolver == null) return surface; + var resolveStateRef = stateRefResolver.AsFunc(); return new EveSurfaceDocument( surface.Type, surface.Schema, @@ -94,7 +95,7 @@ namespace GameCult.Aetheria.State.Verse surface.UpdatedAtUtc, new EveSurfaceTree( surface.Surface.Id, - ResolveStateRefs(surface.Surface.Root, stateRefResolver), + ResolveStateRefs(surface.Surface.Root, resolveStateRef), surface.Surface.Styles), surface.Commands); } @@ -187,37 +188,37 @@ namespace GameCult.Aetheria.State.Verse private static EveSurfaceComponent ResolveStateRefs( EveSurfaceComponent component, - Func stateRefResolver) + Func resolveStateRef) { var props = new Dictionary(component.Props, StringComparer.Ordinal); - ResolvePropRefs(props, stateRefResolver); + ResolvePropRefs(props, resolveStateRef); return new EveSurfaceComponent( component.Id, component.Kind, props, - ResolveStateRefs(component.Children, stateRefResolver), + ResolveStateRefs(component.Children, resolveStateRef), component.StateBindings); } private static IReadOnlyList ResolveStateRefs( IReadOnlyList children, - Func stateRefResolver) + Func resolveStateRef) { if (children == null || children.Count == 0) return Array.Empty(); var resolved = new EveSurfaceComponent[children.Count]; for (var index = 0; index < children.Count; index++) - resolved[index] = ResolveStateRefs(children[index], stateRefResolver); + resolved[index] = ResolveStateRefs(children[index], resolveStateRef); return resolved; } private static void ResolvePropRefs( Dictionary props, - Func stateRefResolver) + Func resolveStateRef) { - ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, "value", stateRefResolver); + ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, "value", resolveStateRef); var refProps = props .Where(prop => IsStatePointerProp(prop.Key) && @@ -226,7 +227,7 @@ namespace GameCult.Aetheria.State.Verse .ToArray(); foreach (var refProp in refProps) - ResolvePropRef(props, refProp.Key, ResolvePointerValueKey(refProp.Key), stateRefResolver); + ResolvePropRef(props, refProp.Key, ResolvePointerValueKey(refProp.Key), resolveStateRef); } private static bool IsStatePointerProp(string key) @@ -243,12 +244,12 @@ namespace GameCult.Aetheria.State.Verse Dictionary props, string refKey, string valueKey, - Func stateRefResolver) + Func resolveStateRef) { if (!props.TryGetValue(refKey, out var stateRef) || string.IsNullOrWhiteSpace(stateRef)) return; - var resolved = stateRefResolver(stateRef); + var resolved = resolveStateRef(stateRef); if (!string.IsNullOrWhiteSpace(resolved)) props[valueKey] = resolved; }