Reframe Unity plugins as projection adapters
This commit is contained in:
parent
f9711c3532
commit
4712f7c7f8
22 changed files with 274 additions and 86 deletions
|
|
@ -25,8 +25,8 @@ The target shape:
|
|||
- Owner repos: Sai owns VN/Ink, Norn owns graph semantics, providers such as
|
||||
Aetheria own live state and authored product surfaces.
|
||||
- Runtime repos: EveUnity, EveFlutter, EveAndroid, EveIOS, EveGodot, EveElectron,
|
||||
Fensalir/Direct2D, and future bodies own projection, build glue, plugin host
|
||||
adapters, capture, and runtime tests.
|
||||
Fensalir/Direct2D, and future bodies own projection, build glue, plugin
|
||||
projection adapters, capture, and runtime tests.
|
||||
- EveConformance: fixture corpus, parity runner, capability matrix,
|
||||
screenshot/report artifacts, plugin packs, and CI once the harness is stable
|
||||
enough to leave Eve core.
|
||||
|
|
@ -208,10 +208,11 @@ Purpose: let runtime repos own native projection without losing conformance.
|
|||
|
||||
Work:
|
||||
|
||||
- EveFlutter: provider picker, command transport, plugin host, Android/iOS/desktop
|
||||
build flow, native capture, and parity reports.
|
||||
- EveUnity: UPM package release, plugin host behavior, resolver-backed embedded
|
||||
documents, Unity test/capture lifecycle, and Aetheria consumption.
|
||||
- EveFlutter: provider picker, command transport, plugin projection adapters,
|
||||
Android/iOS/desktop build flow, native capture, and parity reports.
|
||||
- EveUnity: UPM package release, plugin projection adapter behavior,
|
||||
resolver-backed embedded documents, Unity test/capture lifecycle, and Aetheria
|
||||
consumption.
|
||||
- EveAndroid: Kotlin device edge, generic surface traversal, sensor publishing,
|
||||
Android-specific CI, and explicit discovery input.
|
||||
- EveIOS: UIKit renderer, sensor edge release flow, fixed-device and simulator
|
||||
|
|
@ -284,28 +285,29 @@ Recently cut:
|
|||
parity harness validates release, test, and capture lifecycle claims against
|
||||
`tools/parity/parity-manifest.json`, checks declared evidence paths, and
|
||||
exports lifecycle status through the conformance index. Current proof covers
|
||||
incubating UPM package identity and the Aetheria consumer-build smoke; tagged
|
||||
EveUnity release, Unity EditMode/PlayMode tests, and editor or batchmode
|
||||
capture remain explicit split blockers.
|
||||
incubating UPM package identity, authored package EditMode tests, and the
|
||||
Aetheria consumer-build smoke; tagged EveUnity release, runtime-owned
|
||||
batchmode test execution, and editor or batchmode capture remain explicit
|
||||
split blockers.
|
||||
- Aetheria now has repeatable Unity package consumer-build evidence for the
|
||||
Eve UI Toolkit runtime. `scripts/run-aetheria-unity-package-smoke.ps1`
|
||||
verifies Aetheria's Unity `Packages/manifest.json` consumes Eve's surface and
|
||||
UI Toolkit packages by file reference, checks the generated
|
||||
`GameCult.Eve.UnityUIToolkit.csproj` includes all current runtime files, and
|
||||
builds the package through Aetheria's Unity-generated project.
|
||||
- Unity UI Toolkit now has a first-party `norn.graph` plugin-host proof for
|
||||
`embed.norn`. `NornGraphUiToolkitPluginHost` owns the native embedded graph
|
||||
shell and graph command emission path, while Norn keeps graph layout and graph
|
||||
semantics. EveUnity split-readiness is now blocked on runtime-owned release,
|
||||
test, and capture lifecycle evidence rather than missing Sai/Norn plugin
|
||||
support.
|
||||
- Unity UI Toolkit now has a first-party `sai.vn` plugin-host proof. The
|
||||
runtime owns `IEveUiToolkitPluginHost`, registers
|
||||
`SaiVisualNovelUiToolkitPluginHost` through `EveUiToolkitSurfaceOptions`, and
|
||||
declares support for `vn.stage`, `story.choose`, `story.continue`, and
|
||||
`story.jump` in its runtime capability manifest. Sai still owns story state
|
||||
and command semantics; Unity only lowers the visual stage/dialogue/action
|
||||
surface and emits Eve command requests.
|
||||
- Unity UI Toolkit now has a first-party `norn.graph` projection-adapter proof
|
||||
for `embed.norn`. `NornGraphUiToolkitProjectionAdapter` owns the native
|
||||
embedded graph shell and graph command emission path, while the Norn sidecar
|
||||
plugin keeps graph layout and graph semantics. EveUnity split-readiness is now
|
||||
blocked on runtime-owned release, test, and capture lifecycle evidence rather
|
||||
than missing Sai/Norn projection support.
|
||||
- Unity UI Toolkit now has a first-party `sai.vn` projection-adapter proof. The
|
||||
runtime owns `IEveUiToolkitPluginProjectionAdapter`, registers
|
||||
`SaiVisualNovelUiToolkitProjectionAdapter` through
|
||||
`EveUiToolkitSurfaceOptions`, and declares support for `vn.stage`,
|
||||
`story.choose`, `story.continue`, and `story.jump` in its runtime capability
|
||||
manifest. Sai still owns story state and command semantics; Unity only lowers
|
||||
the visual stage/dialogue/action surface and emits Eve command requests.
|
||||
- Unity UI Toolkit now publishes a runtime-owned capability manifest at
|
||||
`packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json`. The
|
||||
parity harness validates that manifest against
|
||||
|
|
@ -324,9 +326,10 @@ Recently cut:
|
|||
- The parity harness now emits an `EveConformance`-shaped export under
|
||||
`artifacts/conformance/latest`, with a top-level index and per-pack JSON
|
||||
files for core, plugin, provider, and runtime consumers.
|
||||
- Unity's plugin-host capability gap is now explicitly demoted. The UI Toolkit
|
||||
runtime owns generic projection and command requests, while Sai, Norn, and
|
||||
TeX semantics remain unsupported until a real Unity plugin host exists.
|
||||
- Unity's plugin projection capability gap is now explicitly demoted. The UI
|
||||
Toolkit runtime owns generic projection and command requests, while Sai, Norn,
|
||||
and TeX semantics remain sidecar-plugin responsibilities. Unity only adds
|
||||
projection adapters for capabilities a plugin advertises through Eve.
|
||||
- Flutter and Unity now have runtime command-transport smoke evidence in the
|
||||
parity report. Flutter emits `gamecult.eve.command.v1` intents from lowered
|
||||
controls, and Unity command requests now carry the same command schema.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ coordinate split-readiness, but the runtime body must publish the capability
|
|||
claim it expects other repos to consume.
|
||||
|
||||
Unity UI Toolkit currently uses this path for its `sai.vn` and `norn.graph`
|
||||
plugin-host proofs while leaving `tex.math` as explicit unsupported plugin
|
||||
plugin projection adapter proofs while leaving `tex.math` as explicit unsupported plugin
|
||||
semantics.
|
||||
|
||||
## Run
|
||||
|
|
@ -78,7 +78,8 @@ The semantic runner writes:
|
|||
|
||||
The conformance export includes runtime `capabilityManifestPath` and
|
||||
`capabilityManifestErrors` fields so external consumers can distinguish a
|
||||
generic projection runtime from a runtime that actually hosts plugin semantics.
|
||||
generic projection runtime from a runtime that can project plugin-declared
|
||||
capabilities.
|
||||
|
||||
After generating the parity report, `run-parity-harness.ps1` copies
|
||||
`artifacts/conformance/latest` into
|
||||
|
|
@ -121,7 +122,8 @@ The parity harness validates those lifecycle claims against
|
|||
exist. The current lifecycle proof is deliberately split:
|
||||
|
||||
- release: incubating UPM package identity and import surface exist in Eve;
|
||||
- test: Aetheria can build the package through Unity's generated project;
|
||||
- test: package-owned EditMode tests are authored and Aetheria can build the
|
||||
package through Unity's generated project;
|
||||
- capture: Unity editor or batchmode capture remains a split blocker.
|
||||
|
||||
The smoke runner writes:
|
||||
|
|
|
|||
|
|
@ -45,8 +45,9 @@ Renderer clients own:
|
|||
- input capture and command emission;
|
||||
- local sensor/media capture when relevant;
|
||||
- runtime-specific capability gaps;
|
||||
- runtime capability manifests that declare supported features, plugin-host
|
||||
support, unsupported plugin semantics, command transport, and split metadata;
|
||||
- runtime capability manifests that declare supported features, plugin projection
|
||||
adapter support, unsupported plugin projections, command transport, and split
|
||||
metadata;
|
||||
- screenshots, frame capture, and performance telemetry.
|
||||
|
||||
Providers own:
|
||||
|
|
@ -129,7 +130,7 @@ Allowed implementation forms:
|
|||
- process sidecar;
|
||||
- WASM module hosted by an Eve runtime;
|
||||
- native dynamic library behind the same ABI when performance demands it;
|
||||
- in-process package only when wrapped by the same plugin host interface.
|
||||
- in-process package only when wrapped by the same executable plugin ABI.
|
||||
|
||||
Forbidden integration:
|
||||
|
||||
|
|
@ -196,7 +197,7 @@ Example ABI response:
|
|||
```
|
||||
|
||||
If a provider and plugin are written in the same language, the provider may run
|
||||
the plugin host in-process for performance. It still talks to the same ABI
|
||||
the plugin runtime in-process for performance. It still talks to the same ABI
|
||||
object model. No special trusted back door.
|
||||
|
||||
### Example Plugin Manifest
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Anything else is guilty until it can explain why it protects a core invariant.
|
|||
## Graduation Rules
|
||||
|
||||
- A runtime splits when it has its own build/deploy lifecycle, platform SDK pain,
|
||||
plugin host behavior, capture pipeline, or release cadence.
|
||||
plugin projection behavior, capture pipeline, or release cadence.
|
||||
- A plugin splits when it owns domain semantics, fixtures, and conformance cases.
|
||||
- A product demo splits when it carries product-specific state, assets, flows,
|
||||
receipts, or deployment authority.
|
||||
|
|
@ -37,7 +37,7 @@ Anything else is guilty until it can explain why it protects a core invariant.
|
|||
- `Sai`: owner for the VN/Ink plugin once `sai.vn` graduates.
|
||||
- `Norn`: owner for graph plugin semantics once `norn.graph` graduates.
|
||||
- `EveUnity`, `EveGodot`, `EveFlutter`, `EveElectron`, and similar runtime
|
||||
repos: native projection, platform build glue, plugin host, captures, and
|
||||
repos: native projection, platform build glue, plugin projection adapters, captures, and
|
||||
runtime tests.
|
||||
- `EveConformance`: fixture corpus, parity runner, capability matrix,
|
||||
screenshot/report artifacts, plugin packs, and CI orchestration once the
|
||||
|
|
|
|||
|
|
@ -7,14 +7,15 @@ It owns native projection only. Providers still own truth, accepted state,
|
|||
style token values, and command effects through CultMesh/CultNet. Unknown
|
||||
component kinds degrade to inert containers instead of gaining local semantics.
|
||||
|
||||
Plugin semantics enter through runtime plugin hosts. The package includes a
|
||||
first-party `sai.vn` host proof for `vn.stage`, dialogue panels, action rails,
|
||||
and story command projection. Sai still owns story state and command semantics;
|
||||
Unity only owns native projection and emits `gamecult.eve.command.v1` requests.
|
||||
The package also includes a `norn.graph` host proof for `embed.norn`; Norn still
|
||||
owns graph layout and graph semantics, while Unity owns the embedded graph shell
|
||||
and command emission. `tex.math` still passes through as generic Eve component
|
||||
structure until it gains an explicit Unity plugin host.
|
||||
Plugin semantics enter through plugin ABI sidecars and advertisements, not
|
||||
through Unity. This package includes first-party projection adapters for the
|
||||
`sai.vn` projection surface (`vn.stage`, dialogue panels, action rails, and
|
||||
story command requests) and the `norn.graph` projection surface (`embed.norn`).
|
||||
Sai still owns story state and command semantics. Norn still owns graph layout
|
||||
and graph semantics. Unity only owns native projection of already-declared
|
||||
plugin capabilities and emits `gamecult.eve.command.v1` requests. `tex.math`
|
||||
still passes through as generic Eve component structure until it gains an
|
||||
explicit Unity projection adapter.
|
||||
|
||||
This package lives in the Eve repository as the shared Unity lowering target.
|
||||
Aetheria and other Unity consumers should import it from Eve instead of
|
||||
|
|
@ -37,7 +38,8 @@ The runtime capability manifest is
|
|||
evidence:
|
||||
|
||||
- release: incubating UPM package identity and import surface;
|
||||
- test: Aetheria consumer-build smoke through Unity's generated project;
|
||||
- test: package-owned EditMode tests plus Aetheria consumer-build smoke through
|
||||
Unity's generated project;
|
||||
- capture: pending Unity editor or batchmode artifact.
|
||||
|
||||
Those lifecycle claims are validated by the parity harness. A missing evidence
|
||||
|
|
|
|||
|
|
@ -76,9 +76,9 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
EveSurfaceDocument document,
|
||||
Action<EveSurfaceCommandRequest>? commandSink)
|
||||
{
|
||||
var pluginHost = _options.FindPluginHost(component);
|
||||
if (pluginHost != null)
|
||||
return pluginHost.Lower(component, document, commandSink);
|
||||
var projectionAdapter = _options.FindPluginProjectionAdapter(component);
|
||||
if (projectionAdapter != null)
|
||||
return projectionAdapter.Lower(component, document, commandSink);
|
||||
|
||||
switch (NormalizeKind(component.Kind))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,23 +13,23 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
|
||||
public EveUiToolkitSurfaceOptions(
|
||||
Func<EveEmbeddedDocumentSlot, EveSurfaceDocument?>? embeddedDocumentResolver = null,
|
||||
IReadOnlyList<IEveUiToolkitPluginHost>? pluginHosts = null)
|
||||
IReadOnlyList<IEveUiToolkitPluginProjectionAdapter>? pluginProjectionAdapters = null)
|
||||
{
|
||||
EmbeddedDocumentResolver = embeddedDocumentResolver;
|
||||
PluginHosts = pluginHosts ?? new IEveUiToolkitPluginHost[]
|
||||
PluginProjectionAdapters = pluginProjectionAdapters ?? new IEveUiToolkitPluginProjectionAdapter[]
|
||||
{
|
||||
new SaiVisualNovelUiToolkitPluginHost(),
|
||||
new NornGraphUiToolkitPluginHost()
|
||||
new SaiVisualNovelUiToolkitProjectionAdapter(),
|
||||
new NornGraphUiToolkitProjectionAdapter()
|
||||
};
|
||||
}
|
||||
|
||||
public Func<EveEmbeddedDocumentSlot, EveSurfaceDocument?>? EmbeddedDocumentResolver { get; }
|
||||
|
||||
public IReadOnlyList<IEveUiToolkitPluginHost> PluginHosts { get; }
|
||||
public IReadOnlyList<IEveUiToolkitPluginProjectionAdapter> PluginProjectionAdapters { get; }
|
||||
|
||||
public IEveUiToolkitPluginHost? FindPluginHost(EveSurfaceComponent component)
|
||||
public IEveUiToolkitPluginProjectionAdapter? FindPluginProjectionAdapter(EveSurfaceComponent component)
|
||||
{
|
||||
return PluginHosts.FirstOrDefault(host => host.CanLower(component));
|
||||
return PluginProjectionAdapters.FirstOrDefault(adapter => adapter.CanLower(component));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using UnityEngine.UIElements;
|
|||
|
||||
namespace GameCult.Eve.UnityUIToolkit
|
||||
{
|
||||
public interface IEveUiToolkitPluginHost
|
||||
public interface IEveUiToolkitPluginProjectionAdapter
|
||||
{
|
||||
string PluginId { get; }
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ using UnityEngine.UIElements;
|
|||
|
||||
namespace GameCult.Eve.UnityUIToolkit
|
||||
{
|
||||
public sealed class NornGraphUiToolkitPluginHost : IEveUiToolkitPluginHost
|
||||
public sealed class NornGraphUiToolkitProjectionAdapter : IEveUiToolkitPluginProjectionAdapter
|
||||
{
|
||||
public string PluginId => "norn.graph";
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
Action<EveSurfaceCommandRequest>? commandSink)
|
||||
{
|
||||
var graph = new VisualElement();
|
||||
graph.AddToClassList("eve-plugin-host");
|
||||
graph.AddToClassList("eve-plugin-projection");
|
||||
graph.AddToClassList("eve-plugin-norn-graph");
|
||||
graph.AddToClassList("norn-graph");
|
||||
graph.style.flexDirection = FlexDirection.Column;
|
||||
|
|
@ -9,7 +9,7 @@ using UnityEngine.UIElements;
|
|||
|
||||
namespace GameCult.Eve.UnityUIToolkit
|
||||
{
|
||||
public sealed class SaiVisualNovelUiToolkitPluginHost : IEveUiToolkitPluginHost
|
||||
public sealed class SaiVisualNovelUiToolkitProjectionAdapter : IEveUiToolkitPluginProjectionAdapter
|
||||
{
|
||||
public string PluginId => "sai.vn";
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
private static VisualElement Stage(EveSurfaceComponent component)
|
||||
{
|
||||
var stage = new VisualElement();
|
||||
stage.AddToClassList("eve-plugin-host");
|
||||
stage.AddToClassList("eve-plugin-projection");
|
||||
stage.AddToClassList("eve-plugin-sai-vn");
|
||||
stage.AddToClassList("sai-vn-stage");
|
||||
stage.style.flexGrow = 1;
|
||||
|
|
@ -86,7 +86,7 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
private static VisualElement DialoguePanel(EveSurfaceComponent component)
|
||||
{
|
||||
var panel = new VisualElement();
|
||||
panel.AddToClassList("eve-plugin-host");
|
||||
panel.AddToClassList("eve-plugin-projection");
|
||||
panel.AddToClassList("eve-plugin-sai-vn");
|
||||
panel.AddToClassList("sai-vn-dialogue");
|
||||
panel.style.flexDirection = FlexDirection.Column;
|
||||
|
|
@ -114,7 +114,7 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
private static VisualElement DialogueText(EveSurfaceComponent component)
|
||||
{
|
||||
var text = new Label(component.GetProp("text"));
|
||||
text.AddToClassList("eve-plugin-host");
|
||||
text.AddToClassList("eve-plugin-projection");
|
||||
text.AddToClassList("eve-plugin-sai-vn");
|
||||
text.AddToClassList("sai-vn-dialogue-text");
|
||||
return text;
|
||||
|
|
@ -123,7 +123,7 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
private static VisualElement ActionRail()
|
||||
{
|
||||
var rail = new VisualElement();
|
||||
rail.AddToClassList("eve-plugin-host");
|
||||
rail.AddToClassList("eve-plugin-projection");
|
||||
rail.AddToClassList("eve-plugin-sai-vn");
|
||||
rail.AddToClassList("sai-vn-actions");
|
||||
rail.style.flexDirection = FlexDirection.Row;
|
||||
|
|
@ -139,7 +139,7 @@ namespace GameCult.Eve.UnityUIToolkit
|
|||
var label = component.GetProp("label", component.GetProp("title", "Continue"));
|
||||
var command = StoryCommand(component);
|
||||
var button = new Button(() => EmitStoryCommand(document, component, command, commandSink)) { text = label };
|
||||
button.AddToClassList("eve-plugin-host");
|
||||
button.AddToClassList("eve-plugin-projection");
|
||||
button.AddToClassList("eve-plugin-sai-vn");
|
||||
button.AddToClassList("sai-vn-story-command");
|
||||
button.AddToClassList($"sai-vn-command-{SafeClass(command)}");
|
||||
8
packages/org.gamecult.eve.unity-uitoolkit/Tests.meta
Normal file
8
packages/org.gamecult.eve.unity-uitoolkit/Tests.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 694b4921723a4d56a9f0f72ad2240feb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: acfcd889183e4bfbac82f8883deef300
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GameCult.Eve.Surface;
|
||||
using GameCult.Mesh;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace GameCult.Eve.UnityUIToolkit.Tests
|
||||
{
|
||||
public sealed class EveUiToolkitSurfaceLowererTests
|
||||
{
|
||||
[Test]
|
||||
public void DefaultOptionsExposeSaiAndNornProjectionAdapters()
|
||||
{
|
||||
var options = EveUiToolkitSurfaceOptions.Default;
|
||||
|
||||
Assert.That(options.FindPluginProjectionAdapter(Component("stage", "vn.stage"))?.PluginId, Is.EqualTo("sai.vn"));
|
||||
Assert.That(options.FindPluginProjectionAdapter(Component("graph", "embed.norn"))?.PluginId, Is.EqualTo("norn.graph"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SaiStageLowersThroughRuntimeProjectionAdapter()
|
||||
{
|
||||
var document = Document(Component(
|
||||
"stage",
|
||||
"vn.stage",
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["storyId"] = "sai.fixture",
|
||||
["currentPath"] = "intro"
|
||||
}));
|
||||
|
||||
var root = new EveUiToolkitSurfaceLowerer().Lower(document);
|
||||
|
||||
Assert.That(root.ClassListContains("eve-plugin-projection"), Is.True);
|
||||
Assert.That(root.ClassListContains("eve-plugin-sai-vn"), Is.True);
|
||||
Assert.That(root.ClassListContains("sai-vn-stage"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NornGraphLowersThroughRuntimeProjectionAdapter()
|
||||
{
|
||||
var document = Document(Component(
|
||||
"graph",
|
||||
"embed.norn",
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["label"] = "World graph",
|
||||
["mode"] = "embedded"
|
||||
}));
|
||||
|
||||
var root = new EveUiToolkitSurfaceLowerer().Lower(document);
|
||||
|
||||
Assert.That(root.ClassListContains("eve-plugin-projection"), Is.True);
|
||||
Assert.That(root.ClassListContains("eve-plugin-norn-graph"), Is.True);
|
||||
Assert.That(root.ClassListContains("norn-graph"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EmbeddedDocumentSlotMountsResolverBackedChildSurface()
|
||||
{
|
||||
var child = Document(
|
||||
Component("child-root", "text", new Dictionary<string, string> { ["text"] = "Nested surface" }),
|
||||
surfaceId: "child-surface");
|
||||
var parentRoot = new EveSurfaceComponent(
|
||||
"parent-root",
|
||||
"surface",
|
||||
EmptyProps(),
|
||||
Array.Empty<EveSurfaceComponent>(),
|
||||
Array.Empty<CultMeshStateBindingDescriptor>(),
|
||||
new[]
|
||||
{
|
||||
new EveEmbeddedDocumentSlot(
|
||||
"child-slot",
|
||||
"child-surface",
|
||||
EveSurfaceDocument.SchemaId,
|
||||
"inline")
|
||||
});
|
||||
var lowerer = new EveUiToolkitSurfaceLowerer(new EveUiToolkitSurfaceOptions(
|
||||
embeddedDocumentResolver: _ => child,
|
||||
pluginProjectionAdapters: Array.Empty<IEveUiToolkitPluginProjectionAdapter>()));
|
||||
|
||||
var root = lowerer.Lower(Document(parentRoot));
|
||||
var embedded = root.Query<VisualElement>(className: "eve-embedded-document").First();
|
||||
|
||||
Assert.That(embedded, Is.Not.Null);
|
||||
Assert.That(embedded.name, Is.EqualTo("child-slot"));
|
||||
Assert.That(embedded.ClassListContains("eve-embedded-kind-inline"), Is.True);
|
||||
}
|
||||
|
||||
private static EveSurfaceDocument Document(EveSurfaceComponent root, string surfaceId = "test-surface")
|
||||
{
|
||||
return new EveSurfaceDocument(
|
||||
"gamecult.eve.unity.tests",
|
||||
"runtime.test",
|
||||
"Unity UI Toolkit tests",
|
||||
1,
|
||||
"2026-07-08T00:00:00Z",
|
||||
new EveSurfaceTree(surfaceId, root, Array.Empty<EveStyleToken>()),
|
||||
Array.Empty<EveCommandTemplate>());
|
||||
}
|
||||
|
||||
private static EveSurfaceComponent Component(
|
||||
string id,
|
||||
string kind,
|
||||
IReadOnlyDictionary<string, string>? props = null)
|
||||
{
|
||||
return new EveSurfaceComponent(
|
||||
id,
|
||||
kind,
|
||||
props ?? EmptyProps(),
|
||||
Array.Empty<EveSurfaceComponent>());
|
||||
}
|
||||
|
||||
private static IReadOnlyDictionary<string, string> EmptyProps()
|
||||
{
|
||||
return new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2921e30d39fe49098bc3763c538ed67c
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "GameCult.Eve.UnityUIToolkit.Tests",
|
||||
"rootNamespace": "GameCult.Eve.UnityUIToolkit.Tests",
|
||||
"references": [
|
||||
"GameCult.Eve.UnityUIToolkit",
|
||||
"GameCult.Eve.Surface",
|
||||
"GameCult.Mesh"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 353e1aea044b46ac98835959a19fe0ac
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
"ownerRepo": "EveUnity",
|
||||
"currentHostRepo": "Eve",
|
||||
"splitTarget": "EveUnity",
|
||||
"graduationTrigger": "Split when Unity package has independent UPM release, plugin host behavior, and Unity test/capture lifecycle."
|
||||
"graduationTrigger": "Split when Unity package has independent UPM release, plugin projection adapter behavior, and Unity test/capture lifecycle."
|
||||
},
|
||||
"supportedFeatures": [
|
||||
"embeddedDocuments"
|
||||
|
|
@ -21,20 +21,20 @@
|
|||
"story.continue",
|
||||
"story.jump"
|
||||
],
|
||||
"host": "SaiVisualNovelUiToolkitPluginHost"
|
||||
"projectionAdapter": "SaiVisualNovelUiToolkitProjectionAdapter"
|
||||
},
|
||||
{
|
||||
"pluginId": "norn.graph",
|
||||
"capabilities": [
|
||||
"embed.norn"
|
||||
],
|
||||
"host": "NornGraphUiToolkitPluginHost"
|
||||
"projectionAdapter": "NornGraphUiToolkitProjectionAdapter"
|
||||
}
|
||||
],
|
||||
"unsupportedPlugins": [
|
||||
{
|
||||
"pluginId": "tex.math",
|
||||
"reason": "Unity UI Toolkit currently preserves embed.tex as generic Eve structure; no TeX render plugin host exists in this runtime."
|
||||
"reason": "Unity UI Toolkit currently preserves embed.tex as generic Eve structure; no TeX projection adapter exists in this runtime."
|
||||
}
|
||||
],
|
||||
"commandTransport": {
|
||||
|
|
@ -59,13 +59,15 @@
|
|||
},
|
||||
"test": {
|
||||
"ownerRepo": "EveUnity",
|
||||
"status": "consumer-build-smoke",
|
||||
"status": "authored-editmode-tests-and-consumer-build-smoke",
|
||||
"command": "powershell -ExecutionPolicy Bypass -File .\\scripts\\run-aetheria-unity-package-smoke.ps1",
|
||||
"evidencePaths": [
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/GameCult.Eve.UnityUIToolkit.Tests.asmdef",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs",
|
||||
"scripts/run-aetheria-unity-package-smoke.ps1"
|
||||
],
|
||||
"pendingProofs": [
|
||||
"Unity EditMode or PlayMode test assembly runs from the runtime repo."
|
||||
"Unity EditMode or PlayMode test assembly runs from the runtime repo in batchmode."
|
||||
]
|
||||
},
|
||||
"capture": {
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ $project = Get-Content -Raw -LiteralPath $unityToolkitProject
|
|||
$requiredCompileItems = @(
|
||||
"Runtime\EveUiToolkitSurfaceOptions.cs",
|
||||
"Runtime\EveUiToolkitSurfaceLowerer.cs",
|
||||
"Runtime\IEveUiToolkitPluginHost.cs",
|
||||
"Runtime\SaiVisualNovelUiToolkitPluginHost.cs",
|
||||
"Runtime\NornGraphUiToolkitPluginHost.cs"
|
||||
"Runtime\IEveUiToolkitPluginProjectionAdapter.cs",
|
||||
"Runtime\SaiVisualNovelUiToolkitProjectionAdapter.cs",
|
||||
"Runtime\NornGraphUiToolkitProjectionAdapter.cs"
|
||||
)
|
||||
foreach ($compileItem in $requiredCompileItems) {
|
||||
$expected = Join-Path $eveRoot "packages\org.gamecult.eve.unity-uitoolkit\$compileItem"
|
||||
|
|
|
|||
|
|
@ -428,7 +428,7 @@
|
|||
],
|
||||
"pendingProofs": [
|
||||
"Tagged UPM release is cut from EveUnity rather than Eve incubation.",
|
||||
"Unity EditMode or PlayMode test assembly runs from the runtime repo.",
|
||||
"Unity EditMode or PlayMode test assembly runs from the runtime repo in batchmode.",
|
||||
"Unity batchmode or editor capture artifact is attached to the runtime conformance report."
|
||||
]
|
||||
}
|
||||
|
|
@ -478,7 +478,7 @@
|
|||
"ownerRepo": "Eve",
|
||||
"repoRole": "runtime-incubating",
|
||||
"splitTarget": "EveFlutter",
|
||||
"graduationTrigger": "Split when Flutter has provider picker, command transport, plugin host, and its own build/release lifecycle.",
|
||||
"graduationTrigger": "Split when Flutter has provider picker, command transport, plugin projection adapters, and its own build/release lifecycle.",
|
||||
"requiredFixtures": ["embedded-surface"],
|
||||
"pluginFixtures": ["sai-vn"],
|
||||
"supportedFeatures": ["embeddedDocuments"],
|
||||
|
|
@ -603,7 +603,7 @@
|
|||
"ownerRepo": "Eve",
|
||||
"repoRole": "runtime-incubating",
|
||||
"splitTarget": "EveFlutter",
|
||||
"graduationTrigger": "Split with EveFlutter when Android APK smoke, provider discovery, command transport, and plugin host are runtime-owned.",
|
||||
"graduationTrigger": "Split with EveFlutter when Android APK smoke, provider discovery, command transport, and plugin projection adapters are runtime-owned.",
|
||||
"requiredFixtures": ["embedded-surface"],
|
||||
"pluginFixtures": ["sai-vn"],
|
||||
"supportedFeatures": ["embeddedDocuments"],
|
||||
|
|
@ -677,7 +677,7 @@
|
|||
"ownerRepo": "Eve",
|
||||
"repoRole": "runtime-incubating",
|
||||
"splitTarget": "EveUnity",
|
||||
"graduationTrigger": "Split when Unity package has independent UPM release, plugin host behavior, and Unity test/capture lifecycle.",
|
||||
"graduationTrigger": "Split when Unity package has independent UPM release, plugin projection adapter behavior, and Unity test/capture lifecycle.",
|
||||
"capabilityManifest": {
|
||||
"schemaPath": "schemas/gamecult.eve.runtime_capability.v1.schema.json",
|
||||
"manifestPath": "packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json"
|
||||
|
|
@ -698,31 +698,37 @@
|
|||
"unsupportedPlugins": [
|
||||
{
|
||||
"pluginId": "tex.math",
|
||||
"reason": "Unity UI Toolkit currently preserves embed.tex as generic Eve structure; no TeX render plugin host exists in this runtime."
|
||||
"reason": "Unity UI Toolkit currently preserves embed.tex as generic Eve structure; no TeX projection adapter exists in this runtime."
|
||||
}
|
||||
],
|
||||
"expectedPaths": [
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/IEveUiToolkitPluginHost.cs",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/SaiVisualNovelUiToolkitPluginHost.cs",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/NornGraphUiToolkitPluginHost.cs"
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/IEveUiToolkitPluginProjectionAdapter.cs",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/SaiVisualNovelUiToolkitProjectionAdapter.cs",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/NornGraphUiToolkitProjectionAdapter.cs",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/GameCult.Eve.UnityUIToolkit.Tests.asmdef",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs"
|
||||
],
|
||||
"expectedSourceSymbols": [
|
||||
{
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs",
|
||||
"contains": ["LowerEmbeddedDocument(", "EmbeddedDocuments", "eve-embedded-document", "FindPluginHost", "pluginHost.Lower"]
|
||||
"contains": ["LowerEmbeddedDocument(", "EmbeddedDocuments", "eve-embedded-document", "FindPluginProjectionAdapter", "projectionAdapter.Lower"]
|
||||
},
|
||||
{
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/IEveUiToolkitPluginHost.cs",
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/IEveUiToolkitPluginProjectionAdapter.cs",
|
||||
"contains": ["PluginId", "Capabilities", "CanLower", "Lower("]
|
||||
},
|
||||
{
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/SaiVisualNovelUiToolkitPluginHost.cs",
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/SaiVisualNovelUiToolkitProjectionAdapter.cs",
|
||||
"contains": ["sai.vn", "vn.stage", "story.choose", "story.continue", "story.jump", "StoryButton", "EmitStoryCommand", "EveSurfaceCommandRequest", "sai-vn-stage", "sai-vn-dialogue", "sai-vn-actions"]
|
||||
},
|
||||
{
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/NornGraphUiToolkitPluginHost.cs",
|
||||
"contains": ["norn.graph", "embed.norn", "NornGraphUiToolkitPluginHost", "norn-graph", "EmitGraphCommand", "EveSurfaceCommandRequest"]
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/NornGraphUiToolkitProjectionAdapter.cs",
|
||||
"contains": ["norn.graph", "embed.norn", "NornGraphUiToolkitProjectionAdapter", "norn-graph", "EmitGraphCommand", "EveSurfaceCommandRequest"]
|
||||
},
|
||||
{
|
||||
"path": "packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs",
|
||||
"contains": ["FindPluginProjectionAdapter", "SaiStageLowersThroughRuntimeProjectionAdapter", "NornGraphLowersThroughRuntimeProjectionAdapter", "EmbeddedDocumentSlotMountsResolverBackedChildSurface", "eve-plugin-projection"]
|
||||
}
|
||||
],
|
||||
"commandTransportSmoke": {
|
||||
|
|
@ -757,12 +763,14 @@
|
|||
},
|
||||
"test": {
|
||||
"ownerRepo": "EveUnity",
|
||||
"status": "consumer-build-smoke",
|
||||
"status": "authored-editmode-tests-and-consumer-build-smoke",
|
||||
"evidencePaths": [
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/GameCult.Eve.UnityUIToolkit.Tests.asmdef",
|
||||
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs",
|
||||
"scripts/run-aetheria-unity-package-smoke.ps1"
|
||||
],
|
||||
"pendingProofs": [
|
||||
"Unity EditMode or PlayMode test assembly runs from the runtime repo."
|
||||
"Unity EditMode or PlayMode test assembly runs from the runtime repo in batchmode."
|
||||
]
|
||||
},
|
||||
"capture": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue