Move Eve surface state lowering into runtime adapter

This commit is contained in:
Meta Vens 2026-06-29 03:48:39 +01:00
commit 2e5cf53ba1
5 changed files with 110 additions and 101 deletions

View file

@ -780,19 +780,19 @@ static async Task PublishDaemonApiDocumentsAsync(
.ConfigureAwait(false);
if (result.GameSurface != null)
await node.MutableDocument<EveSurfaceState>(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)
.ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.GameSurface))
.ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.GameSurface))
.ConfigureAwait(false);
if (result.GameTuiSurface != null)
await node.MutableDocument<EveSurfaceState>(AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface)
.ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.GameTuiSurface))
.ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.GameTuiSurface))
.ConfigureAwait(false);
if (result.EditorSurface != null)
await node.MutableDocument<EveSurfaceState>(AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface)
.ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.EditorSurface))
.ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.EditorSurface))
.ConfigureAwait(false);
if (result.EditorTuiSurface != null)
await node.MutableDocument<EveSurfaceState>(AetheriaRuntimeVerseRecordKeys.DaemonEditorTuiSurface)
.ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(result.EditorTuiSurface))
.ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(result.EditorTuiSurface))
.ConfigureAwait(false);
}

View file

@ -173,7 +173,7 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
}
}
await node.MutableDocument<EveSurfaceState>(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)
.ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(daemonGameSurface));
.ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(daemonGameSurface));
await node.MutableDocument<AetheriaRuntimeSession>(AetheriaStateNode.RuntimeSessionKey("smoke-runtime")).ReplaceAsync(new AetheriaRuntimeSession
{
RuntimeId = "smoke-runtime",

View file

@ -725,10 +725,6 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
"org.gamecult.aetheria.state",
"Runtime",
"AetheriaRuntimeCultCacheDocumentStore.cs");
var runtimeSurfaceStateProjectorPath = Path.Combine(
root,
"Aetheria.State",
"AetheriaRuntimeEveSurfaceStateProjector.cs");
var playerSettingsSurfaceProjectorPath = Path.Combine(
root,
"Aetheria.State",
@ -772,9 +768,6 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
var runtimeCultCacheDocumentStore = File.Exists(runtimeCultCacheDocumentStorePath)
? File.ReadAllText(runtimeCultCacheDocumentStorePath)
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaRuntimeCultCacheDocumentStore.cs is missing.");
var runtimeSurfaceStateProjector = File.Exists(runtimeSurfaceStateProjectorPath)
? File.ReadAllText(runtimeSurfaceStateProjectorPath)
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaRuntimeEveSurfaceStateProjector.cs is missing.");
var playerSettingsSurfaceProjector = File.Exists(playerSettingsSurfaceProjectorPath)
? File.ReadAllText(playerSettingsSurfaceProjectorPath)
: throw new InvalidOperationException("Cannot verify shared Eve package ownership; AetheriaPlayerSettingsSurfaceProjector.cs is missing.");
@ -896,9 +889,19 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
"Aetheria runtime surfaces reintroduced local state binding flattening; state binding persistence belongs to CultMesh.StateBindingRecord.");
}
var deletedRuntimeSurfaceStateProjectorPath = Path.Combine(
root,
"Aetheria.State",
"AetheriaRuntimeEveSurfaceStateProjector.cs");
if (File.Exists(deletedRuntimeSurfaceStateProjectorPath))
{
throw new InvalidOperationException(
"AetheriaRuntimeEveSurfaceStateProjector is dead conversion chaff; AetheriaRuntimeEveSurfaceAdapter owns runtime surface to Eve state lowering.");
}
var surfaceCommandProjectors = string.Join(
"\n",
runtimeSurfaceStateProjector,
runtimeAdapter,
playerSettingsSurfaceProjector,
catalogSurfaceProjector,
operationsSurfaceProjector);
@ -907,6 +910,8 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root)
!runtimeCultCacheDocumentStore.Contains("routeDescription).ToBinding()", StringComparison.Ordinal) ||
!runtimeAdapter.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) ||
!runtimeAdapter.Contains("command.SchemaId", StringComparison.Ordinal) ||
!runtimeAdapter.Contains("public static EveSurfaceState ToEveSurfaceState(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) ||
!runtimeAdapter.Contains("global::Aetheria.State.Documents.EveSurfaceComponent ToEveSurfaceState(", StringComparison.Ordinal) ||
!surfaceCommandProjectors.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) ||
runtimeCultCacheDocumentStore.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal) ||
runtimeAdapter.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal))
@ -10508,7 +10513,7 @@ static void RequireDaemonVersePublication(string root)
var daemonHostProgramPath = Path.Combine(root, "Aetheria.State.Daemon", "Program.cs");
var documentRegistryPath = Path.Combine(root, "Aetheria.State", "AetheriaDocumentRegistry.cs");
var stateNodePath = Path.Combine(root, "Aetheria.State", "AetheriaStateNode.cs");
var daemonSurfaceProjectorPath = Path.Combine(root, "Aetheria.State", "AetheriaRuntimeEveSurfaceStateProjector.cs");
var runtimeEveSurfaceAdapterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeEveSurfaceAdapter.cs");
var providerAdvertisementPath = Path.Combine(root, "Aetheria.State", "AetheriaProviderAdvertisementProjector.cs");
var documentStorePath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeCultCacheDocumentStore.cs");
var boundaryPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeStateBoundary.cs");
@ -10534,7 +10539,7 @@ static void RequireDaemonVersePublication(string root)
daemonHostProgramPath,
documentRegistryPath,
stateNodePath,
daemonSurfaceProjectorPath,
runtimeEveSurfaceAdapterPath,
providerAdvertisementPath,
documentStorePath,
boundaryPath,
@ -10569,7 +10574,7 @@ static void RequireDaemonVersePublication(string root)
var daemonHostProgram = File.ReadAllText(daemonHostProgramPath);
var documentRegistry = File.ReadAllText(documentRegistryPath);
var stateNode = File.ReadAllText(stateNodePath);
var daemonSurfaceProjector = File.ReadAllText(daemonSurfaceProjectorPath);
var runtimeEveSurfaceAdapter = File.ReadAllText(runtimeEveSurfaceAdapterPath);
var providerAdvertisement = File.ReadAllText(providerAdvertisementPath);
var documentStore = File.ReadAllText(documentStorePath);
var boundary = File.ReadAllText(boundaryPath);
@ -10842,11 +10847,18 @@ static void RequireDaemonVersePublication(string root)
string.Join(", ", survivingDaemonNodeSymbols));
}
if (!daemonSurfaceProjector.Contains("public static EveSurfaceState ToState(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) ||
!daemonSurfaceProjector.Contains("EveCommandTemplate", StringComparison.Ordinal) ||
!daemonSurfaceProjector.Contains("EveSurfaceComponent", StringComparison.Ordinal))
var deletedDaemonSurfaceProjectorPath = Path.Combine(root, "Aetheria.State", "AetheriaRuntimeEveSurfaceStateProjector.cs");
if (File.Exists(deletedDaemonSurfaceProjectorPath))
{
throw new InvalidOperationException("Daemon Eve surface projector no longer lowers daemon surfaces into registered Eve surface state.");
throw new InvalidOperationException(
"Daemon Eve surface state lowering still lives in Aetheria.State projector chaff instead of the runtime Eve surface adapter.");
}
if (!runtimeEveSurfaceAdapter.Contains("public static EveSurfaceState ToEveSurfaceState(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) ||
!runtimeEveSurfaceAdapter.Contains("EveCommandTemplate", StringComparison.Ordinal) ||
!runtimeEveSurfaceAdapter.Contains("global::Aetheria.State.Documents.EveSurfaceComponent", StringComparison.Ordinal))
{
throw new InvalidOperationException("Runtime Eve surface adapter no longer lowers daemon surfaces into registered Eve surface state.");
}
if (!daemonDocuments.Contains("AetheriaRuntimeDaemonCommandKinds", StringComparison.Ordinal))
@ -11482,7 +11494,7 @@ static void RequireDaemonVersePublication(string root)
"AetheriaClient UI submission did not appear as a typed Eve state record.",
"node.MutableDocument<AetheriaRuntimeDaemonFrameDocument>(AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest)",
"node.MutableDocument<EveSurfaceState>(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)",
".ReplaceAsync(AetheriaRuntimeEveSurfaceStateProjector.ToState(daemonGameSurface))",
".ReplaceAsync(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceState(daemonGameSurface))",
"reopened.MutableDocument<AetheriaRuntimeDaemonProviderAdvertisementDocument>(AetheriaRuntimeVerseRecordKeys.DaemonProviderAdvertisement)",
"reopened.MutableDocument<AetheriaRuntimeDaemonHealthDocument>(AetheriaRuntimeVerseRecordKeys.DaemonHealth)",
"reopened.MutableDocument<AetheriaRuntimeDaemonCommandBoundaryDocument>(AetheriaRuntimeVerseRecordKeys.DaemonCommandBoundary)",

View file

@ -1,80 +0,0 @@
using Aetheria.State.Documents;
using GameCult.Aetheria.State.Verse;
namespace Aetheria.State;
public static class AetheriaRuntimeEveSurfaceStateProjector
{
public static EveSurfaceState ToState(AetheriaRuntimeSurfaceDocument document)
{
return new EveSurfaceState
{
ProviderId = document.ProviderId,
ProviderKind = document.ProviderKind,
Title = document.Title,
Version = document.Version,
UpdatedAtUtc = document.UpdatedAtUtc,
Surface = ToSurface(document.Surface),
Commands = document.Commands
.Select(command =>
{
var record = GameCult.Mesh.CultMesh.OperationBindingRecord(command.Operation);
return new EveCommandTemplate
{
Command = record.OperationId,
Label = record.Label,
Transport = record.RouteDescription,
SchemaId = record.SchemaId,
RouteKind = record.RouteKind,
RouteDescription = record.RouteDescription
};
})
.ToArray()
};
}
private static EveSurface ToSurface(AetheriaRuntimeSurfaceTree surface)
{
return new EveSurface
{
Id = surface.Id,
Root = ToComponent(surface.Root),
Styles = surface.Styles
.Select(style => new EveStyleToken
{
Name = style.Name,
Value = style.Value
})
.ToArray()
};
}
private static EveSurfaceComponent ToComponent(AetheriaRuntimeSurfaceComponent component)
{
var props = new Dictionary<string, string>(component.Props, StringComparer.Ordinal);
AetheriaRuntimeSurfaceStateBindings.AddPointerProps(props, component.StateBindings);
return new EveSurfaceComponent
{
Id = component.Id,
Kind = component.Kind,
Props = props,
Children = component.Children.Select(ToComponent).ToArray(),
StateBindings = component.StateBindings
.Select(binding =>
{
var record = GameCult.Mesh.CultMesh.StateBindingRecord(binding);
return new EveSurfaceStateBinding
{
TargetProp = record.TargetProp,
PointerId = record.PointerId,
SourceId = record.SourceId,
SchemaId = record.SchemaId,
RouteKind = record.RouteKind,
RouteDescription = record.RouteDescription
};
})
.ToArray()
};
}
}

View file

@ -11,6 +11,36 @@ namespace GameCult.Aetheria.State.Verse
{
public static class AetheriaRuntimeEveSurfaceAdapter
{
public static EveSurfaceState ToEveSurfaceState(AetheriaRuntimeSurfaceDocument document)
{
if (document == null) throw new ArgumentNullException(nameof(document));
return new EveSurfaceState
{
ProviderId = document.ProviderId,
ProviderKind = document.ProviderKind,
Title = document.Title,
Version = document.Version,
UpdatedAtUtc = document.UpdatedAtUtc,
Surface = ToEveSurfaceState(document.Surface),
Commands = document.Commands
.Select(command =>
{
var record = CultMesh.OperationBindingRecord(command.Operation);
return new global::Aetheria.State.Documents.EveCommandTemplate
{
Command = record.OperationId,
Label = record.Label,
Transport = record.RouteDescription,
SchemaId = record.SchemaId,
RouteKind = record.RouteKind,
RouteDescription = record.RouteDescription
};
})
.ToArray()
};
}
public static EveSurfaceDocument ToEveSurfaceDocument(AetheriaRuntimeSurfaceDocument document)
{
return ToEveSurfaceDocument(document, null);
@ -134,6 +164,53 @@ namespace GameCult.Aetheria.State.Verse
component.StateBindings.Select(ToCultMeshStateBinding).ToArray());
}
private static global::Aetheria.State.Documents.EveSurface ToEveSurfaceState(
AetheriaRuntimeSurfaceTree surface)
{
return new global::Aetheria.State.Documents.EveSurface
{
Id = surface.Id,
Root = ToEveSurfaceState(surface.Root),
Styles = surface.Styles
.Select(style => new global::Aetheria.State.Documents.EveStyleToken
{
Name = style.Name,
Value = style.Value
})
.ToArray()
};
}
private static global::Aetheria.State.Documents.EveSurfaceComponent ToEveSurfaceState(
AetheriaRuntimeSurfaceComponent component)
{
var props = new Dictionary<string, string>(component.Props, StringComparer.Ordinal);
AetheriaRuntimeSurfaceStateBindings.AddPointerProps(props, component.StateBindings);
return new global::Aetheria.State.Documents.EveSurfaceComponent
{
Id = component.Id,
Kind = component.Kind,
Props = props,
Children = component.Children.Select(ToEveSurfaceState).ToArray(),
StateBindings = component.StateBindings
.Select(binding =>
{
var record = CultMesh.StateBindingRecord(binding);
return new global::Aetheria.State.Documents.EveSurfaceStateBinding
{
TargetProp = record.TargetProp,
PointerId = record.PointerId,
SourceId = record.SourceId,
SchemaId = record.SchemaId,
RouteKind = record.RouteKind,
RouteDescription = record.RouteDescription
};
})
.ToArray()
};
}
private static EveSurfaceComponent ToEveSurfaceComponent(global::Aetheria.State.Documents.EveSurfaceComponent component)
{
var props = new Dictionary<string, string>(component.Props, StringComparer.Ordinal);