Advertise stat recipes from daemon editor surface

This commit is contained in:
Meta Vens 2026-06-21 10:52:21 +01:00
commit 458f40fddb
5 changed files with 63 additions and 7 deletions

View file

@ -6344,6 +6344,7 @@ static void RequireDaemonVersePublication(string root)
"AetheriaRuntimeDaemonPublicationStore.PublishProviderAdvertisement",
"AetheriaRuntimeDaemonPublicationStore.PublishHealth",
"AetheriaRuntimeDaemonGameSurfaceBuilder.Build",
"AetheriaRuntimeCatalogStore.ProjectStatRecipeSurfaceDocument(stateFilePath)",
"AetheriaRuntimeDaemonPublicationStore.PublishGameSurface",
"AetheriaRuntimeDaemonPublicationStore.PublishGameTuiSurface",
"AetheriaRuntimeDaemonEditorSurfaceBuilder.Build",
@ -6466,6 +6467,9 @@ static void RequireDaemonVersePublication(string root)
"\"editor.daemon\"",
"\"Verse Provider\"",
"\"Witnesses\"",
"\"Designer Surfaces\"",
"AetheriaRuntimeSurfaceDocument",
"AetheriaRuntimeStatRecipeCommands.SurfaceId",
"\"Typed Commands\"",
"AetheriaRuntimeDaemonCommandBoundaryEntry"
};
@ -6495,6 +6499,7 @@ static void RequireDaemonVersePublication(string root)
"AetheriaRuntimeDaemonSchemas.EditorSurface",
"AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId",
"AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId",
"AetheriaRuntimeStatRecipeCommands.SurfaceId",
"AetheriaRuntimeDaemonCommandKinds.TransferCargoItem",
"nameof(AetheriaRuntimeCargoTransferCommand)"
};

View file

@ -286,6 +286,10 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual(42, editorSurface.Version);
Assert.IsTrue(ContainsSurfaceMetric(editorSurface.Surface.Root, "Verse", "aetheria.test"));
Assert.IsTrue(ContainsSurfaceMetric(editorSurface.Surface.Root, "Status", "healthy"));
Assert.IsTrue(ContainsSurfaceProp(
editorSurface.Surface.Root,
"surfaceId",
AetheriaRuntimeStatRecipeCommands.SurfaceId));
Assert.IsTrue(editorSurface.Commands.Any(command =>
command.Command == "aetheria.daemon.commands.TransferCargoItem" &&
command.Transport == "cultmesh"));
@ -2376,4 +2380,18 @@ public class DaemonRuntimeDocumentTests
return component.Children.Any(child => ContainsSurfaceMetric(child, label, value));
}
private static bool ContainsSurfaceProp(
AetheriaRuntimeSurfaceComponent component,
string key,
string value)
{
if (component.Props.TryGetValue(key, out var actual) &&
string.Equals(actual, value, StringComparison.Ordinal))
{
return true;
}
return component.Children.Any(child => ContainsSurfaceProp(child, key, value));
}
}

View file

@ -69,16 +69,15 @@ namespace GameCult.Aetheria.State.Verse
surfaces.Add(ReadEveSurface(record.Payload));
}
surfaces.Add(ProjectStatRecipeSurface(stateFilePath));
surfaces.Add(AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(
ProjectStatRecipeSurfaceDocument(stateFilePath)));
return surfaces;
}
private static EveSurfaceDocument ProjectStatRecipeSurface(string stateFilePath)
public static AetheriaRuntimeSurfaceDocument ProjectStatRecipeSurfaceDocument(string stateFilePath)
{
var state = ProjectStatRecipeSurfaceState(stateFilePath);
var document = AetheriaRuntimeStatRecipeSurfaceBuilder.Build(
state);
return AetheriaRuntimeEveSurfaceAdapter.ToEveSurfaceDocument(document);
return AetheriaRuntimeStatRecipeSurfaceBuilder.Build(state);
}
private static AetheriaRuntimeStatRecipeSurfaceState ProjectStatRecipeSurfaceState(string stateFilePath)

View file

@ -15,11 +15,13 @@ namespace GameCult.Aetheria.State.Verse
public static AetheriaRuntimeSurfaceDocument Build(
AetheriaRuntimeDaemonProviderAdvertisementDocument provider,
AetheriaRuntimeDaemonHealthDocument health,
AetheriaRuntimeDaemonCommandBoundaryDocument commandBoundary)
AetheriaRuntimeDaemonCommandBoundaryDocument commandBoundary,
IReadOnlyList<AetheriaRuntimeSurfaceDocument>? designerSurfaces = null)
{
provider ??= new AetheriaRuntimeDaemonProviderAdvertisementDocument();
health ??= new AetheriaRuntimeDaemonHealthDocument();
commandBoundary ??= AetheriaRuntimeDaemonCommandBoundaryDocument.Create(provider.DaemonId);
designerSurfaces ??= Array.Empty<AetheriaRuntimeSurfaceDocument>();
return new AetheriaRuntimeSurfaceDocument(
providerId: "aetheria.daemon",
@ -94,6 +96,16 @@ namespace GameCult.Aetheria.State.Verse
commandBoundary.Commands
.Take(16)
.Select((entry, index) => CommandRow(index, entry))
.ToArray())),
Node(
"aetheria.daemon.editor.designer_surfaces",
"card",
new[] { ("title", "Designer Surfaces") },
Row(
"aetheria.daemon.editor.designer_surfaces.rows",
designerSurfaces
.Where(surface => surface != null)
.Select((surface, index) => DesignerSurfaceRow(index, surface))
.ToArray()))),
Array.Empty<AetheriaRuntimeSurfaceStyleToken>()),
commands: commandBoundary.Commands
@ -104,6 +116,23 @@ namespace GameCult.Aetheria.State.Verse
.ToArray());
}
private static AetheriaRuntimeSurfaceComponent DesignerSurfaceRow(
int index,
AetheriaRuntimeSurfaceDocument surface)
{
return Node(
$"aetheria.daemon.editor.designer_surfaces.{index}",
"inspector.kv",
new[]
{
("title", surface.Title),
("surfaceId", surface.Surface.Id),
("provider", surface.ProviderId),
("kind", surface.ProviderKind),
("commands", surface.Commands.Count.ToString(CultureInfo.InvariantCulture))
});
}
private static AetheriaRuntimeSurfaceComponent CommandRow(
int index,
AetheriaRuntimeDaemonCommandBoundaryEntry entry)

View file

@ -165,10 +165,15 @@ namespace GameCult.Aetheria.State.Verse
var gameTuiSurfacePath = AetheriaRuntimeDaemonPublicationStore.PublishGameTuiSurface(
stateFilePath,
gameSurface);
var designerSurfaces = new[]
{
AetheriaRuntimeCatalogStore.ProjectStatRecipeSurfaceDocument(stateFilePath)
};
var editorSurface = AetheriaRuntimeDaemonEditorSurfaceBuilder.Build(
providerAdvertisement,
health,
commandBoundary);
commandBoundary,
designerSurfaces);
var editorSurfacePath = AetheriaRuntimeDaemonPublicationStore.PublishEditorSurface(
stateFilePath,
editorSurface);