diff --git a/src/GameCult.Mesh/CultMeshUiSurfaces.cs b/src/GameCult.Mesh/CultMeshUiSurfaces.cs deleted file mode 100644 index 246ebe4b..00000000 --- a/src/GameCult.Mesh/CultMeshUiSurfaces.cs +++ /dev/null @@ -1,735 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using GameCult.Caching; -using MessagePack; - -#pragma warning disable CS1591 - -namespace GameCult.Mesh -{ - /// - /// Portable CultUI/Eve surface document published through CultMesh. - /// - [CultDocument("gamecult.eve.surface", "gamecult.eve.surface.v1")] - [MessagePackObject] - public sealed class EveSurfaceDocument - { - [SerializationConstructor] - public EveSurfaceDocument( - string providerId, - string providerKind, - string title, - long version, - string updatedAtUtc, - EveSurfaceTree surface, - IReadOnlyList commands) - { - ProviderId = providerId ?? ""; - ProviderKind = providerKind ?? ""; - Title = title ?? ""; - Version = version; - UpdatedAtUtc = updatedAtUtc ?? ""; - Surface = surface ?? throw new ArgumentNullException(nameof(surface)); - Commands = commands ?? Array.Empty(); - } - - [Key(0)] - public string ProviderId { get; } - - [Key(1)] - public string ProviderKind { get; } - - [Key(2)] - public string Title { get; } - - [Key(3)] - public long Version { get; } - - [Key(4)] - public string UpdatedAtUtc { get; } - - [Key(5)] - public EveSurfaceTree Surface { get; } - - [Key(6)] - public IReadOnlyList Commands { get; } - } - - [MessagePackObject] - public sealed class EveSurfaceTree - { - [SerializationConstructor] - public EveSurfaceTree( - string id, - EveSurfaceComponent root, - IReadOnlyList styles) - { - Id = id ?? ""; - Root = root ?? throw new ArgumentNullException(nameof(root)); - Styles = styles ?? Array.Empty(); - } - - [Key(0)] - public string Id { get; } - - [Key(1)] - public EveSurfaceComponent Root { get; } - - [Key(2)] - public IReadOnlyList Styles { get; } - } - - [MessagePackObject] - public sealed class EveSurfaceComponent - { - public EveSurfaceComponent( - string id, - string kind, - IReadOnlyDictionary? props = null, - IReadOnlyList? children = null) - : this(id, kind, props, children, StateBindingsFromProps(props), Array.Empty()) - { - } - - public EveSurfaceComponent( - string id, - string kind, - IReadOnlyDictionary? props, - IReadOnlyList? children, - IReadOnlyList? stateBindings) - : this(id, kind, props, children, stateBindings, Array.Empty()) - { - } - - [SerializationConstructor] - public EveSurfaceComponent( - string id, - string kind, - IReadOnlyDictionary? props, - IReadOnlyList? children, - IReadOnlyList? stateBindings, - IReadOnlyList? embeddedDocuments) - { - Id = id ?? ""; - Kind = kind ?? ""; - Props = props ?? new Dictionary(StringComparer.Ordinal); - Children = children ?? Array.Empty(); - StateBindings = stateBindings ?? Array.Empty(); - EmbeddedDocuments = embeddedDocuments ?? Array.Empty(); - } - - [Key(0)] - public string Id { get; } - - [Key(1)] - public string Kind { get; } - - [Key(2)] - public IReadOnlyDictionary Props { get; } - - [Key(3)] - public IReadOnlyList Children { get; } - - [Key(4)] - public IReadOnlyList StateBindings { get; } - - [Key(5)] - public IReadOnlyList EmbeddedDocuments { get; } - - private static IReadOnlyList StateBindingsFromProps( - IReadOnlyDictionary? props) - { - if (props == null || props.Count == 0) - return Array.Empty(); - - var bindings = new List(); - foreach (var prop in props) - { - if (string.IsNullOrWhiteSpace(prop.Value) || - !prop.Key.EndsWith("PointerId", StringComparison.Ordinal)) - { - continue; - } - - var targetProp = prop.Key.Substring(0, prop.Key.Length - "PointerId".Length); - if (targetProp.Length == 0) - targetProp = "value"; - bindings.Add(EveSurfaceStateBinding.FromDescriptor(new CultMeshStateBindingDescriptor(targetProp, prop.Value))); - } - - return bindings; - } - } - - [MessagePackObject] - public sealed class EveSurfaceStateBinding - { - [SerializationConstructor] - public EveSurfaceStateBinding( - string targetProp, - string pointerId, - string sourceId, - string schemaId, - EveSurfaceRouteHint routeHint) - { - TargetProp = string.IsNullOrWhiteSpace(targetProp) ? "value" : targetProp; - PointerId = pointerId ?? ""; - SourceId = sourceId ?? ""; - SchemaId = schemaId ?? ""; - RouteHint = routeHint ?? EveSurfaceRouteHint.Automatic; - } - - [Key(0)] - public string TargetProp { get; } - - [Key(1)] - public string PointerId { get; } - - [Key(2)] - public string SourceId { get; } - - [Key(3)] - public string SchemaId { get; } - - [Key(4)] - public EveSurfaceRouteHint RouteHint { get; } - - public static EveSurfaceStateBinding FromDescriptor(CultMeshStateBindingDescriptor descriptor) - { - if (descriptor == null) throw new ArgumentNullException(nameof(descriptor)); - return new EveSurfaceStateBinding( - descriptor.TargetProp, - descriptor.PointerId, - descriptor.SourceId ?? "", - descriptor.SchemaId ?? "", - EveSurfaceRouteHint.FromRoute(descriptor.RouteHint)); - } - } - - [MessagePackObject] - public sealed class EveSurfaceOperationBinding - { - [SerializationConstructor] - public EveSurfaceOperationBinding( - string operationId, - string label, - string schemaId, - EveSurfaceRouteHint routeHint) - { - OperationId = operationId ?? ""; - Label = label ?? ""; - SchemaId = schemaId ?? ""; - RouteHint = routeHint ?? EveSurfaceRouteHint.Automatic; - } - - [Key(0)] - public string OperationId { get; } - - [Key(1)] - public string Label { get; } - - [Key(2)] - public string SchemaId { get; } - - [Key(3)] - public EveSurfaceRouteHint RouteHint { get; } - - public static EveSurfaceOperationBinding FromDescriptor(CultMeshOperationBindingDescriptor descriptor) - { - if (descriptor == null) throw new ArgumentNullException(nameof(descriptor)); - return new EveSurfaceOperationBinding( - descriptor.OperationId, - descriptor.Label, - descriptor.SchemaId, - EveSurfaceRouteHint.FromRoute(descriptor.RouteHint)); - } - } - - [MessagePackObject] - public sealed class EveSurfaceRouteHint - { - public static readonly EveSurfaceRouteHint Automatic = - new(nameof(CultMeshLocalityKind.Automatic), ""); - - [SerializationConstructor] - public EveSurfaceRouteHint(string kind, string description) - { - Kind = string.IsNullOrWhiteSpace(kind) ? nameof(CultMeshLocalityKind.Automatic) : kind; - Description = description ?? ""; - } - - [Key(0)] - public string Kind { get; } - - [Key(1)] - public string Description { get; } - - public static EveSurfaceRouteHint FromRoute(CultMeshRouteHint routeHint) - { - var record = CultMeshRouteRecord.FromRoute(routeHint); - return new EveSurfaceRouteHint(record.Kind, record.Description); - } - } - - [MessagePackObject] - public sealed class EveEmbeddedDocumentSlot - { - [SerializationConstructor] - public EveEmbeddedDocumentSlot( - string slotId, - string documentId, - string schemaId, - string presentationKind, - EveSurfaceRouteHint routeHint) - { - SlotId = slotId ?? ""; - DocumentId = documentId ?? ""; - SchemaId = schemaId ?? ""; - PresentationKind = presentationKind ?? ""; - RouteHint = routeHint ?? EveSurfaceRouteHint.Automatic; - } - - public EveEmbeddedDocumentSlot( - string slotId, - string documentId, - string schemaId, - string presentationKind) - : this(slotId, documentId, schemaId, presentationKind, EveSurfaceRouteHint.Automatic) - { - } - - [Key(0)] - public string SlotId { get; } - - [Key(1)] - public string DocumentId { get; } - - [Key(2)] - public string SchemaId { get; } - - [Key(3)] - public string PresentationKind { get; } - - [Key(4)] - public EveSurfaceRouteHint RouteHint { get; } - } - - [MessagePackObject] - public sealed class EveSurfaceStyleToken - { - [SerializationConstructor] - public EveSurfaceStyleToken(string name, string value) - { - Name = name ?? ""; - Value = value ?? ""; - } - - [Key(0)] - public string Name { get; } - - [Key(1)] - public string Value { get; } - } - - [MessagePackObject] - public sealed class EveSurfaceCommandTemplate - { - public EveSurfaceCommandTemplate(string command, string label, string transport = "cultmesh") - : this(new EveSurfaceOperationBinding( - command, - label, - "", - new EveSurfaceRouteHint(nameof(CultMeshLocalityKind.Automatic), transport))) - { - } - - [SerializationConstructor] - public EveSurfaceCommandTemplate(EveSurfaceOperationBinding operation) - { - Operation = operation ?? throw new ArgumentNullException(nameof(operation)); - } - - public EveSurfaceCommandTemplate(CultMeshOperationBindingDescriptor operation) - : this(EveSurfaceOperationBinding.FromDescriptor(operation)) - { - } - - [Key(0)] - public EveSurfaceOperationBinding Operation { get; } - - [IgnoreMember] - public string Command => Operation.OperationId; - - [IgnoreMember] - public string Label => Operation.Label; - } - - /// - /// Fluent CultUI/Eve surface builder. It preserves the old CultUI panel ergonomics while emitting portable documents. - /// - public sealed class EveSurfaceBuilder - { - private readonly string _surfaceId; - private readonly List _children = new(); - private readonly List _styles = new(); - private readonly List _commands = new(); - private long _version = 1; - private string _providerId = "gamecult"; - private string _providerKind = "cultui.surface"; - private string _title = ""; - private string _updatedAtUtc = ""; - - public EveSurfaceBuilder(string surfaceId) - { - _surfaceId = RequireNonEmpty(surfaceId, nameof(surfaceId)); - } - - public EveSurfaceBuilder Provider(string providerId, string providerKind) - { - _providerId = providerId ?? ""; - _providerKind = providerKind ?? ""; - return this; - } - - public EveSurfaceBuilder Title(string title) - { - _title = title ?? ""; - _children.Add(Text($"{_surfaceId}.title", _title, "text.title")); - return this; - } - - public EveSurfaceBuilder TitleSubtitle(string title, string subtitle) - { - _title = string.IsNullOrWhiteSpace(subtitle) ? title ?? "" : $"{title} {subtitle}"; - _children.Add(Text($"{_surfaceId}.title", title ?? "", "text.title")); - _children.Add(Text($"{_surfaceId}.subtitle", subtitle ?? "", "text.subtitle")); - return this; - } - - public EveSurfaceBuilder Text(string text, string? id = null) - { - _children.Add(Text(id ?? $"{_surfaceId}.text.{_children.Count}", text, "text")); - return this; - } - - public EveSurfaceBuilder Button(string label, string command) - { - var operation = CultMesh.OperationBinding(command, label); - _commands.Add(new EveSurfaceCommandTemplate(operation)); - _children.Add(ButtonComponent($"{_surfaceId}.button.{Slug(label)}", label, operation)); - return this; - } - - public EveSurfaceBuilder Button(string label, CultMeshOperationBindingDescriptor operation) - { - if (operation == null) throw new ArgumentNullException(nameof(operation)); - _commands.Add(new EveSurfaceCommandTemplate(operation)); - _children.Add(ButtonComponent($"{_surfaceId}.button.{Slug(label)}", label, operation)); - return this; - } - - public EveSurfaceBuilder ButtonColumn(string id, Action build) - { - return Group(id, "column", build); - } - - public EveSurfaceBuilder ButtonRow(string id, Action build) - { - return Group(id, "row", build); - } - - public EveSurfaceBuilder Form(string id, Action build) - { - if (build == null) throw new ArgumentNullException(nameof(build)); - var form = new EveSurfaceFormBuilder(id, AddCommand); - build(form); - _children.Add(form.Build()); - return this; - } - - public EveSurfaceBuilder EmbeddedDocument( - string slotId, - string documentId, - string schemaId, - string presentationKind, - CultMeshRouteHint? routeHint = null) - { - _children.Add(new EveSurfaceComponent( - $"{_surfaceId}.slot.{Slug(slotId)}", - "surface.slot", - new Dictionary(StringComparer.Ordinal) - { - ["slotId"] = slotId ?? "", - ["documentId"] = documentId ?? "", - ["schemaId"] = schemaId ?? "", - ["presentationKind"] = presentationKind ?? "" - }, - Array.Empty(), - Array.Empty(), - new[] - { - new EveEmbeddedDocumentSlot( - slotId ?? "", - documentId ?? "", - schemaId ?? "", - presentationKind ?? "", - routeHint == null ? EveSurfaceRouteHint.Automatic : EveSurfaceRouteHint.FromRoute(routeHint)) - })); - return this; - } - - public EveSurfaceBuilder Style(string name, string value) - { - _styles.Add(new EveSurfaceStyleToken(name, value)); - return this; - } - - public EveSurfaceBuilder Version(long version) - { - _version = version; - return this; - } - - public EveSurfaceBuilder UpdatedAtUtc(string updatedAtUtc) - { - _updatedAtUtc = updatedAtUtc ?? ""; - return this; - } - - public EveSurfaceDocument Build() - { - return new EveSurfaceDocument( - _providerId, - _providerKind, - _title, - _version, - string.IsNullOrWhiteSpace(_updatedAtUtc) ? DateTime.UtcNow.ToString("O") : _updatedAtUtc, - new EveSurfaceTree( - _surfaceId, - new EveSurfaceComponent( - $"{_surfaceId}.root", - "surface", - EmptyProps(), - _children.ToArray()), - _styles.ToArray()), - _commands.ToArray()); - } - - private EveSurfaceBuilder Group(string id, string kind, Action build) - { - if (build == null) throw new ArgumentNullException(nameof(build)); - var group = new EveSurfaceGroupBuilder(id, kind, AddCommand); - build(group); - _children.Add(group.Build()); - return this; - } - - private void AddCommand(EveSurfaceCommandTemplate command) - { - if (command != null) - _commands.Add(command); - } - - internal static EveSurfaceComponent Text(string id, string value, string kind) - { - return new EveSurfaceComponent( - id, - kind, - new Dictionary(StringComparer.Ordinal) - { - ["value"] = value ?? "" - }, - Array.Empty()); - } - - internal static EveSurfaceComponent ButtonComponent( - string id, - string label, - CultMeshOperationBindingDescriptor operation) - { - return new EveSurfaceComponent( - id, - "control.button", - new Dictionary(StringComparer.Ordinal) - { - ["label"] = label ?? operation.Label, - ["command"] = operation.OperationId, - ["operationId"] = operation.OperationId, - ["schemaId"] = operation.SchemaId - }, - Array.Empty()); - } - - internal static Dictionary EmptyProps() - { - return new Dictionary(StringComparer.Ordinal); - } - - internal static string Slug(string? value) - { - if (string.IsNullOrWhiteSpace(value)) - return "unnamed"; - - var chars = value - .Select(character => char.IsLetterOrDigit(character) ? char.ToLowerInvariant(character) : '.') - .ToArray(); - var slug = new string(chars).Trim('.'); - while (slug.Contains("..", StringComparison.Ordinal)) - slug = slug.Replace("..", ".", StringComparison.Ordinal); - return string.IsNullOrWhiteSpace(slug) ? "unnamed" : slug; - } - - private static string RequireNonEmpty(string value, string paramName) - { - return string.IsNullOrWhiteSpace(value) - ? throw new ArgumentException("Value must be non-empty.", paramName) - : value; - } - } - - public sealed class EveSurfaceGroupBuilder - { - private readonly string _id; - private readonly string _kind; - private readonly Action _addCommand; - private readonly List _children = new(); - - internal EveSurfaceGroupBuilder( - string id, - string kind, - Action addCommand) - { - _id = id ?? ""; - _kind = kind ?? "column"; - _addCommand = addCommand ?? throw new ArgumentNullException(nameof(addCommand)); - } - - public EveSurfaceGroupBuilder Button(string label, string command) - { - var operation = CultMesh.OperationBinding(command, label); - _addCommand(new EveSurfaceCommandTemplate(operation)); - _children.Add(EveSurfaceBuilder.ButtonComponent($"{_id}.button.{EveSurfaceBuilder.Slug(label)}", label, operation)); - return this; - } - - public EveSurfaceGroupBuilder Button(string label, CultMeshOperationBindingDescriptor operation) - { - if (operation == null) throw new ArgumentNullException(nameof(operation)); - _addCommand(new EveSurfaceCommandTemplate(operation)); - _children.Add(EveSurfaceBuilder.ButtonComponent($"{_id}.button.{EveSurfaceBuilder.Slug(label)}", label, operation)); - return this; - } - - internal EveSurfaceComponent Build() - { - return new EveSurfaceComponent(_id, _kind, EveSurfaceBuilder.EmptyProps(), _children.ToArray()); - } - } - - public sealed class EveSurfaceFormBuilder - { - private readonly string _id; - private readonly Action _addCommand; - private readonly List _children = new(); - - internal EveSurfaceFormBuilder(string id, Action addCommand) - { - _id = id ?? ""; - _addCommand = addCommand ?? throw new ArgumentNullException(nameof(addCommand)); - } - - public EveSurfaceFormBuilder Text( - string label, - string value, - CultMeshOperationBindingDescriptor operation, - CultMeshStateBindingDescriptor? binding = null) - { - if (operation == null) throw new ArgumentNullException(nameof(operation)); - _addCommand(new EveSurfaceCommandTemplate(operation)); - _children.Add(Control( - "control.text", - label, - value, - operation, - binding)); - return this; - } - - public EveSurfaceFormBuilder Toggle( - string label, - bool value, - CultMeshOperationBindingDescriptor operation, - CultMeshStateBindingDescriptor? binding = null) - { - if (operation == null) throw new ArgumentNullException(nameof(operation)); - _addCommand(new EveSurfaceCommandTemplate(operation)); - _children.Add(Control( - "control.toggle", - label, - value ? "true" : "false", - operation, - binding)); - return this; - } - - public EveSurfaceFormBuilder Metric( - string label, - string value, - CultMeshStateBindingDescriptor? binding = null) - { - var bindings = binding == null - ? Array.Empty() - : new[] { EveSurfaceStateBinding.FromDescriptor(binding) }; - _children.Add(new EveSurfaceComponent( - $"{_id}.metric.{EveSurfaceBuilder.Slug(label)}", - "metric", - new Dictionary(StringComparer.Ordinal) - { - ["label"] = label ?? "", - ["value"] = value ?? "" - }, - Array.Empty(), - bindings)); - return this; - } - - internal EveSurfaceComponent Build() - { - return new EveSurfaceComponent(_id, "form", EveSurfaceBuilder.EmptyProps(), _children.ToArray()); - } - - private EveSurfaceComponent Control( - string kind, - string label, - string value, - CultMeshOperationBindingDescriptor operation, - CultMeshStateBindingDescriptor? binding) - { - var bindings = binding == null - ? Array.Empty() - : new[] { EveSurfaceStateBinding.FromDescriptor(binding) }; - return new EveSurfaceComponent( - $"{_id}.{EveSurfaceBuilder.Slug(label)}", - kind, - new Dictionary(StringComparer.Ordinal) - { - ["label"] = label ?? "", - ["value"] = value ?? "", - ["command"] = operation.OperationId, - ["operationId"] = operation.OperationId, - ["schemaId"] = operation.SchemaId - }, - Array.Empty(), - bindings); - } - } - - public static class EveSurface - { - public static EveSurfaceBuilder Create(string surfaceId) - { - return new EveSurfaceBuilder(surfaceId); - } - } -} diff --git a/tests/GameCult.Mesh.Tests/EveSurfaceBuilderTests.cs b/tests/GameCult.Mesh.Tests/EveSurfaceBuilderTests.cs deleted file mode 100644 index 02a857d4..00000000 --- a/tests/GameCult.Mesh.Tests/EveSurfaceBuilderTests.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.Linq; -using FluentAssertions; -using GameCult.Caching.MessagePack; -using NUnit.Framework; - -namespace GameCult.Mesh.Tests; - -public sealed class EveSurfaceBuilderTests -{ - [Test] - public void Builder_ComposesMainMenuLikeLegacyCultUiPanel() - { - var surface = EveSurface.Create("aetheria.main_menu.root") - .Provider("aetheria", "game.menu") - .TitleSubtitle("AETHERIA", "TERMINUS") - .ButtonColumn("aetheria.main_menu.root.actions", actions => actions - .Button("Continue", "aetheria.main_menu.root.continue") - .Button("New Game", "aetheria.main_menu.root.new_game") - .Button("Settings", "aetheria.main_menu.root.show_settings") - .Button("Quit", "aetheria.main_menu.root.quit")) - .Style("font.title.family", "Montserrat") - .Style("font.body.family", "Ubuntu") - .UpdatedAtUtc("2026-07-01T00:00:00.0000000Z") - .Build(); - - surface.ProviderId.Should().Be("aetheria"); - surface.ProviderKind.Should().Be("game.menu"); - surface.Title.Should().Be("AETHERIA TERMINUS"); - surface.UpdatedAtUtc.Should().Be("2026-07-01T00:00:00.0000000Z"); - surface.Surface.Id.Should().Be("aetheria.main_menu.root"); - surface.Surface.Root.Kind.Should().Be("surface"); - surface.Surface.Styles.Select(style => style.Name).Should().Contain(["font.title.family", "font.body.family"]); - - var rootChildren = surface.Surface.Root.Children; - rootChildren[0].Kind.Should().Be("text.title"); - rootChildren[0].Props["value"].Should().Be("AETHERIA"); - rootChildren[1].Kind.Should().Be("text.subtitle"); - rootChildren[1].Props["value"].Should().Be("TERMINUS"); - - var actions = rootChildren[2]; - actions.Kind.Should().Be("column"); - actions.Children.Should().HaveCount(4); - actions.Children[2].Kind.Should().Be("control.button"); - actions.Children[2].Props["label"].Should().Be("Settings"); - actions.Children[2].Props["command"].Should().Be("aetheria.main_menu.root.show_settings"); - - surface.Commands.Select(command => command.Command).Should().Equal( - "aetheria.main_menu.root.continue", - "aetheria.main_menu.root.new_game", - "aetheria.main_menu.root.show_settings", - "aetheria.main_menu.root.quit"); - } - - [Test] - public void Form_ControlsCarryOperationAndStateBindings() - { - var nameOperation = CultMesh.OperationBinding("settings.player.name.set", "Set Player Name", "gamecult.settings.name.v1"); - var asteroidOperation = CultMesh.OperationBinding("settings.graphics.asteroids.toggle", "Toggle Asteroids"); - var nameBinding = new CultMeshStateBindingDescriptor( - "value", - "player.settings.name", - "global:aetheria.player_settings.v1", - "gamecult.aetheria.player_settings.v1"); - var asteroidBinding = new CultMeshStateBindingDescriptor( - "value", - "player.settings.show_asteroids", - "global:aetheria.player_settings.v1", - "gamecult.aetheria.player_settings.v1"); - - var surface = EveSurface.Create("aetheria.main_menu.player_settings") - .Form("aetheria.main_menu.player_settings.form", form => form - .Text("Name", "Meta", nameOperation, nameBinding) - .Toggle("Show Asteroids In Minimap", true, asteroidOperation, asteroidBinding) - .Metric("Significant Digits", "3")) - .Build(); - - var form = surface.Surface.Root.Children.Single(); - form.Kind.Should().Be("form"); - form.Children.Should().HaveCount(3); - - var name = form.Children[0]; - name.Kind.Should().Be("control.text"); - name.Props["label"].Should().Be("Name"); - name.Props["value"].Should().Be("Meta"); - name.Props["command"].Should().Be("settings.player.name.set"); - name.StateBindings.Single().PointerId.Should().Be("player.settings.name"); - - var toggle = form.Children[1]; - toggle.Kind.Should().Be("control.toggle"); - toggle.Props["value"].Should().Be("true"); - toggle.StateBindings.Single().PointerId.Should().Be("player.settings.show_asteroids"); - - surface.Commands.Select(command => command.Command).Should().Equal( - "settings.player.name.set", - "settings.graphics.asteroids.toggle"); - } - - [Test] - public void EmbeddedDocumentSlot_CarriesNestedSurfaceContract() - { - var surface = EveSurface.Create("station.inventory") - .EmbeddedDocument( - "cargo", - "daemon:aetheria.inventory.station.v1", - "gamecult.eve.surface.v1", - "inventory.grid", - new CultMeshRouteHint(CultMeshLocalityKind.SharedMemory, "daemon-published CultUI surface")) - .Build(); - - var slot = surface.Surface.Root.Children.Single(); - slot.Kind.Should().Be("surface.slot"); - slot.EmbeddedDocuments.Should().ContainSingle(); - slot.EmbeddedDocuments[0].SlotId.Should().Be("cargo"); - slot.EmbeddedDocuments[0].DocumentId.Should().Be("daemon:aetheria.inventory.station.v1"); - slot.EmbeddedDocuments[0].SchemaId.Should().Be("gamecult.eve.surface.v1"); - slot.EmbeddedDocuments[0].RouteHint.Kind.Should().Be(nameof(CultMeshLocalityKind.SharedMemory)); - } - - [Test] - public void SurfaceDocument_RoundTripsThroughCultCacheMessagePack() - { - var surface = EveSurface.Create("aetheria.main_menu.player_settings") - .Provider("aetheria", "game.menu") - .TitleSubtitle("Gameplay", "Settings") - .Form("aetheria.main_menu.player_settings.form", form => form - .Text( - "Name", - "Meta", - CultMesh.OperationBinding("settings.player.name.set", "Set Player Name"), - new CultMeshStateBindingDescriptor( - "value", - "player.settings.name", - "global:aetheria.player_settings.v1", - "gamecult.aetheria.player_settings.v1"))) - .Build(); - - var payload = CultDocumentMessagePackSerialization.Serialize(surface); - var roundTrip = CultDocumentMessagePackSerialization.Deserialize(payload); - - roundTrip.Surface.Id.Should().Be(surface.Surface.Id); - roundTrip.Surface.Root.Children[2].Children.Single().StateBindings.Single().PointerId - .Should().Be("player.settings.name"); - roundTrip.Commands.Single().Command.Should().Be("settings.player.name.set"); - } -}