Task 2 of the acdream UI Studio plan. Adds three new files under src/AcDream.App/Studio/ and one new test file: - StudioOptions.cs: record + Parse() for the ui-studio CLI args (positional dat dir or ACDREAM_DAT_DIR, --layout 0xNNNN, --markup <path>; defaults to vitals 0x2100006C when neither layout nor markup given). - LayoutSource.cs: wraps LayoutImporter.Import for dat-backed layouts; markup path sets LastError "markup unsupported (Task 6)" and returns null for now. Exposes Kind / LayoutId / MarkupPath / LastError / CurrentLayout / Reload(). - StudioWindow.cs: Silk.NET 1280×720 GL 4.3 window; boots RenderBootstrap, wires input to UiHost, loads the panel via LayoutSource, adds the root to UiHost.Root.AddChild. QualitySettings resolved the same way GameWindow.Run() does (SettingsStore → QualitySettings.From → WithEnvOverrides). - Program.cs: ui-studio dispatch at the top of top-level statements (before the dat-dir parse) so `dotnet run -- ui-studio` routes to StudioWindow. - LayoutSourceTests.cs: dat-gated test (skips when dats absent); verifies that the vitals LayoutDesc (0x2100006C) loads, root is non-null, byId contains the vitals root element (0x100005F9), and Kind == DatLayout. Passes (1/1 with dats present; silently skips on CI). Note: the spec asserts FindElement(0x2100006Cu) — that id is the LayoutDesc dat id, not a widget element id. The actual vitals root element id is 0x100005F9 (confirmed from the vitals_2100006C.json fixture). The test uses the correct element id and documents the discrepancy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
60 lines
2.5 KiB
C#
60 lines
2.5 KiB
C#
using AcDream.App.Studio;
|
|
using AcDream.App.UI;
|
|
using AcDream.App.UI.Layout;
|
|
using DatReaderWriter;
|
|
using DatReaderWriter.Options;
|
|
|
|
namespace AcDream.App.Tests.Studio;
|
|
|
|
/// <summary>
|
|
/// Unit tests for <see cref="LayoutSource"/>. The dat-backed test skips cleanly
|
|
/// when the real dats are not present (CI / dev machines without AC installed).
|
|
/// </summary>
|
|
public class LayoutSourceTests
|
|
{
|
|
private static (uint handle, int width, int height) NoTex(uint _) => (1u, 1, 1);
|
|
|
|
/// <summary>Resolve the client dat directory, or null if unavailable (skip the test).</summary>
|
|
private static string? ResolveDatDir()
|
|
{
|
|
var fromEnv = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR");
|
|
if (!string.IsNullOrWhiteSpace(fromEnv) && Directory.Exists(fromEnv))
|
|
return fromEnv;
|
|
var def = Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
|
"Documents", "Asheron's Call");
|
|
return Directory.Exists(def) ? def : null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load the vitals LayoutDesc (0x2100006C) from the real dats and verify
|
|
/// that LayoutSource returns a non-null root with the layout id findable.
|
|
/// Skips when the dats are unavailable.
|
|
///
|
|
/// Note: the spec asserts FindElement(0x2100006Cu) — that is the layout dat
|
|
/// id, not an element id in the widget tree. The actual vitals root element id
|
|
/// is 0x100005F9 (confirmed from vitals_2100006C.json fixture). We assert
|
|
/// FindElement(0x100005F9) here which verifies the same integration path: the
|
|
/// layout was successfully loaded and the element dict was populated.
|
|
/// </summary>
|
|
[Fact]
|
|
public void LoadsDatLayout_byId()
|
|
{
|
|
var dir = ResolveDatDir();
|
|
if (dir is null)
|
|
return; // Skip: dats not available on this machine / CI.
|
|
|
|
using var dats = new DatCollection(dir, DatAccessType.Read);
|
|
|
|
var src = new LayoutSource(dats, NoTex, datFont: null);
|
|
var root = src.Load(new StudioOptions(dir, 0x2100006Cu, null));
|
|
|
|
// root must be non-null: Import found the LayoutDesc and built the tree.
|
|
Assert.NotNull(root);
|
|
Assert.NotNull(src.CurrentLayout);
|
|
// The vitals root element id is 0x100005F9 (layout dat id 0x2100006C ≠ element id).
|
|
// Asserting FindElement verifies the byId dict was populated by the importer.
|
|
Assert.NotNull(src.CurrentLayout!.FindElement(0x100005F9u));
|
|
Assert.Equal(LayoutSourceKind.DatLayout, src.Kind);
|
|
}
|
|
}
|