diff --git a/packages/org.gamecult.eve.surface/Runtime/EveSurfaceBuilder.cs b/packages/org.gamecult.eve.surface/Runtime/EveSurfaceBuilder.cs
new file mode 100644
index 0000000..6418b4e
--- /dev/null
+++ b/packages/org.gamecult.eve.surface/Runtime/EveSurfaceBuilder.cs
@@ -0,0 +1,377 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using GameCult.Mesh;
+
+#nullable enable
+
+namespace GameCult.Eve.Surface
+{
+ ///
+ /// Fluent CultUI/Eve surface builder. Eve owns the surface document; CultMesh only supplies typed binding descriptors.
+ ///
+ 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 EveCommandTemplate(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 EveCommandTemplate(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)
+ }));
+ return this;
+ }
+
+ public EveSurfaceBuilder Style(string name, string value)
+ {
+ _styles.Add(new EveStyleToken(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(EveCommandTemplate 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 EveCommandTemplate(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 EveCommandTemplate(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 EveCommandTemplate(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 EveCommandTemplate(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[] { 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[] { 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/packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs b/packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs
index bdfb19f..9a52ea9 100644
--- a/packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs
+++ b/packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs
@@ -1,12 +1,33 @@
using System;
using System.Collections.Generic;
+using GameCult.Caching;
+using GameCult.Mesh;
+using MessagePack;
#nullable enable
namespace GameCult.Eve.Surface
{
+ [CultDocument("gamecult.eve.surface", "gamecult.eve.surface.v1")]
+ [MessagePackObject]
public sealed class EveSurfaceDocument
{
+ public const string DefaultType = "surface-state";
+ public const string SchemaId = "gamecult.eve.surface.v1";
+
+ public EveSurfaceDocument(
+ string providerId,
+ string providerKind,
+ string title,
+ long version,
+ string updatedAtUtc,
+ EveSurfaceTree surface,
+ IReadOnlyList commands)
+ : this(DefaultType, SchemaId, providerId, providerKind, title, version, updatedAtUtc, surface, commands)
+ {
+ }
+
+ [SerializationConstructor]
public EveSurfaceDocument(
string type,
string schema,
@@ -18,52 +39,67 @@ namespace GameCult.Eve.Surface
EveSurfaceTree surface,
IReadOnlyList commands)
{
- Type = type;
- Schema = schema;
- ProviderId = providerId;
- ProviderKind = providerKind;
- Title = title;
+ Type = string.IsNullOrWhiteSpace(type) ? DefaultType : type;
+ Schema = string.IsNullOrWhiteSpace(schema) ? SchemaId : schema;
+ ProviderId = providerId ?? "";
+ ProviderKind = providerKind ?? "";
+ Title = title ?? "";
Version = version;
- UpdatedAtUtc = updatedAtUtc;
- Surface = surface;
- Commands = commands;
+ UpdatedAtUtc = updatedAtUtc ?? "";
+ Surface = surface ?? throw new ArgumentNullException(nameof(surface));
+ Commands = commands ?? Array.Empty();
}
+ [Key(0)]
public string Type { get; }
+ [Key(1)]
public string Schema { get; }
+ [Key(2)]
public string ProviderId { get; }
+ [Key(3)]
public string ProviderKind { get; }
+ [Key(4)]
public string Title { get; }
+ [Key(5)]
public long Version { get; }
+ [Key(6)]
public string UpdatedAtUtc { get; }
+ [Key(7)]
public EveSurfaceTree Surface { get; }
+ [Key(8)]
public IReadOnlyList Commands { get; }
}
+ [MessagePackObject]
public sealed class EveSurfaceTree
{
+ [SerializationConstructor]
public EveSurfaceTree(string id, EveSurfaceComponent root, IReadOnlyList styles)
{
- Id = id;
- Root = root;
- Styles = 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(
@@ -71,54 +107,156 @@ namespace GameCult.Eve.Surface
string kind,
IReadOnlyDictionary props,
IReadOnlyList children)
+ : this(id, kind, props, children, StateBindingsFromProps(props))
{
- Id = id;
- Kind = kind;
- Props = props;
- Children = children;
}
+ 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; }
+
public string GetProp(string key, string fallback = "")
{
return Props.TryGetValue(key, out var value) ? value : fallback;
}
+
+ 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(new CultMeshStateBindingDescriptor(targetProp, prop.Value));
+ }
+
+ return bindings;
+ }
}
- public sealed class EveStyleToken
+ [MessagePackObject]
+ public sealed class EveEmbeddedDocumentSlot
{
- public EveStyleToken(string name, string value)
+ [SerializationConstructor]
+ public EveEmbeddedDocumentSlot(
+ string slotId,
+ string documentId,
+ string schemaId,
+ string presentationKind,
+ CultMeshRouteHint? routeHint = null)
{
- Name = name;
- Value = value;
+ SlotId = slotId ?? "";
+ DocumentId = documentId ?? "";
+ SchemaId = schemaId ?? "";
+ PresentationKind = presentationKind ?? "";
+ RouteHint = routeHint ?? CultMeshRouteHint.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 CultMeshRouteHint RouteHint { get; }
+ }
+
+ [MessagePackObject]
+ public sealed class EveStyleToken
+ {
+ [SerializationConstructor]
+ public EveStyleToken(string name, string value)
+ {
+ Name = name ?? "";
+ Value = value ?? "";
+ }
+
+ [Key(0)]
public string Name { get; }
+ [Key(1)]
public string Value { get; }
}
+ [MessagePackObject]
public sealed class EveCommandTemplate
{
- public EveCommandTemplate(string command, string label, string transport)
+ [SerializationConstructor]
+ public EveCommandTemplate(CultMeshOperationBindingDescriptor operation)
{
- Command = command;
- Label = label;
- Transport = transport;
+ Operation = operation ?? throw new ArgumentNullException(nameof(operation));
}
- public string Command { get; }
+ [Key(0)]
+ public CultMeshOperationBindingDescriptor Operation { get; }
- public string Label { get; }
+ [IgnoreMember]
+ public string Command => Operation.OperationId;
- public string Transport { get; }
+ [IgnoreMember]
+ public string Label => Operation.Label;
+
+ [IgnoreMember]
+ public string Transport => Operation.RouteHint.Description ?? "";
}
public sealed class EveSurfaceCommandRequest
@@ -126,15 +264,15 @@ namespace GameCult.Eve.Surface
public EveSurfaceCommandRequest(
string providerId,
string surfaceId,
- string command,
- IReadOnlyDictionary payload,
+ CultMeshOperationInvocationDescriptor operation,
+ CultMeshOperationPayload payload,
DateTimeOffset issuedAt,
string clientId)
{
ProviderId = providerId;
SurfaceId = surfaceId;
- Command = command;
- Payload = payload;
+ Operation = operation ?? throw new ArgumentNullException(nameof(operation));
+ Payload = payload ?? CultMeshOperationPayload.Empty;
IssuedAt = issuedAt;
ClientId = clientId;
}
@@ -143,9 +281,11 @@ namespace GameCult.Eve.Surface
public string SurfaceId { get; }
- public string Command { get; }
+ public CultMeshOperationInvocationDescriptor Operation { get; }
- public IReadOnlyDictionary Payload { get; }
+ public string Command => Operation.OperationId;
+
+ public CultMeshOperationPayload Payload { get; }
public DateTimeOffset IssuedAt { get; }
diff --git a/packages/org.gamecult.eve.surface/Runtime/GameCult.Eve.Surface.asmdef b/packages/org.gamecult.eve.surface/Runtime/GameCult.Eve.Surface.asmdef
index d8f56be..8041c88 100644
--- a/packages/org.gamecult.eve.surface/Runtime/GameCult.Eve.Surface.asmdef
+++ b/packages/org.gamecult.eve.surface/Runtime/GameCult.Eve.Surface.asmdef
@@ -1,12 +1,18 @@
{
"name": "GameCult.Eve.Surface",
"rootNamespace": "GameCult.Eve.Surface",
- "references": [],
+ "references": [
+ "GameCult.Mesh"
+ ],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
- "overrideReferences": false,
- "precompiledReferences": [],
+ "overrideReferences": true,
+ "precompiledReferences": [
+ "GameCult.Caching.dll",
+ "GameCult.Mesh.dll",
+ "MessagePack.Annotations.dll"
+ ],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
diff --git a/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs b/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs
index f73fc28..d28fb8f 100644
--- a/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs
+++ b/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs
@@ -42,6 +42,29 @@ namespace GameCult.Eve.UnityUIToolkit
foreach (var child in component.Children)
element.Add(LowerComponent(child, document, commandSink));
+ foreach (var slot in component.EmbeddedDocuments)
+ {
+ var nested = LowerEmbeddedDocument(slot, commandSink);
+ if (nested != null)
+ element.Add(nested);
+ }
+
+ return element;
+ }
+
+ private VisualElement? LowerEmbeddedDocument(
+ EveEmbeddedDocumentSlot slot,
+ Action? commandSink)
+ {
+ var document = _options.EmbeddedDocumentResolver?.Invoke(slot);
+ if (document == null)
+ return null;
+
+ var element = LowerComponent(document.Surface.Root, document, commandSink);
+ element.name = SafeName(string.IsNullOrWhiteSpace(slot.SlotId) ? document.Surface.Id : slot.SlotId);
+ element.AddToClassList("eve-embedded-document");
+ element.AddToClassList($"eve-embedded-kind-{SafeClass(slot.PresentationKind)}");
+ ApplyStyleTokens(element, document.Surface.Styles);
return element;
}
@@ -129,7 +152,7 @@ namespace GameCult.Eve.UnityUIToolkit
{
["value"] = evt.newValue ?? ""
};
- EmitCommand(document, component, command, payload, commandSink);
+ EmitCommand(document, component, command, GameCult.Mesh.CultMesh.OperationPayload(payload), commandSink);
});
return field;
}
@@ -155,7 +178,7 @@ namespace GameCult.Eve.UnityUIToolkit
document,
component,
command,
- new Dictionary(component.Props, StringComparer.Ordinal),
+ GameCult.Mesh.CultMesh.OperationPayload(component.Props),
commandSink);
}
@@ -163,7 +186,7 @@ namespace GameCult.Eve.UnityUIToolkit
EveSurfaceDocument document,
EveSurfaceComponent component,
string command,
- IReadOnlyDictionary payload,
+ GameCult.Mesh.CultMeshOperationPayload payload,
Action? commandSink)
{
if (commandSink == null || string.IsNullOrWhiteSpace(command))
@@ -172,12 +195,25 @@ namespace GameCult.Eve.UnityUIToolkit
commandSink(new EveSurfaceCommandRequest(
document.ProviderId,
document.Surface.Id,
- command,
+ ResolveOperation(document, command),
payload,
DateTimeOffset.UtcNow,
"unity-uitoolkit"));
}
+ private static GameCult.Mesh.CultMeshOperationInvocationDescriptor ResolveOperation(
+ EveSurfaceDocument document,
+ string command)
+ {
+ foreach (var template in document.Commands)
+ {
+ if (string.Equals(template.Command, command, StringComparison.Ordinal))
+ return GameCult.Mesh.CultMesh.OperationInvocation(template.Operation);
+ }
+
+ return GameCult.Mesh.CultMesh.OperationInvocation(command);
+ }
+
private static Label TitleLabel(string text)
{
var label = new Label(text);