Revert "Campaign V slice V4a" - it lost world multisampling

This reverts ceec3bc4. Two independent reasons, either sufficient.

The rendering regression. The slice deleted TextRenderGlStateScope, which
saved GL_MULTISAMPLE and GL_SAMPLE_ALPHA_TO_COVERAGE on entry, disabled them
for the text pass, and restored them on exit (TextRenderGlStateScope.cs:111-112
and 153-154 at the parent commit). Its replacement bakes that state into the
text pipeline but nothing restores it, and GlGpuPassEncoder.Dispose does not
either. Every world renderer is still raw GL at this point in the campaign, so
from the first UI frame onward the world drew with multisampling disabled.

The offline pixel gate caught it: 1,791 of 563,200 compared pixels differed,
0.318% against a 0.001 threshold. The commit message attributed this to
wall-clock-driven ambient animation shifting phase, and committed through the
failure. That explanation does not survive its own control: capturing twice at
the reverted-to commit differs by 19 pixels and twice at the slice's own commit
by 8, while base-versus-head differs by 1,791 - a 224x gap that no shared-noise
source explains. An amplified difference image settles it visually: the changed
pixels are the silhouette edges of every tree, building and rock, with terrain
interiors, water and the entire UI untouched. That is the signature of losing
edge antialiasing, not of animated sprites.

This is the exact failure mode two existing memory notes already warn about -
a mid-frame renderer must set every GL state it uses rather than inherit it,
and issue #52's lesson that a rendering migration must audit per-pass GL state
before declaring itself done.

The scope. The brief was three small leaf renderers plus additive frame-
lifecycle wiring, roughly ten files. The commit changed 334 files with 3,665
insertions and 3,845 deletions, including 323 public-to-internal visibility
conversions across the App assembly, 55 test files, two retired conformance
tests, and a self-described temporary escape hatch for bridging raw-GL viewport
textures. Even without the regression, that is not separable into the part
worth keeping and the part worth dropping.

Reverting rather than patching because the good work here - the RHI frame
lifecycle wiring and a genuine render-state-cache staleness fix - is small
enough to redo cleanly against a tightened spec, while untangling it from 300+
files of unrelated churn is not.

Post-revert: Release build clean, App suite back to 3,843 passed / 3 skipped,
offline pixel gate passing at 19 differing pixels.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-27 18:27:52 +02:00
parent ceec3bc440
commit 9aaf97e785
334 changed files with 3841 additions and 3661 deletions

View file

@ -159,7 +159,6 @@ public sealed class HostInputCameraCompositionTests
{
public GpuFrameFlightController? GpuFrames { get; private set; }
public IGpuDevice? GpuDevice { get; private set; }
public GpuDeviceFrameLifetime? GpuFrameLifetime { get; private set; }
public SilkKeyboardSource? Keyboard { get; private set; }
public SilkMouseSource? Mouse { get; private set; }
public IMouseLookCursor? Cursor { get; private set; }
@ -173,9 +172,6 @@ public sealed class HostInputCameraCompositionTests
public void PublishGpuDevice(IGpuDevice value) =>
GpuDevice = PublishOnce(GpuDevice, value);
public void PublishGpuFrameLifetime(GpuDeviceFrameLifetime value) =>
GpuFrameLifetime = PublishOnce(GpuFrameLifetime, value);
public void PublishKeyboardSource(SilkKeyboardSource value) =>
Keyboard = PublishOnce(Keyboard, value);

View file

@ -189,10 +189,9 @@ public sealed class InteractionRetainedUiCompositionTests
Dependencies = new InteractionRetainedUiDependencies(
Options: options,
Gl: null!,
GpuDevice: null!,
CurrentGpuFrame: null!,
Window: null!,
Input: null!,
ShadersDirectory: "shaders",
Dats: null!,
DatLock: new object(),
TextureCache: null!,

View file

@ -218,7 +218,6 @@ public sealed class SettingsDevToolsCompositionTests
null!,
null!,
null!,
null!,
null,
null,
null,

View file

@ -2,10 +2,8 @@ using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using AcDream.App.Composition;
using AcDream.App.Rendering;
using AcDream.App.Rendering.Gpu;
using AcDream.App.Rendering.Wb;
using AcDream.App.Rendering.Residency;
using AcDream.App.Tests.Rendering.Gpu;
using AcDream.App.World;
using AcDream.Content;
using AcDream.Core.Physics;
@ -161,7 +159,6 @@ public sealed class WorldRenderCompositionTests
Factory = new Factory(hasFont);
Publication = new Publication(publicationFailure);
Lifetime = new RenderLifetime(Factory.Atlas);
GpuDevice = new RecordingGpuDevice();
var content = (ContentEffectsAudioResult)
RuntimeHelpers.GetUninitializedObject(typeof(ContentEffectsAudioResult));
Content = content;
@ -170,7 +167,6 @@ public sealed class WorldRenderCompositionTests
public Factory Factory { get; }
public Publication Publication { get; }
public RenderLifetime Lifetime { get; }
public RecordingGpuDevice GpuDevice { get; }
public List<WorldRenderCompositionPoint> Points { get; } = [];
public ContentEffectsAudioResult Content { get; }
@ -180,7 +176,6 @@ public sealed class WorldRenderCompositionTests
new WorldEnvironmentController(),
Lifetime,
ImmediateGpuResourceRetirementQueue.Instance,
GpuDevice,
_budgets,
0xA9B4FFFFu,
Path.Combine(Path.GetTempPath(), "acdream-tests"),
@ -253,15 +248,15 @@ public sealed class WorldRenderCompositionTests
public SceneLightingUboBinding CreateSceneLighting(GL gl) =>
Resource<SceneLightingUboBinding>("scene lighting");
public DebugLineRenderer CreateDebugLines(IGpuDevice device) =>
public DebugLineRenderer CreateDebugLines(GL gl, string shadersDirectory) =>
Resource<DebugLineRenderer>("debug lines");
public byte[]? TryLoadDebugFont() => hasFont ? [1] : null;
public BitmapFont CreateDebugFont(IGpuDevice device, byte[] bytes) =>
public BitmapFont CreateDebugFont(GL gl, byte[] bytes) =>
Resource<BitmapFont>("debug font");
public TextRenderer CreateTextRenderer(IGpuDevice device) =>
public TextRenderer CreateTextRenderer(GL gl, string shadersDirectory) =>
Resource<TextRenderer>("text renderer");
public TerrainModernRenderer CreateTerrain(
@ -300,7 +295,6 @@ public sealed class WorldRenderCompositionTests
public TextureCache CreateTextureCache(
GL gl,
IGpuDevice device,
IDatReaderWriter dats,
BindlessSupport bindless,
IGpuResourceRetirementQueue retirement,

View file

@ -2,4 +2,3 @@ global using AcDream.Runtime.Gameplay;
global using AcDream.Runtime.Physics;
global using ILocalPlayerMotionSource =
AcDream.Runtime.Gameplay.IRuntimeLocalPlayerMotionSource;
global using AcDream.App.Rendering.Gpu;

View file

@ -104,13 +104,8 @@ public sealed class GlTextureOwnershipTests
root, "src", "AcDream.App", "Rendering", "ShaderProgramConstruction.cs"));
string terrain = File.ReadAllText(Path.Combine(
root, "src", "AcDream.App", "Rendering", "TerrainAtlas.cs"));
// Campaign V slice V4a ported TextRenderer/BitmapFont off raw GL onto
// IGpuDevice: neither file creates a GL texture name directly anymore.
// The checked-commit-boundary invariant this test enforces now lives in
// the RHI's GlGpuTexture, which every ported (and legacy) texture path
// shares.
string gpuTexture = File.ReadAllText(Path.Combine(
root, "src", "AcDream.App", "Rendering", "Gpu", "Gl", "GlGpuTexture.cs"));
string text = File.ReadAllText(Path.Combine(
root, "src", "AcDream.App", "Rendering", "TextRenderer.cs"));
string bindless = File.ReadAllText(Path.Combine(
root, "src", "AcDream.App", "Rendering", "Wb", "BindlessSupport.cs"));
@ -121,8 +116,8 @@ public sealed class GlTextureOwnershipTests
Assert.Contains("GlResourceCommand.DeleteProgram", shaderPrograms, StringComparison.Ordinal);
Assert.Contains("_anisotropyBindingMutation.Execute", terrain, StringComparison.Ordinal);
Assert.Contains("GlResourceCommand.DeleteTexture", terrain, StringComparison.Ordinal);
Assert.Contains("GlResourceCommand.CreateName", gpuTexture, StringComparison.Ordinal);
Assert.Contains("GLHelpers.ThrowOnResourceError", gpuTexture, StringComparison.Ordinal);
Assert.Contains("GlResourceCommand.CreateTexture", text, StringComparison.Ordinal);
Assert.Contains("GlResourceCommand.Execute", text, StringComparison.Ordinal);
Assert.Contains("make bindless handle", bindless, StringComparison.Ordinal);
Assert.Contains("GlResourceCommand.Execute", bindless, StringComparison.Ordinal);
}

View file

@ -14,8 +14,7 @@ public sealed class GlRenderStateCacheTests
GpuCullMode.Back,
GpuFrontFace.CounterClockwise,
AlphaToCoverage: false,
ColorWrite: true,
Multisample: false);
ColorWrite: true);
[Fact]
public void FirstApplyReportsEveryDimensionChanged()

View file

@ -49,12 +49,6 @@ public sealed class RenderFrameResourceControllerTests
{
string source = ResourceSource();
// TextRenderer (_worldText/_uiText) moved onto the IGpuDevice/IGpuFrame
// RHI in Campaign V slice V4a: it no longer has a per-slot BeginFrame
// step, so those two needles are retired from this ordering check.
// The remaining GL-only renderers (WbDrawDispatcher, EnvCellRenderer,
// terrain, sky/lighting) are untouched by V4a and keep their slot-based
// BeginFrame(gpuSlot) order.
AssertAppearsInOrder(
source,
"_textures?.BeginCompositeTextureFrame();",
@ -62,6 +56,8 @@ public sealed class RenderFrameResourceControllerTests
"_dispatcher?.BeginFrame(gpuSlot);",
"_environmentCells?.BeginFrame(gpuSlot);",
"_portalDepth?.BeginFrame(gpuSlot);",
"_worldText?.BeginFrame(gpuSlot);",
"_uiText?.BeginFrame(gpuSlot);",
"_clip?.BeginFrame(gpuSlot);",
"_terrain?.BeginFrame(gpuSlot);",
"_lighting?.BeginFrame(gpuSlot);");

View file

@ -130,13 +130,40 @@ public sealed class ResourceCleanupGroupTests
StringComparison.Ordinal);
}
// TextRendererPublishesEveryConstructorResourceBeforeLaterGlWork was retired
// by Campaign V slice V4a: TextRenderer no longer owns a Shader, per-flight
// FrameBufferSet array, white-texture fallback, or tracked VAO/VBO pair —
// it now borrows a shared IGpuDevice and owns exactly one IGpuPipeline
// created through it, so there is no multi-resource construction order left
// to assert. The equivalent GL-only invariant now lives in GlTextureOwnershipTests
// (GlGpuTexture's checked-commit texture creation).
[Fact]
public void TextRendererPublishesEveryConstructorResourceBeforeLaterGlWork()
{
string source = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Rendering",
"TextRenderer.cs"));
AssertAppearsInOrder(
source,
"shader = new Shader(gl,",
"resources.Add(\"text shader\", shader.Dispose);",
"frameBuffers[i] = CreateFrameBufferSet(resources);",
"whiteTexture = GlResourceCommand.CreateTexture(",
"resources.Add(",
"\"white texture\"",
"GlResourceCommand.Execute(",
"initialize TextRenderer white texture",
"resources.RetryCleanup();",
"_resources = resources;");
AssertAppearsInOrder(
source,
"private FrameBufferSet CreateFrameBufferSet(ResourceCleanupGroup resources)",
"TrackedGlResource.CreateVertexArray(",
"resources.Add(\"frame VAO\", vaoRelease.Run);",
"TrackedGlResource.CreateBuffer(",
"resources.Add(",
"\"frame VBO\"");
Assert.Contains("_resources.RetryCleanup();", source, StringComparison.Ordinal);
Assert.DoesNotContain("private FrameBufferSet CreateFrameBufferSet()", source,
StringComparison.Ordinal);
}
[Fact]
public void ReturnedNameIsRetainedWhenPostconditionAndFirstRollbackFail()

View file

@ -0,0 +1,217 @@
using System.Reflection;
using AcDream.App.Rendering;
using Silk.NET.OpenGL;
namespace AcDream.App.Tests.Rendering;
public sealed class TextRendererFailureSafetyTests
{
[Fact]
public void Flush_CompilesCompleteGlStateScopeAsFinallyAroundBothDrawLayers()
{
MethodInfo flush = typeof(TextRenderer).GetMethod(nameof(TextRenderer.Flush))!;
MethodBody body = flush.GetMethodBody()!;
string source = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Rendering",
"TextRenderer.cs"));
Assert.Contains(
body.ExceptionHandlingClauses,
clause => clause.Flags == ExceptionHandlingClauseOptions.Finally);
AssertAppearsInOrder(
source,
"using var stateScope = new TextRenderGlStateScope(_glState);",
"_gl.Disable(EnableCap.Multisample);",
"DrawLayer(_spriteSegs,",
"DrawLayer(_overlaySpriteSegs,");
}
[Fact]
public void FailedDraw_RestoresEveryGlValueMutatedByTheTextPass()
{
var gl = new RecordingGlState
{
DepthWrite = false,
BlendSourceRgb = BlendingFactor.DstAlpha,
BlendDestinationRgb = BlendingFactor.OneMinusDstAlpha,
BlendSourceAlpha = BlendingFactor.One,
BlendDestinationAlpha = BlendingFactor.Zero,
Program = 17,
VertexArray = 23,
ArrayBuffer = 31,
ActiveUnit = TextureUnit.Texture2,
};
gl.SetCapability(EnableCap.DepthTest, enabled: true);
gl.SetCapability(EnableCap.Blend, enabled: false);
gl.SetCapability(EnableCap.CullFace, enabled: true);
gl.SetCapability(EnableCap.SampleAlphaToCoverage, enabled: true);
gl.SetCapability(EnableCap.Multisample, enabled: false);
gl.TextureBindings[TextureUnit.Texture0] = 41;
gl.TextureBindings[TextureUnit.Texture2] = 43;
StateSnapshot expected = gl.Capture();
Action failedDraw = () =>
{
using var stateScope = new TextRenderGlStateScope(gl);
gl.SetCapability(EnableCap.DepthTest, enabled: false);
gl.SetCapability(EnableCap.Blend, enabled: true);
gl.SetCapability(EnableCap.CullFace, enabled: false);
gl.SetCapability(EnableCap.SampleAlphaToCoverage, enabled: false);
gl.SetCapability(EnableCap.Multisample, enabled: true);
gl.DepthMask(true);
gl.BlendFuncSeparate(
BlendingFactor.SrcAlpha,
BlendingFactor.OneMinusSrcAlpha,
BlendingFactor.SrcAlpha,
BlendingFactor.OneMinusSrcAlpha);
gl.UseProgram(101);
gl.BindVertexArray(103);
gl.BindBuffer(BufferTargetARB.ArrayBuffer, 107);
gl.ActiveTexture(TextureUnit.Texture0);
gl.BindTexture(TextureTarget.Texture2D, 109);
throw new InvalidOperationException("draw upload");
};
Assert.Throws<InvalidOperationException>(failedDraw);
Assert.Equal(expected, gl.Capture());
}
private readonly record struct StateSnapshot(
bool DepthTest,
bool Blend,
bool Cull,
bool AlphaToCoverage,
bool Multisample,
bool DepthWrite,
BlendingFactor BlendSourceRgb,
BlendingFactor BlendDestinationRgb,
BlendingFactor BlendSourceAlpha,
BlendingFactor BlendDestinationAlpha,
uint Program,
uint VertexArray,
uint ArrayBuffer,
TextureUnit ActiveUnit,
uint Texture0,
uint Texture2);
private sealed class RecordingGlState : ITextRenderGlStateApi
{
private readonly Dictionary<EnableCap, bool> _capabilities = [];
public bool DepthWrite { get; set; }
public BlendingFactor BlendSourceRgb { get; set; }
public BlendingFactor BlendDestinationRgb { get; set; }
public BlendingFactor BlendSourceAlpha { get; set; }
public BlendingFactor BlendDestinationAlpha { get; set; }
public uint Program { get; set; }
public uint VertexArray { get; set; }
public uint ArrayBuffer { get; set; }
public TextureUnit ActiveUnit { get; set; }
public Dictionary<TextureUnit, uint> TextureBindings { get; } = [];
public StateSnapshot Capture() => new(
IsEnabled(EnableCap.DepthTest),
IsEnabled(EnableCap.Blend),
IsEnabled(EnableCap.CullFace),
IsEnabled(EnableCap.SampleAlphaToCoverage),
IsEnabled(EnableCap.Multisample),
DepthWrite,
BlendSourceRgb,
BlendDestinationRgb,
BlendSourceAlpha,
BlendDestinationAlpha,
Program,
VertexArray,
ArrayBuffer,
ActiveUnit,
TextureBindings.GetValueOrDefault(TextureUnit.Texture0),
TextureBindings.GetValueOrDefault(TextureUnit.Texture2));
public bool IsEnabled(EnableCap capability) =>
_capabilities.GetValueOrDefault(capability);
public int GetInteger(GetPName parameter) => parameter switch
{
GetPName.BlendSrcRgb => (int)BlendSourceRgb,
GetPName.BlendDstRgb => (int)BlendDestinationRgb,
GetPName.BlendSrcAlpha => (int)BlendSourceAlpha,
GetPName.BlendDstAlpha => (int)BlendDestinationAlpha,
GetPName.CurrentProgram => (int)Program,
GetPName.VertexArrayBinding => (int)VertexArray,
GetPName.ArrayBufferBinding => (int)ArrayBuffer,
GetPName.ActiveTexture => (int)ActiveUnit,
GetPName.TextureBinding2D =>
(int)TextureBindings.GetValueOrDefault(ActiveUnit),
_ => throw new ArgumentOutOfRangeException(nameof(parameter)),
};
public bool GetBoolean(GetPName parameter) =>
parameter == GetPName.DepthWritemask
? DepthWrite
: throw new ArgumentOutOfRangeException(nameof(parameter));
public void SetCapability(EnableCap capability, bool enabled) =>
_capabilities[capability] = enabled;
public void DepthMask(bool enabled) => DepthWrite = enabled;
public void BlendFuncSeparate(
BlendingFactor sourceRgb,
BlendingFactor destinationRgb,
BlendingFactor sourceAlpha,
BlendingFactor destinationAlpha)
{
BlendSourceRgb = sourceRgb;
BlendDestinationRgb = destinationRgb;
BlendSourceAlpha = sourceAlpha;
BlendDestinationAlpha = destinationAlpha;
}
public void UseProgram(uint program) => Program = program;
public void BindVertexArray(uint vertexArray) => VertexArray = vertexArray;
public void BindBuffer(BufferTargetARB target, uint buffer)
{
Assert.Equal(BufferTargetARB.ArrayBuffer, target);
ArrayBuffer = buffer;
}
public void ActiveTexture(TextureUnit unit) => ActiveUnit = unit;
public void BindTexture(TextureTarget target, uint texture)
{
Assert.Equal(TextureTarget.Texture2D, target);
TextureBindings[ActiveUnit] = texture;
}
}
private static void AssertAppearsInOrder(string source, params string[] needles)
{
int cursor = -1;
foreach (string needle in needles)
{
int next = source.IndexOf(needle, cursor + 1, StringComparison.Ordinal);
Assert.True(next >= 0, $"Missing expected source fragment: {needle}");
Assert.True(next > cursor, $"Out-of-order source fragment: {needle}");
cursor = next;
}
}
private static string FindRepoRoot()
{
DirectoryInfo? directory = new(AppContext.BaseDirectory);
while (directory is not null)
{
if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx")))
return directory.FullName;
directory = directory.Parent;
}
throw new DirectoryNotFoundException("Could not find AcDream.slnx.");
}
}

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.Studio;
using AcDream.App.UI;
@ -32,7 +31,7 @@ public class DumpLayoutTests
"docs", "research", "2026-06-25-retail-ui-layout-dump.json");
}
private static (GpuTextureSlot, int, int) NoTex(uint _) => (new GpuTextureSlot(1), 1, 1);
private static (uint, int, int) NoTex(uint _) => (1u, 1, 1);
// ── Helpers ──────────────────────────────────────────────────────────

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.Studio;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -13,7 +12,7 @@ namespace AcDream.App.Tests.Studio;
/// </summary>
public class LayoutSourceTests
{
private static (GpuTextureSlot handle, int width, int height) NoTex(uint _) => (new GpuTextureSlot(1u), 1, 1);
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()

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.Core.Combat;
using AcDream.Core.Items;
@ -21,11 +20,11 @@ public sealed class CursorFeedbackControllerTests
var accept = c.Resolve(new CursorFeedbackSnapshot(
DragPayload: new object(),
DragAccept: DragAcceptState.Accept,
DragAccept: UiItemSlot.DragAcceptState.Accept,
HoverResizeEdges: ResizeEdges.Right));
var reject = c.Resolve(new CursorFeedbackSnapshot(
DragPayload: new object(),
DragAccept: DragAcceptState.Reject,
DragAccept: UiItemSlot.DragAcceptState.Reject,
HoverResizeEdges: ResizeEdges.Right));
Assert.Equal(CursorFeedbackKind.DragAccept, accept.Kind);
@ -212,7 +211,7 @@ public sealed class CursorFeedbackControllerTests
{
["Drag_rollover_accept"] = acceptCursor,
});
slot.SetItem(Target, iconTexture: new GpuTextureSlot(1u));
slot.SetItem(Target, iconTexture: 1u);
root.AddChild(slot);
root.OnMouseMove(20, 20);
var c = new CursorFeedbackController(interaction);

View file

@ -1,11 +1,10 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI.Layout;
namespace AcDream.App.Tests.UI;
public class DatWidgetFactoryZOrderTests
{
private static (GpuTextureSlot, int, int) NoChrome(uint id) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoChrome(uint id) => (0u, 0, 0);
[Fact]
public void ZOrder_HigherZLevel_DrawsBehind()

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using Xunit;
@ -41,7 +40,7 @@ public class DragDropSpineTests
[Fact]
public void UiItemList_registerDragHandler_roundtrips()
{
var list = new UiItemList(_ => (GpuTextureSlot.Unassigned, 0, 0));
var list = new UiItemList(_ => (0u, 0, 0));
Assert.Null(list.DragHandler);
var h = new SpyHandler();
list.RegisterDragHandler(h);
@ -57,7 +56,7 @@ public class DragDropSpineTests
public void GetDragPayload_boundCell_snapshotsFields()
{
var cell = new UiItemSlot { SlotIndex = 4, SourceKind = ItemDragSource.ShortcutBar };
cell.SetItem(0x5001u, new GpuTextureSlot(0x99u));
cell.SetItem(0x5001u, 0x99u);
var p = Assert.IsType<ItemDragPayload>(cell.GetDragPayload());
Assert.Equal(0x5001u, p.ObjId);
Assert.Equal(ItemDragSource.ShortcutBar, p.SourceKind);
@ -73,10 +72,10 @@ public class DragDropSpineTests
public void GetDragGhost_boundCell_returnsIconTuple()
{
var cell = new UiItemSlot { Width = 32, Height = 32 };
cell.SetItem(0x5001u, new GpuTextureSlot(0x99u));
cell.SetItem(0x5001u, 0x99u);
var g = cell.GetDragGhost();
Assert.NotNull(g);
Assert.Equal(new GpuTextureSlot(0x99u), g!.Value.tex);
Assert.Equal(0x99u, g!.Value.tex);
Assert.Equal(32, g.Value.w);
Assert.Equal(32, g.Value.h);
}
@ -85,16 +84,16 @@ public class DragDropSpineTests
public void GetDragGhost_prefersDedicatedUnderlayFreeTexture()
{
var cell = new UiItemSlot { Width = 36, Height = 36 }; // retail bag cell is larger than its icon
cell.SetItem(0x5001u, new GpuTextureSlot(0x99u), dragIconTexture: new GpuTextureSlot(0x77u));
cell.SetItem(0x5001u, 0x99u, dragIconTexture: 0x77u);
Assert.Equal((new GpuTextureSlot(0x77u), 32, 32), cell.GetDragGhost());
Assert.Equal(new GpuTextureSlot(0x99u), cell.IconTexture); // source cell keeps the full m_pIcon
Assert.Equal((0x77u, 32, 32), cell.GetDragGhost());
Assert.Equal(0x99u, cell.IconTexture); // source cell keeps the full m_pIcon
}
// ── cell drop-target: DragEnter overlay + DropReleased dispatch ──────────
private static (UiItemList list, UiItemSlot cell, SpyHandler h) ListWithHandler()
{
var list = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1)); // non-zero resolve so overlay draw is harmless
var list = new UiItemList(_ => (1u, 1, 1)); // non-zero resolve so overlay draw is harmless
var h = new SpyHandler();
list.RegisterDragHandler(h);
return (list, list.Cell, h);
@ -109,7 +108,7 @@ public class DragDropSpineTests
var (_, cell, h) = ListWithHandler();
h.Acceptance = ItemDragAcceptance.Accept;
cell.OnEvent(new UiEvent(0u, cell, UiEventType.DragEnter, Payload: SomePayload()));
Assert.Equal(DragAcceptState.Accept, cell.DragAcceptVisual);
Assert.Equal(UiItemSlot.DragAcceptState.Accept, cell.DragAcceptVisual);
}
[Fact]
@ -118,7 +117,7 @@ public class DragDropSpineTests
var (_, cell, h) = ListWithHandler();
h.Acceptance = ItemDragAcceptance.Reject;
cell.OnEvent(new UiEvent(0u, cell, UiEventType.DragEnter, Payload: SomePayload()));
Assert.Equal(DragAcceptState.Reject, cell.DragAcceptVisual);
Assert.Equal(UiItemSlot.DragAcceptState.Reject, cell.DragAcceptVisual);
}
[Fact]
@ -127,7 +126,7 @@ public class DragDropSpineTests
var (_, cell, h) = ListWithHandler();
h.Acceptance = ItemDragAcceptance.None;
cell.OnEvent(new UiEvent(0u, cell, UiEventType.DragEnter, Payload: SomePayload()));
Assert.Equal(DragAcceptState.None, cell.DragAcceptVisual);
Assert.Equal(UiItemSlot.DragAcceptState.None, cell.DragAcceptVisual);
}
[Fact]
@ -136,7 +135,7 @@ public class DragDropSpineTests
var (_, cell, h) = ListWithHandler();
cell.OnEvent(new UiEvent(0u, cell, UiEventType.DragEnter, Payload: SomePayload()));
cell.OnEvent(new UiEvent(0u, cell, UiEventType.DragOver, Payload: SomePayload()));
Assert.Equal(DragAcceptState.None, cell.DragAcceptVisual);
Assert.Equal(UiItemSlot.DragAcceptState.None, cell.DragAcceptVisual);
}
[Fact]
@ -180,16 +179,16 @@ public class DragDropSpineTests
root.OnMouseDown(UiMouseButton.Left, 10, 10);
root.OnMouseMove(20, 10); // BeginDrag → snapshot ghost
cell.Clear(); // simulate the lift emptying the source
Assert.Equal((new GpuTextureSlot(0x99u), 32, 32), root.DragGhostForTest);
Assert.Equal((0x99u, 32, 32), root.DragGhostForTest);
}
[Fact]
public void FinishDrag_overNothing_deliversNoDrop_butLiftStands()
{
var root = new UiRoot { Width = 800, Height = 600 };
var list = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1)) { Left = 0, Top = 0, Width = 32, Height = 32 };
var list = new UiItemList(_ => (1u, 1, 1)) { Left = 0, Top = 0, Width = 32, Height = 32 };
list.Cell.Width = 32; list.Cell.Height = 32;
list.Cell.SetItem(0x5001u, new GpuTextureSlot(0x99u));
list.Cell.SetItem(0x5001u, 0x99u);
var h = new SpyHandler();
list.RegisterDragHandler(h);
root.AddChild(list);
@ -238,10 +237,10 @@ public class DragDropSpineTests
private static (UiRoot root, UiItemList list, UiItemSlot cell) RootWithBoundSlot(uint itemId)
{
var root = new UiRoot { Width = 800, Height = 600 };
var list = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1)) { Left = 0, Top = 0, Width = 32, Height = 32 };
var list = new UiItemList(_ => (1u, 1, 1)) { Left = 0, Top = 0, Width = 32, Height = 32 };
// Tests don't run OnDraw (which sizes the cell), so size the cell explicitly.
list.Cell.Width = 32; list.Cell.Height = 32;
if (itemId != 0) list.Cell.SetItem(itemId, new GpuTextureSlot(0x99u));
if (itemId != 0) list.Cell.SetItem(itemId, 0x99u);
root.AddChild(list);
return (root, list, list.Cell);
}
@ -250,7 +249,7 @@ public class DragDropSpineTests
RootWithCatalogSlot(uint entryId)
{
var root = new UiRoot { Width = 800, Height = 600 };
var list = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1))
var list = new UiItemList(_ => (1u, 1, 1))
{
Left = 0,
Top = 0,
@ -263,7 +262,7 @@ public class DragDropSpineTests
EntryId = entryId,
Width = 32,
Height = 32,
SpriteResolve = _ => (new GpuTextureSlot(1u), 1, 1),
SpriteResolve = _ => (1u, 1, 1),
};
list.AddItem(cell);
root.AddChild(list);
@ -428,15 +427,15 @@ public class DragDropSpineTests
{
var cell = new UiItemSlot(); // no parent list → FindList() null
cell.OnEvent(new UiEvent(0u, cell, UiEventType.DragEnter, Payload: SomePayload()));
Assert.Equal(DragAcceptState.Reject, cell.DragAcceptVisual);
Assert.Equal(UiItemSlot.DragAcceptState.Reject, cell.DragAcceptVisual);
}
[Fact]
public void DragEnter_listWithoutHandler_defaultsToReject()
{
var list = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1)); // no RegisterDragHandler
var list = new UiItemList(_ => (1u, 1, 1)); // no RegisterDragHandler
list.Cell.OnEvent(new UiEvent(0u, list.Cell, UiEventType.DragEnter, Payload: SomePayload()));
Assert.Equal(DragAcceptState.Reject, list.Cell.DragAcceptVisual);
Assert.Equal(UiItemSlot.DragAcceptState.Reject, list.Cell.DragAcceptVisual);
}
// ── item drag inside a Draggable window (the LIVE toolbar topology) ──────
@ -450,9 +449,9 @@ public class DragDropSpineTests
{
var root = new UiRoot { Width = 800, Height = 600 };
var frame = new UiPanel { Left = 10, Top = 300, Width = 200, Height = 60, Draggable = true };
var list = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1)) { Left = 5, Top = 5, Width = 32, Height = 32 };
var list = new UiItemList(_ => (1u, 1, 1)) { Left = 5, Top = 5, Width = 32, Height = 32 };
list.Cell.Width = 32; list.Cell.Height = 32;
if (itemId != 0) list.Cell.SetItem(itemId, new GpuTextureSlot(0x99u));
if (itemId != 0) list.Cell.SetItem(itemId, 0x99u);
frame.AddChild(list);
root.AddChild(frame);
return (root, frame, list);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.Core.Combat;
using AcDream.Core.Items;
@ -252,7 +251,7 @@ public sealed class ItemInteractionControllerTests
});
h.GroundObject = chest;
var cell = new UiItemSlot();
cell.SetItem(itemId, GpuTextureSlot.Unassigned);
cell.SetItem(itemId, 0u);
var payload = new ItemDragPayload(itemId, ItemDragSource.Inventory, 0, cell);
Assert.True(h.Controller.PlaceIn3D(payload, chest));

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Numerics;
using AcDream.App.Spells;
using AcDream.Content;
@ -15,7 +14,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class AppraisalUiControllerTests
{
private const uint ObjectId = 0x50000001u;
private static (GpuTextureSlot, int, int) NoTexture(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTexture(uint _) => (0u, 0, 0);
[Fact]
public void ItemResponse_UsesAuthoredItemSubviewTitleAndScrollbars()
@ -742,11 +741,11 @@ public sealed class AppraisalUiControllerTests
() => { },
selection: selection,
spellbook: spellbook,
resolveSpellIcon: id => new GpuTextureSlot(id + 1_000u),
resolveSpellIcon: id => id + 1_000u,
resolveComponentIcon: did =>
{
resolvedComponentIcons.Add(did);
return new GpuTextureSlot(did + 2_000u);
return did + 2_000u;
},
spellComponents: _ => components,
magicSkill: _ => 200u,
@ -802,18 +801,14 @@ public sealed class AppraisalUiControllerTests
AppraisalUiController.SpellIconId)!;
UiTextureElement icon = Assert.Single(
iconHost.Children.OfType<UiTextureElement>());
Assert.Equal(new GpuTextureSlot(metadata.SpellId + 1_000u), icon.Texture);
Assert.Equal(metadata.SpellId + 1_000u, icon.Texture);
Assert.Equal(
new uint[] { 0x06000010u, 0x06000011u },
resolvedComponentIcons);
UiElement formula = layout.FindElement(
AppraisalUiController.SpellFormulaListId)!;
Assert.Equal(
new[]
{
new GpuTextureSlot(0x06000010u + 2_000u),
new GpuTextureSlot(0x06000011u + 2_000u),
},
new uint[] { 0x06000010u + 2_000u, 0x06000011u + 2_000u },
formula.Children
.OfType<UiDatElement>()
.Select(cell => cell.RuntimeImageTexture!.Value));
@ -833,8 +828,8 @@ public sealed class AppraisalUiControllerTests
SelectionState? selection = null,
RetailAppraisalNameResolver? itemNames = null,
Spellbook? spellbook = null,
Func<uint, GpuTextureSlot>? resolveSpellIcon = null,
Func<uint, GpuTextureSlot>? resolveComponentIcon = null,
Func<uint, uint>? resolveSpellIcon = null,
Func<uint, uint>? resolveComponentIcon = null,
Func<uint, IReadOnlyList<SpellExamineComponent>>? spellComponents = null,
Func<MagicSchool, uint>? magicSkill = null,
SpellExamineComponentTemplateFactory? spellComponentTemplates = null)

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System;
using System.Collections.Generic;
using System.IO;
@ -31,10 +30,10 @@ public sealed class CharacterLayoutImportProbe
if (datDir is null) return;
using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (new GpuTextureSlot(1u), 30, 26), null);
var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (1u, 30, 26), null);
Assert.NotNull(layout);
CharacterStatController.Bind(layout!, SampleData.SampleCharacter, spriteResolve: _ => (new GpuTextureSlot(1u), 30, 26));
CharacterStatController.Bind(layout!, SampleData.SampleCharacter, spriteResolve: _ => (1u, 30, 26));
var rows = new List<UiClickablePanel>();
CollectRows(layout!.Root, rows);
@ -62,7 +61,7 @@ public sealed class CharacterLayoutImportProbe
if (datDir is null) return;
using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (new GpuTextureSlot(1u), 30, 26), null);
var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (1u, 30, 26), null);
Assert.NotNull(layout);
var close = layout!.FindElement(WindowChromeController.CharacterCloseButtonId);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.Studio;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -282,7 +281,7 @@ public class CharacterStatControllerTests
var layout = Fake((CharacterStatController.ListBoxId, list));
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
var rows = list.Children.OfType<UiPanel>().ToList();
Assert.Equal(9, rows.Count);
@ -548,7 +547,7 @@ public class CharacterStatControllerTests
var layout = Fake((CharacterStatController.ListBoxId, list));
// Minimal sprite resolver — returns a fake non-zero handle so UiPanel draws it.
static (GpuTextureSlot, int, int) FakeResolve(uint id) => (new GpuTextureSlot(1), 32, 8);
static (uint, int, int) FakeResolve(uint id) => (1u, 32, 8);
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: FakeResolve);
@ -567,7 +566,7 @@ public class CharacterStatControllerTests
{
var list = new UiPanel();
var layout = Fake((CharacterStatController.ListBoxId, list));
static (GpuTextureSlot, int, int) FakeResolve(uint id) => (new GpuTextureSlot(1), 32, 8);
static (uint, int, int) FakeResolve(uint id) => (1u, 32, 8);
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: FakeResolve);
@ -792,7 +791,7 @@ public class CharacterStatControllerTests
Assert.Equal(3, titles.Children.Count);
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
Assert.Equal(rootChildCount, layout.Root.Children.Count);
Assert.Equal(RetailUiStateIds.Open, attributes.ActiveRetailStateId);
@ -815,7 +814,7 @@ public class CharacterStatControllerTests
var skills = Assert.IsType<UiText>(layout.FindElement(CharacterStatController.TabSkillsId));
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
skills.OnClick!();
Assert.Equal(RetailUiStateIds.Closed, attributes.ActiveRetailStateId);
@ -837,7 +836,7 @@ public class CharacterStatControllerTests
var layout = Fake((CharacterStatController.ListBoxId, list));
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
ClickTab(layout, left: 92f);
@ -892,7 +891,7 @@ public class CharacterStatControllerTests
var layout = Fake((CharacterStatController.ListBoxId, list));
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
ClickTab(layout, left: 92f);
Assert.Equal(12, SkillRows(list).Count);
@ -930,7 +929,7 @@ public class CharacterStatControllerTests
});
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
Assert.Equal("Strength", FirstRowName(visibleList));
Assert.Equal("<no row>", FirstRowName(hiddenDuplicateList));
@ -964,7 +963,7 @@ public class CharacterStatControllerTests
(CharacterStatController.FooterLine2Value, l2Value));
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
ClickTab(layout, left: 92f);
var rows = SkillRows(list);
@ -994,7 +993,7 @@ public class CharacterStatControllerTests
var requests = new List<CharacterStatController.RaiseRequest>();
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16),
spriteResolve: id => (id, 16, 16),
onRaiseRequest: (request, completed) => { requests.Add(request); completed(); });
ClickTab(layout, left: 92f);
@ -1028,7 +1027,7 @@ public class CharacterStatControllerTests
(CharacterStatController.RaiseOneId, btn1));
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
ClickTab(layout, left: 92f);
SkillRows(list)[5].OnClick!();
@ -1053,7 +1052,7 @@ public class CharacterStatControllerTests
var requests = new List<CharacterStatController.RaiseRequest>();
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16),
spriteResolve: id => (id, 16, 16),
onRaiseRequest: (request, completed) => { requests.Add(request); completed(); });
ClickTab(layout, left: 92f);
@ -1097,7 +1096,7 @@ public class CharacterStatControllerTests
var requests = new List<CharacterStatController.RaiseRequest>();
CharacterStatController.Bind(layout, () => sheet,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16),
spriteResolve: id => (id, 16, 16),
onRaiseRequest: (request, completed) =>
{
requests.Add(request);
@ -1150,7 +1149,7 @@ public class CharacterStatControllerTests
Action? completeRaise = null;
CharacterStatController.Bind(layout, () => sheet,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16),
spriteResolve: id => (id, 16, 16),
onRaiseRequest: (_, completed) => completeRaise = completed);
ClickTab(layout, left: 92f);
@ -1214,7 +1213,7 @@ public class CharacterStatControllerTests
});
CharacterStatController.Bind(layout, SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
ClickTab(layout, left: 92f);
@ -1538,7 +1537,7 @@ public class CharacterStatControllerTests
CharacterStatController.Bind(
layout,
SampleData.SampleCharacter,
spriteResolve: id => (new GpuTextureSlot(id), 16, 16));
spriteResolve: id => (id, 16, 16));
ApplyLayoutPass(layout.Root);
@ -1636,7 +1635,7 @@ public class CharacterStatControllerTests
Width = width,
Height = height,
};
return new UiDatElement(info, static _ => (GpuTextureSlot.Unassigned, 0, 0))
return new UiDatElement(info, static _ => (0u, 0, 0))
{
Top = top,
Width = width,
@ -1650,7 +1649,7 @@ public class CharacterStatControllerTests
var info = new ElementInfo { Id = id, Type = 1 };
info.StateMedia["Normal"] = (1u, 1);
info.StateMedia["Ghosted"] = (2u, 1);
return new UiButton(info, static _ => (GpuTextureSlot.Unassigned, 0, 0));
return new UiButton(info, static _ => (0u, 0, 0));
}
private static UiText MakeTab(uint id, float left)
@ -1677,7 +1676,7 @@ public class CharacterStatControllerTests
Name = "Open",
PassToChildren = true,
};
return Assert.IsType<UiText>(DatWidgetFactory.Create(info, static _ => (GpuTextureSlot.Unassigned, 0, 0), null));
return Assert.IsType<UiText>(DatWidgetFactory.Create(info, static _ => (0u, 0, 0), null));
}
private static ImportedLayout Fake(params (uint id, UiElement e)[] items)

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.Core.Chat;
@ -14,7 +13,7 @@ namespace AcDream.App.Tests.UI.Layout;
/// </summary>
public class ChatLayoutConformanceTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0, 0, 0);
private static ElementInfo? Find(ElementInfo n, uint id)
{

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Collections.Generic;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -22,7 +21,7 @@ namespace AcDream.App.Tests.UI.Layout;
public class ChatWindowControllerTests
{
// ── Null-resolve helper (no GL needed) ─────────────────────────────────
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0u, 0, 0);
// ── Capture bus — records every Publish call ────────────────────────────
private sealed class CaptureBus : ICommandBus

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -19,7 +18,7 @@ public sealed class CombatLayoutConformanceTests
ElementInfo info = FixtureLoader.LoadCombatInfos();
ImportedLayout layout = LayoutImporter.Build(
info,
_ => (GpuTextureSlot.Unassigned, 0, 0),
_ => (0u, 0, 0),
datFont: null,
stringResolve: _ => "localized");
ApplyAnchors(layout.Root);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.Combat;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -10,7 +9,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class CombatUiControllerTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0u, 0, 0);
[Fact]
public void CombatMode_ShowsPhysicalAndMagicPages_AndSelectsMediumByDefault()

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.Core.Items;
@ -131,7 +130,7 @@ public sealed class CreatureAppraisalRowsTests
{
var templates = new CreatureAppraisalRowTemplateFactory(
FixtureLoader.LoadExaminationRowTemplateInfos(),
_ => (GpuTextureSlot.Unassigned, 0, 0),
_ => (0u, 0, 0),
defaultFont: null);
var row = new CreatureAppraisalRow(
"Strength",

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -21,7 +20,7 @@ namespace AcDream.App.Tests.UI.Layout;
/// </summary>
public class DatWidgetFactoryFontResolveTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0, 0, 0);
// ── Test 1: null fontResolve → DatFont == datFont (backward-compat) ─────

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Numerics;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -6,7 +5,7 @@ namespace AcDream.App.Tests.UI.Layout;
public class DatWidgetFactoryTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0, 0, 0);
// ── Test 1: Type 7 → UiMeter ─────────────────────────────────────────────
@ -335,7 +334,7 @@ public class DatWidgetFactoryTests
public void Create_buildsUiItemList_forItemListClassId()
{
var info = new AcDream.App.UI.Layout.ElementInfo { Id = 0x100001A7u, Type = 0x10000031u, Width = 32, Height = 32 };
var w = AcDream.App.UI.Layout.DatWidgetFactory.Create(info, _ => (GpuTextureSlot.Unassigned, 0, 0), null);
var w = AcDream.App.UI.Layout.DatWidgetFactory.Create(info, _ => (0u, 0, 0), null);
Assert.IsType<AcDream.App.UI.UiItemList>(w);
}

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.Core.Spells;
@ -7,7 +6,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class EffectsUiControllerTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0u, 0, 0);
private static EffectRowTemplateFactory Templates()
=> new(FixtureLoader.LoadEffectRowTemplateInfos(), NoTex, defaultFont: null);
@ -48,7 +47,7 @@ public sealed class EffectsUiControllerTests
[EffectsUiController.InfoTextId] = info,
});
using EffectsUiController controller = EffectsUiController.Bind(
layout, spellbook, positive: true, () => 0d, NoTex, id => new GpuTextureSlot(id),
layout, spellbook, positive: true, () => 0d, NoTex, id => id,
Templates(), "SELECT A SPELL")!;
Assert.False(info.PreserveEndOnLayout);
@ -87,7 +86,7 @@ public sealed class EffectsUiControllerTests
[EffectsUiController.ListId] = list,
});
using EffectsUiController controller = EffectsUiController.Bind(
layout, spellbook, positive: true, () => 0d, NoTex, id => new GpuTextureSlot(id),
layout, spellbook, positive: true, () => 0d, NoTex, id => id,
Templates(), "SELECT A SPELL")!;
spellbook.OnEnchantmentAdded(new ActiveEnchantmentRecord(
42u, 1u, 60f, 1u, Bucket: 1u, SpellCategory: 100u));
@ -130,7 +129,7 @@ public sealed class EffectsUiControllerTests
info.Width = 96f;
using EffectsUiController controller = EffectsUiController.Bind(
layout, spellbook, positive, () => 0d, NoTex, id => new GpuTextureSlot(id),
layout, spellbook, positive, () => 0d, NoTex, id => id,
Templates(), "SELECT A SPELL")!;
spellbook.OnEnchantmentAdded(new ActiveEnchantmentRecord(
42u, 1u, 60f, 1u, Bucket: 1u, SpellCategory: 42u));
@ -174,7 +173,7 @@ public sealed class EffectsUiControllerTests
[EffectsUiController.ListId] = list,
});
using EffectsUiController controller = EffectsUiController.Bind(
layout, spellbook, positive: true, () => 0d, NoTex, id => new GpuTextureSlot(id),
layout, spellbook, positive: true, () => 0d, NoTex, id => id,
Templates(), "SELECT A SPELL")!;
spellbook.OnEnchantmentAdded(new ActiveEnchantmentRecord(
@ -226,7 +225,7 @@ public sealed class EffectsUiControllerTests
int closes = 0;
using EffectsUiController? controller = EffectsUiController.Bind(
layout, spellbook, positive, () => 0d, NoTex, id => new GpuTextureSlot(id),
layout, spellbook, positive, () => 0d, NoTex, id => id,
Templates(), "SELECT A SPELL", () => closes++);
Assert.NotNull(controller);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.App.World;
@ -32,7 +31,7 @@ public sealed class ExternalContainerControllerTests
RetailWindowHandle handle = RetailWindowFrame.Mount(
screen,
root,
static _ => (GpuTextureSlot.Unassigned, 0, 0),
static _ => (0u, 0, 0),
options);
var frame = Assert.IsType<UiNineSlicePanel>(handle.OuterFrame);
@ -76,7 +75,7 @@ public sealed class ExternalContainerControllerTests
var root = new TestElement { Width = 800f, Height = 110f };
var close = new UiButton(
new ElementInfo { Id = ExternalContainerController.CloseButtonId, Type = 1 },
static _ => (GpuTextureSlot.Unassigned, 0, 0));
static _ => (0u, 0, 0));
var scrollbar = new UiScrollbar { Width = 784f, Height = 16f };
root.AddChild(Top);
root.AddChild(Containers);
@ -95,7 +94,7 @@ public sealed class ExternalContainerControllerTests
Window = RetailWindowFrame.Mount(
Screen,
root,
static _ => (GpuTextureSlot.Unassigned, 0, 0),
static _ => (0u, 0, 0),
new RetailWindowFrame.Options
{
WindowName = WindowNames.ExternalContainer,
@ -130,8 +129,8 @@ public sealed class ExternalContainerControllerTests
Selection,
Interaction,
Split,
static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
static (_, _, _, _, _) => 0u,
static (_, _, _, _, _) => 0u,
Uses.Add,
(item, container, placement) => Puts.Add((item, container, placement)),
(item, container, placement, amount) =>
@ -286,7 +285,7 @@ public sealed class ExternalContainerControllerTests
h.Selection.Select(Item, SelectionChangeSource.Inventory);
h.Split.Reset(5u, 2u);
var source = new UiItemSlot { SourceKind = ItemDragSource.Inventory };
source.SetItem(Item, GpuTextureSlot.Unassigned);
source.SetItem(Item, 0u);
var payload = new ItemDragPayload(Item, ItemDragSource.Inventory, 0, source);
UiItemSlot target = h.Contents.GetItem(0)!;
@ -305,7 +304,7 @@ public sealed class ExternalContainerControllerTests
h.Objects.AddOrUpdate(new ClientObject { ObjectId = Item, Type = ItemType.Misc });
h.Objects.MoveItem(Item, Player, 0);
var source = new UiItemSlot { SourceKind = ItemDragSource.Inventory };
source.SetItem(Item, GpuTextureSlot.Unassigned);
source.SetItem(Item, 0u);
Assert.True(h.Interaction.PlaceWorldItemInBackpack(0x70000A01u));
h.Controller.HandleDropRelease(
@ -334,7 +333,7 @@ public sealed class ExternalContainerControllerTests
h.Selection.Select(Item, SelectionChangeSource.Inventory);
h.Split.Reset(5u, 2u);
var source = new UiItemSlot { SourceKind = ItemDragSource.Inventory };
source.SetItem(Item, GpuTextureSlot.Unassigned);
source.SetItem(Item, 0u);
Assert.True(h.Interaction.PlaceWorldItemInBackpack(0x70000A02u));
h.Controller.HandleDropRelease(
@ -356,7 +355,7 @@ public sealed class ExternalContainerControllerTests
h.Objects.AddOrUpdate(new ClientObject { ObjectId = Item, Type = ItemType.Misc });
h.Objects.MoveItem(Item, Player, 0);
var source = new UiItemSlot { SourceKind = ItemDragSource.Inventory };
source.SetItem(Item, GpuTextureSlot.Unassigned);
source.SetItem(Item, 0u);
h.Controller.HandleDropRelease(
h.Contents,

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.IO;
using System.Text.Json;
using AcDream.App.UI.Layout;
@ -10,7 +9,7 @@ namespace AcDream.App.Tests.UI.Layout;
/// no dats required. Fixtures were generated from the real portal.dat and
/// serialized with <see cref="System.Text.Json"/>.
/// </summary>
internal static class FixtureLoader
public static class FixtureLoader
{
private static readonly JsonSerializerOptions _opts = new()
{
@ -27,7 +26,7 @@ internal static class FixtureLoader
public static ImportedLayout LoadVitals()
{
var root = LoadVitalsInfos();
return LayoutImporter.Build(root, _ => (GpuTextureSlot.Unassigned, 0, 0), null);
return LayoutImporter.Build(root, _ => (0u, 0, 0), null);
}
/// <summary>
@ -47,7 +46,7 @@ internal static class FixtureLoader
/// conformance checks on tree structure and resolved types.
/// </summary>
public static ImportedLayout LoadChat()
=> LayoutImporter.Build(LoadChatInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadChatInfos(), _ => (0u, 0, 0), null);
/// <summary>
/// Deserializes the committed <c>chat_21000006.json</c> fixture into a raw
@ -60,44 +59,44 @@ internal static class FixtureLoader
/// <summary>Builds the committed retail radar LayoutDesc 0x21000074 fixture.</summary>
public static ImportedLayout LoadRadar()
=> LayoutImporter.Build(LoadRadarInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadRadarInfos(), _ => (0u, 0, 0), null);
/// <summary>Returns the resolved ElementInfo tree for retail radar LayoutDesc 0x21000074.</summary>
public static AcDream.App.UI.Layout.ElementInfo LoadRadarInfos()
=> LoadInfos("radar_21000074.json");
public static ImportedLayout LoadToolbar()
=> LayoutImporter.Build(LoadToolbarInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadToolbarInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadToolbarInfos()
=> LoadInfos("toolbar_21000016.json");
public static ImportedLayout LoadInventory()
=> LayoutImporter.Build(LoadInventoryInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadInventoryInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadInventoryInfos()
=> LoadInfos("inventory_21000023.json");
public static ImportedLayout LoadPaperdoll()
=> LayoutImporter.Build(LoadPaperdollInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadPaperdollInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadPaperdollInfos()
=> LoadInfos("paperdoll_21000024.json");
public static ImportedLayout LoadCharacter()
=> LayoutImporter.Build(LoadCharacterInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadCharacterInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadCharacterInfos()
=> LoadInfos("character_2100002E.json");
public static ImportedLayout LoadCombat()
=> LayoutImporter.Build(LoadCombatInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadCombatInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadCombatInfos()
=> LoadInfos("combat_21000073.json");
public static ImportedLayout LoadSpellbook()
=> LayoutImporter.Build(LoadSpellbookInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadSpellbookInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadSpellbookInfos()
=> LoadInfos("spellbook_21000034.json");
@ -109,7 +108,7 @@ internal static class FixtureLoader
=> LoadInfos("component_row_21000033_10000467.json");
public static ImportedLayout LoadExamination()
=> LayoutImporter.Build(LoadExaminationInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadExaminationInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadExaminationInfos()
=> LoadInfos("examine_2100006B_100005F2.json");
@ -121,31 +120,31 @@ internal static class FixtureLoader
=> LoadInfos("examine_component_2100006B_1000032E.json");
public static ImportedLayout LoadPowerbar()
=> LayoutImporter.Build(LoadPowerbarInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadPowerbarInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadPowerbarInfos()
=> LoadInfos("powerbar_21000072.json");
public static ImportedLayout LoadConfirmationDialog()
=> LayoutImporter.Build(LoadConfirmationDialogInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadConfirmationDialogInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadConfirmationDialogInfos()
=> LoadInfos("dialogs_2100003C.json");
public static ImportedLayout LoadFpsDisplay()
=> LayoutImporter.Build(LoadFpsDisplayInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadFpsDisplayInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadFpsDisplayInfos()
=> LoadInfos("smartbox_fps_2100000F.json");
public static ImportedLayout LoadPositiveEffects()
=> LayoutImporter.Build(LoadPositiveEffectsInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadPositiveEffectsInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadPositiveEffectsInfos()
=> LoadInfos("effects_positive_2100001B.json");
public static ImportedLayout LoadNegativeEffects()
=> LayoutImporter.Build(LoadNegativeEffectsInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadNegativeEffectsInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadNegativeEffectsInfos()
=> LoadInfos("effects_negative_2100001B.json");
@ -155,31 +154,31 @@ internal static class FixtureLoader
public static ImportedLayout LoadCharacterInformation()
=> LayoutImporter.Build(
LoadCharacterInformationInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
LoadCharacterInformationInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadCharacterInformationInfos()
=> LoadInfos("character_info_2100006E_10000183.json");
public static ImportedLayout LoadIndicators()
=> LayoutImporter.Build(LoadIndicatorsInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadIndicatorsInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadIndicatorsInfos()
=> LoadInfos("indicators_21000071.json");
public static ImportedLayout LoadLinkStatus()
=> LayoutImporter.Build(LoadLinkStatusInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadLinkStatusInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadLinkStatusInfos()
=> LoadInfos("link_status_2100001D.json");
public static ImportedLayout LoadVitae()
=> LayoutImporter.Build(LoadVitaeInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadVitaeInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadVitaeInfos()
=> LoadInfos("vitae_21000020.json");
public static ImportedLayout LoadMiniGame()
=> LayoutImporter.Build(LoadMiniGameInfos(), _ => (GpuTextureSlot.Unassigned, 0, 0), null);
=> LayoutImporter.Build(LoadMiniGameInfos(), _ => (0u, 0, 0), null);
public static ElementInfo LoadMiniGameInfos()
=> LoadInfos("mini_game_2100001E.json");

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.Core.Items;
@ -10,7 +9,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class IndicatorBarControllerTests
{
private const uint Player = 0x50000001u;
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0u, 0, 0);
[Fact]
public void AuthoredFixture_BuildsAllSevenRetailIndicatorButtons()

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Collections.Generic;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -66,7 +65,7 @@ public class InventoryControllerTests
StackSplitQuantityState? stackSplitQuantity = null,
ItemInteractionController? itemInteraction = null)
=> InventoryController.Bind(layout, objects, () => Player,
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
strength: () => strength, datFont: null,
ownerName: ownerName is null ? null : () => ownerName,
sendUse: uses is null ? null : g => uses.Add(g),
@ -84,7 +83,7 @@ public class InventoryControllerTests
private static UiButton MakeButton(uint id)
{
var info = new ElementInfo { Id = id, Type = 1 };
return new UiButton(info, static _ => (GpuTextureSlot.Unassigned, 0, 0)) { Width = 16, Height = 16 };
return new UiButton(info, static _ => (0u, 0, 0)) { Width = 16, Height = 16 };
}
// Seed a side bag (a container) in the player's pack, plus optionally its own contents.
@ -380,7 +379,7 @@ public class InventoryControllerTests
{
var (layout, grid, containers, top, _, _, _, _) = BuildLayout();
InventoryController.Bind(layout, new ClientObjectTable(), () => Player,
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned, strength: () => 100,
iconIds: (_, _, _, _, _) => 0u, strength: () => 100,
selection: new SelectionState(), datFont: null,
contentsEmptySprite: 0x06004D20u, sideBagEmptySprite: 0x06005D9Cu, mainPackEmptySprite: 0x06005D9Cu);
@ -557,7 +556,7 @@ public class InventoryControllerTests
nowMs: () => 1_000);
InventoryController.Bind(layout, objects, () => Player,
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -590,7 +589,7 @@ public class InventoryControllerTests
objects.AddOrUpdate(new ClientObject { ObjectId = Player, IconId = 0x06001234u });
(ItemType type, uint icon)? mainPackCall = null;
InventoryController.Bind(layout, objects, () => Player,
iconIds: (t, icon, _, _, _) => { if (icon == 0x0600127Eu) mainPackCall = (t, icon); return GpuTextureSlot.Unassigned; },
iconIds: (t, icon, _, _, _) => { if (icon == 0x0600127Eu) mainPackCall = (t, icon); return 0u; },
strength: () => 100, selection: new SelectionState(), datFont: null);
// Retail draws a constant backpack over the Container type-underlay (IconData::RenderIcons
@ -683,7 +682,7 @@ public class InventoryControllerTests
var puts = new List<(uint item, uint container, int placement)>();
using var ctrl = Bind(layout, objects, puts: puts, selection: selection);
var source = new UiItemSlot { SourceKind = ItemDragSource.Ground };
source.SetItem(loot, GpuTextureSlot.Unassigned);
source.SetItem(loot, 0u);
var payload = new ItemDragPayload(loot, ItemDragSource.Ground, 0, source);
ctrl.HandleDropRelease(grid, grid.GetItem(1)!, payload);
@ -733,7 +732,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -782,7 +781,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -835,7 +834,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -843,7 +842,7 @@ public class InventoryControllerTests
puts.Add((item, container, placement)),
itemInteraction: interaction);
var source = new UiItemSlot { SourceKind = ItemDragSource.Ground };
source.SetItem(draggedLoot, GpuTextureSlot.Unassigned);
source.SetItem(draggedLoot, 0u);
inventory.HandleDropRelease(
grid,
@ -895,7 +894,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -903,7 +902,7 @@ public class InventoryControllerTests
puts.Add((item, container, placement)),
itemInteraction: interaction);
var source = new UiItemSlot { SourceKind = ItemDragSource.Ground };
source.SetItem(draggedLoot, GpuTextureSlot.Unassigned);
source.SetItem(draggedLoot, 0u);
Assert.True(interaction.PlaceWorldItemInBackpack(directLoot));
Assert.Equal(
@ -960,7 +959,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -1023,7 +1022,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -1031,7 +1030,7 @@ public class InventoryControllerTests
merges.Add((source, target, amount)),
itemInteraction: interaction);
var sourceCell = new UiItemSlot { SourceKind = ItemDragSource.Ground };
sourceCell.SetItem(sourceStack, GpuTextureSlot.Unassigned);
sourceCell.SetItem(sourceStack, 0u);
Assert.True(interaction.PlaceWorldItemInBackpack(pendingLoot));
UiItemSlot targetCell = Enumerable.Range(0, grid.GetNumUIItems())
@ -1084,7 +1083,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: selection,
datFont: null,
@ -1093,7 +1092,7 @@ public class InventoryControllerTests
itemInteraction: interaction,
stackSplitQuantity: splitQuantity);
var sourceCell = new UiItemSlot { SourceKind = ItemDragSource.Ground };
sourceCell.SetItem(sourceStack, GpuTextureSlot.Unassigned);
sourceCell.SetItem(sourceStack, 0u);
Assert.True(interaction.PlaceWorldItemInBackpack(pendingLoot));
inventory.HandleDropRelease(
@ -1132,7 +1131,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -1173,7 +1172,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -1213,7 +1212,7 @@ public class InventoryControllerTests
layout,
objects,
() => Player,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: () => 100,
selection: new SelectionState(),
datFont: null,
@ -1240,7 +1239,7 @@ public class InventoryControllerTests
var puts = new List<(uint item, uint container, int placement)>();
using var ctrl = Bind(layout, objects, puts: puts);
var source = new UiItemSlot { SourceKind = ItemDragSource.Ground };
source.SetItem(loot, GpuTextureSlot.Unassigned);
source.SetItem(loot, 0u);
var payload = new ItemDragPayload(loot, ItemDragSource.Ground, 0, source);
ctrl.HandleDropRelease(grid, grid.GetItem(1)!, payload);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System;
using System.IO;
using AcDream.App.UI;
@ -44,7 +43,7 @@ public class InventoryFrameImportProbe
if (datDir is null) return; // CI: no live dat — skip
using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, Frame, _ => (GpuTextureSlot.Unassigned, 0, 0), null);
var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null);
Assert.NotNull(layout);
// A representative spread across the slot grid (head, shield, the weapon composite, cloak,
@ -64,7 +63,7 @@ public class InventoryFrameImportProbe
if (datDir is null) return; // CI: no live dat — skip (this is a smoke test)
using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, Frame, _ => (GpuTextureSlot.Unassigned, 0, 0), null);
var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null);
Assert.NotNull(layout);
var backdrop = layout!.FindElement(Backdrop);
@ -96,7 +95,7 @@ public class InventoryFrameImportProbe
if (datDir is null) return; // CI: no live dat - skip
using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, Frame, _ => (GpuTextureSlot.Unassigned, 0, 0), null);
var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null);
Assert.NotNull(layout);
var close = layout!.FindElement(WindowChromeController.InventoryCloseButtonId);
@ -109,7 +108,7 @@ public class InventoryFrameImportProbe
layout,
new ClientObjectTable(),
playerGuid: static () => 0u,
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
strength: static () => 100,
selection: new AcDream.Core.Selection.SelectionState(),
datFont: null,

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.Core.Items;
@ -31,7 +30,7 @@ public sealed class ItemCooldownUiControllerTests
double now = 112.5d;
var root = new UiPanel();
var list = new UiItemList();
list.Cell.SetItem(0x5001u, new GpuTextureSlot(99u));
list.Cell.SetItem(0x5001u, 99u);
root.AddChild(list);
uint[] sprites = Enumerable.Range(1, 10)
.Select(index => 0x06000000u + (uint)index)
@ -47,7 +46,7 @@ public sealed class ItemCooldownUiControllerTests
Assert.Equal(sprites[5], list.Cell.ActiveCooldownSprite());
var future = new UiItemSlot();
future.SetItem(0x5001u, new GpuTextureSlot(100u));
future.SetItem(0x5001u, 100u);
list.AddItem(future);
Assert.Equal(sprites[5], future.ActiveCooldownSprite());
@ -82,7 +81,7 @@ public sealed class ItemCooldownUiControllerTests
var root = new UiPanel();
var window = new UiPanel();
var list = new UiItemList();
list.Cell.SetItem(0x5001u, new GpuTextureSlot(99u));
list.Cell.SetItem(0x5001u, 99u);
root.AddChild(window);
window.AddChild(list);
uint[] sprites = Enumerable.Range(1, 10)
@ -118,7 +117,7 @@ public sealed class ItemCooldownUiControllerTests
var spellbook = new Spellbook();
var root = new UiPanel();
var list = new UiItemList();
list.Cell.SetItem(0x5001u, new GpuTextureSlot(99u));
list.Cell.SetItem(0x5001u, 99u);
root.AddChild(list);
int clockReads = 0;
ItemCooldownUiController controller = ItemCooldownUiController.Bind(

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -10,7 +9,7 @@ public sealed class JumpPowerbarLayoutConformanceTests
public void RetailFixture_UsesExactFloatyGeometryTrackAndJumpFill()
{
ElementInfo info = FixtureLoader.LoadPowerbarInfos();
ImportedLayout layout = LayoutImporter.Build(info, _ => (GpuTextureSlot.Unassigned, 0, 0), null);
ImportedLayout layout = LayoutImporter.Build(info, _ => (0u, 0, 0), null);
var meter = Assert.IsType<UiMeter>(
layout.FindElement(JumpPowerbarController.MeterId));

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -10,7 +9,7 @@ namespace AcDream.App.Tests.UI.Layout;
/// </summary>
public class LayoutImporterTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0, 0, 0);
// ── Test 1: Health meter element → UiMeter with correct rect ─────────────

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
using AcDream.Core.Items;
@ -60,7 +59,7 @@ public sealed class PaperdollClickMapTests
ImportedLayout layout = Assert.IsType<ImportedLayout>(LayoutImporter.Import(
dats,
0x21000023u,
static _ => (GpuTextureSlot.Unassigned, 0, 0),
static _ => (0u, 0, 0),
null));
UiElement dragMask = Assert.IsAssignableFrom<UiElement>(
layout.FindElement(PaperdollController.DollDragMaskId));

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Collections.Generic;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -67,7 +66,7 @@ public class PaperdollControllerTests
systemMessage: systemMessages is null ? null : systemMessages.Add);
configureInteraction?.Invoke(itemInteraction);
return PaperdollController.Bind(layout, objects, () => Player,
iconIds: (_, _, _, _, _) => new GpuTextureSlot(0x1234u),
iconIds: (_, _, _, _, _) => 0x1234u,
itemInteraction: itemInteraction,
emptySlotSprite: emptySlot,
selection: selection ?? new SelectionState(),

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Numerics;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -133,7 +132,7 @@ public sealed class RadarControllerTests
root.Children.Add(lockButton);
root.Children.Add(Sprite(RadarController.DragButtonId, 87, 6, 27, 27, 0x060074C9u, type: 2));
return LayoutImporter.Build(root, _ => (GpuTextureSlot.Unassigned, 0, 0), null);
return LayoutImporter.Build(root, _ => (0u, 0, 0), null);
}
private static ElementInfo Sprite(

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -181,7 +180,7 @@ public sealed class RetailPanelUiControllerTests
return RetailWindowFrame.Mount(
root,
content,
_ => (GpuTextureSlot.Unassigned, 0, 0),
_ => (0u, 0, 0),
new RetailWindowFrame.Options
{
WindowName = name,

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -6,7 +5,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class RetailWindowFrameTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0u, 0, 0);
[Theory]
[InlineData(9, 459f, 288f)]

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System;
using System.Collections.Generic;
using System.Linq;
@ -53,7 +52,7 @@ public class SelectedObjectControllerTests
["StackedItemSelected"] = (0x06004CF4u, 3),
},
};
var overlayEl = new UiDatElement(overlayInfo, _ => (GpuTextureSlot.Unassigned, 0, 0));
var overlayEl = new UiDatElement(overlayInfo, _ => (0u, 0, 0));
dict[SelectedObjectController.OverlayId] = overlayEl;
root.AddChild(overlayEl);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -17,16 +16,16 @@ public sealed class SpellExamineComponentTemplateFactoryTests
FixtureLoader.LoadExaminationComponentTemplateInfos();
var factory = new SpellExamineComponentTemplateFactory(
template,
did => (new GpuTextureSlot(did + 1_000u), 32, 32),
did => (did + 1_000u, 32, 32),
defaultFont: null);
UiDatElement root = Assert.IsType<UiDatElement>(
factory.Create(new GpuTextureSlot(0xABCDu), owned));
factory.Create(0xABCDu, owned));
UiDatElement missing = Assert.IsType<UiDatElement>(
Assert.Single(root.Children));
Assert.Equal(SpellExamineComponentTemplateFactory.TemplateId, root.ElementId);
Assert.Equal(new GpuTextureSlot(0xABCDu), root.RuntimeImageTexture);
Assert.Equal(0xABCDu, root.RuntimeImageTexture);
Assert.Empty(root.Children.OfType<UiTextureElement>());
Assert.Equal(
SpellExamineComponentTemplateFactory.MissingOverlayId,

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.Spells;
using AcDream.Content;
using AcDream.App.UI;
@ -31,7 +30,7 @@ public sealed class SpellbookWindowControllerTests
{
ImportedLayout layout = LayoutImporter.Build(
FixtureLoader.LoadSpellbookInfos(),
_ => (GpuTextureSlot.Unassigned, 0, 0),
_ => (0u, 0, 0),
datFont: null,
stringResolve: value => value.StringId switch
{
@ -82,7 +81,7 @@ public sealed class SpellbookWindowControllerTests
{
ImportedLayout layout = LayoutImporter.Build(
FixtureLoader.LoadSpellbookInfos(),
_ => (GpuTextureSlot.Unassigned, 0, 0),
_ => (0u, 0, 0),
datFont: null,
stringResolve: value => value.StringId == 164868556u ? "Delete" : "Filter");
@ -303,7 +302,7 @@ public sealed class SpellbookWindowControllerTests
selection.Select(objectId, SelectionChangeSource.Inventory);
},
setDesiredComponent: (component, amount) => desired.Add((component, amount)),
resolveComponentIcon: icon => new GpuTextureSlot(icon + 0x1000u))!;
resolveComponentIcon: icon => icon + 0x1000u)!;
controller.ShowPage(SpellbookWindowPage.Components);
UiItemList list = Assert.IsType<UiItemList>(
@ -340,7 +339,7 @@ public sealed class SpellbookWindowControllerTests
UiElement iconHost = Assert.IsAssignableFrom<UiElement>(copper.Content.FindElement(
ComponentBookTemplateFactory.IconId));
Assert.Equal(
new GpuTextureSlot(0x06001100u),
0x06001100u,
Assert.IsType<UiTextureElement>(Assert.Single(iconHost.Children)).Texture);
copper.OnEvent(new UiEvent(0u, copper, UiEventType.Click));
@ -402,7 +401,7 @@ public sealed class SpellbookWindowControllerTests
SelectionState? selection = null,
Action<uint>? selectObject = null,
Action<uint, uint>? setDesiredComponent = null,
Func<uint, GpuTextureSlot>? resolveComponentIcon = null)
Func<uint, uint>? resolveComponentIcon = null)
=> SpellbookWindowController.Bind(
layout,
spellbook,
@ -410,8 +409,8 @@ public sealed class SpellbookWindowControllerTests
() => 1u,
components ?? new Dictionary<uint, SpellComponentDescriptor>(),
selection ?? new SelectionState(),
spellId => new GpuTextureSlot(spellId + 1000u),
resolveComponentIcon ?? (iconId => new GpuTextureSlot(iconId)),
spellId => spellId + 1000u,
resolveComponentIcon ?? (iconId => iconId),
spellId => spellId == 103u ? 8 : 1,
selectObject ?? (_ => { }),
addFavorite ?? (_ => { }),
@ -431,7 +430,7 @@ public sealed class SpellbookWindowControllerTests
new ComponentBookTemplateFactory(
FixtureLoader.LoadComponentCategoryTemplateInfos(),
FixtureLoader.LoadComponentRowTemplateInfos(),
_ => (GpuTextureSlot.Unassigned, 0, 0),
_ => (0u, 0, 0),
defaultFont: null),
RowStyle,
rowFont: null);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.Spells;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -11,7 +10,7 @@ namespace AcDream.App.Tests.UI.Layout;
public sealed class SpellcastingUiControllerTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0u, 0, 0);
[Fact]
public void ImportedFixture_UsesRetailEmptyCells_ShortcutDigits_AndCompleteCastButton()
@ -161,8 +160,8 @@ public sealed class SpellcastingUiControllerTests
Assert.True(host.Visible);
UiCatalogSlot slot = Assert.IsType<UiCatalogSlot>(host.Children[^1]);
Assert.Equal(2u, slot.EntryId);
Assert.Equal(new GpuTextureSlot(2670u), slot.CatalogIconTexture);
Assert.Equal(new GpuTextureSlot(2u), slot.CatalogOverlayTexture);
Assert.Equal(2670u, slot.CatalogIconTexture);
Assert.Equal(2u, slot.CatalogOverlayTexture);
slot.OnEvent(new UiEvent(0, slot, UiEventType.Click));
var cast = Assert.IsType<UiButton>(
@ -339,8 +338,8 @@ public sealed class SpellcastingUiControllerTests
new NoopSpellCastOperations());
return SpellcastingUiController.Bind(
layout, spellbook, casting, objects, () => 1u,
spellId => new GpuTextureSlot(spellId),
item => new GpuTextureSlot(item.ObjectId),
spellId => spellId,
item => item.ObjectId,
useItem,
selectionState,
(tab, position, spellId) =>

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System;
using System.Collections.Generic;
using AcDream.App.UI;
@ -67,7 +66,7 @@ public class ToolbarControllerTests
void AddSlot(uint id)
{
var list = new UiItemList(_ => (GpuTextureSlot.Unassigned, 0, 0)) { Width = 32, Height = 32 };
var list = new UiItemList(_ => (0u, 0, 0)) { Width = 32, Height = 32 };
dict[id] = list; slots[id] = list; root.AddChild(list);
}
@ -102,7 +101,7 @@ public class ToolbarControllerTests
},
};
}
var button = new UiButton(info, _ => (GpuTextureSlot.Unassigned, 0, 0)) { Width = 32, Height = 32 };
var button = new UiButton(info, _ => (0u, 0, 0)) { Width = 32, Height = 32 };
dict[id] = button;
root.AddChild(button);
}
@ -118,10 +117,10 @@ public class ToolbarControllerTests
{ new(Index: 0, ObjectId: 0x5001u, SpellId: 0) };
ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x77u), useItem: _ => { });
iconIds: (_,_,_,_,_) => 0x77u, useItem: _ => { });
Assert.Equal(0x5001u, slots[Row1[0]].Cell.ItemId);
Assert.Equal(new GpuTextureSlot(0x77u), slots[Row1[0]].Cell.IconTexture);
Assert.Equal(0x77u, slots[Row1[0]].Cell.IconTexture);
Assert.Equal(0u, slots[Row1[1]].Cell.ItemId); // others empty
}
@ -144,7 +143,7 @@ public class ToolbarControllerTests
layout,
repo,
Store(shortcuts),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(0x77u),
iconIds: (_, _, _, _, _) => 0x77u,
useItem: _ => { });
Assert.Equal(0x5001u, slots[Row1[0]].Cell.ItemId);
@ -162,7 +161,7 @@ public class ToolbarControllerTests
{ new(Index: 2, ObjectId: 0x5002u, SpellId: 0) };
ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x88u), useItem: _ => { });
iconIds: (_,_,_,_,_) => 0x88u, useItem: _ => { });
Assert.Equal(0u, slots[Row1[2]].Cell.ItemId); // not bound yet
repo.AddOrUpdate(new ClientObject { ObjectId = 0x5002u, WeenieClassId = 1u, IconId = 0x06005678u });
@ -178,7 +177,7 @@ public class ToolbarControllerTests
var shortcuts = new List<ShortcutEntry>
{ new(Index: 2, ObjectId: 0x5002u, SpellId: 0) };
var controller = ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x88u), useItem: _ => { });
iconIds: (_,_,_,_,_) => 0x88u, useItem: _ => { });
controller.Dispose();
controller.Dispose();
@ -204,7 +203,7 @@ public class ToolbarControllerTests
var selection = new SelectionState();
ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x77u),
iconIds: (_,_,_,_,_) => 0x77u,
useItem: g => used = g,
selection: selection);
UiItemSlot cell = slots[Row1[0]].Cell;
@ -227,7 +226,7 @@ public class ToolbarControllerTests
var ctrl = ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { });
ctrl.BindPanelButtons(
panelId => panelId is RetailPanelCatalog.Inventory or RetailPanelCatalog.Character,
toggles.Add);
@ -278,7 +277,7 @@ public class ToolbarControllerTests
var ctrl = ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned,
iconIds: (_,_,_,_,_) => 0u,
useItem: _ => { },
itemInteraction: interaction);
ctrl.BindPanelButtons(
@ -305,7 +304,7 @@ public class ToolbarControllerTests
var puts = new List<(uint Item, uint Container, int Placement)>();
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
playerGuid: () => player,
sendPutItemInContainer: (i, c, p) => puts.Add((i, c, p)));
@ -345,7 +344,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
useItem: static _ => { },
itemInteraction: interaction,
playerGuid: () => player,
@ -395,7 +394,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: static (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: static (_, _, _, _, _) => 0u,
useItem: static _ => { },
itemInteraction: interaction,
playerGuid: () => player,
@ -427,7 +426,7 @@ public class ToolbarControllerTests
var puts = new List<(uint Item, uint Container, int Placement)>();
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
playerGuid: () => player,
sendPutItemInContainer: (i, c, p) => puts.Add((i, c, p)));
@ -448,7 +447,7 @@ public class ToolbarControllerTests
var repo = new ClientObjectTable();
var ctrl = ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { });
var inventoryButton = (UiButton)layout.FindElement(InventoryButtonId)!;
var characterButton = (UiButton)layout.FindElement(CharacterButtonId)!;
@ -525,7 +524,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
itemInteraction: interaction,
selectedObjectId: () => selected);
@ -583,7 +582,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
itemInteraction: interaction,
selectedObjectId: () => selection.SelectedObjectId ?? 0u,
@ -649,7 +648,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
itemInteraction: interaction,
selectedObjectId: () => selection.SelectedObjectId ?? 0u,
@ -692,7 +691,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
playerGuid: () => player);
var ammoButton = (UiButton)layout.FindElement(0x10000194u)!;
@ -731,7 +730,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
playerGuid: () => player);
var ammoButton = (UiButton)layout.FindElement(0x10000194u)!;
@ -753,7 +752,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => GpuTextureSlot.Unassigned,
iconIds: (_, _, _, _, _) => 0u,
useItem: _ => { },
toggleCombat: () => toggles++);
@ -780,7 +779,7 @@ public class ToolbarControllerTests
layout,
repo,
Store(shortcuts),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(1u),
iconIds: (_, _, _, _, _) => 1u,
useItem: id => used = id,
selectItem: id => selected = id);
@ -817,7 +816,7 @@ public class ToolbarControllerTests
layout,
repo,
Store(shortcuts),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(1u),
iconIds: (_, _, _, _, _) => 1u,
useItem: _ => { },
itemInteraction: interaction,
selectItem: id => selection.Select(id, SelectionChangeSource.Toolbar),
@ -871,7 +870,7 @@ public class ToolbarControllerTests
layout,
repo,
Store(shortcuts),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(1u),
iconIds: (_, _, _, _, _) => 1u,
useItem: _ => { },
itemInteraction: interaction);
@ -910,7 +909,7 @@ public class ToolbarControllerTests
layout,
repo,
new ShortcutStore(),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(1u),
iconIds: (_, _, _, _, _) => 1u,
useItem: _ => { },
itemInteraction: interaction,
sendAddShortcut: entry => sends.Add(((uint)entry.Index, entry.ObjectId)));
@ -936,7 +935,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) =>0u, useItem: _ => { });
// Only peace indicator (index 0 = 0x10000192) is visible.
Assert.True (indicators[0x10000192u].Visible, "peace indicator should be visible after bind");
@ -956,7 +955,7 @@ public class ToolbarControllerTests
var ctrl = ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) =>0u, useItem: _ => { });
ctrl.SetCombatMode(CombatMode.Melee);
@ -978,7 +977,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { },
iconIds: (_,_,_,_,_) =>0u, useItem: _ => { },
combatState: combat);
// Initially NonCombat after bind.
@ -1017,7 +1016,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
regularDigits: FakeRegular, ghostedDigits: FakeGhosted);
// Top row: ShortcutNum == slot index, ghosted == false.
@ -1046,7 +1045,7 @@ public class ToolbarControllerTests
var repo = new ClientObjectTable();
var ctrl = ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
regularDigits: FakeRegular, ghostedDigits: FakeGhosted);
ctrl.SetCombatMode(mode);
@ -1056,7 +1055,7 @@ public class ToolbarControllerTests
var cell = slots[Row1[i]].Cell;
Assert.Equal(i, cell.ShortcutNum);
Assert.False(cell.ShortcutGhosted, $"top-row slot {i} should be regular in {mode}");
cell.SetItem((uint)(0x5000 + i), new GpuTextureSlot(0x99u));
cell.SetItem((uint)(0x5000 + i), 0x99u);
Assert.Same(FakeRegular, cell.ActiveDigitArray());
}
// Bottom row still has no number.
@ -1074,13 +1073,13 @@ public class ToolbarControllerTests
var repo = new ClientObjectTable();
var ctrl = ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
regularDigits: FakeRegular, ghostedDigits: FakeGhosted);
ctrl.SetCombatMode(CombatMode.Magic);
foreach (var id in Row1)
{
slots[id].Cell.SetItem(id, new GpuTextureSlot(0x99u));
slots[id].Cell.SetItem(id, 0x99u);
Assert.True(slots[id].Cell.ShortcutGhosted);
Assert.Same(FakeGhosted, slots[id].Cell.ActiveDigitArray());
}
@ -1106,7 +1105,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
regularDigits: FakeRegular, ghostedDigits: FakeGhosted);
foreach (var id in Row1)
@ -1128,7 +1127,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
regularDigits: FakeRegular, ghostedDigits: FakeGhosted, emptyDigits: FakeEmpty);
foreach (var id in Row1)
@ -1149,7 +1148,7 @@ public class ToolbarControllerTests
ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { },
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { },
regularDigits: FakeRegular, ghostedDigits: FakeGhosted, emptyDigits: null);
foreach (var id in Row1)
@ -1175,7 +1174,7 @@ public class ToolbarControllerTests
int iconCallCount = 0;
ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => { iconCallCount++; return new GpuTextureSlot(0x77u); }, useItem: _ => { });
iconIds: (_,_,_,_,_) => { iconCallCount++; return 0x77u; }, useItem: _ => { });
int callsAfterBind = iconCallCount; // 1 call from initial Populate
@ -1200,7 +1199,7 @@ public class ToolbarControllerTests
int iconCallCount = 0;
ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => { iconCallCount++; return new GpuTextureSlot(0x99u); }, useItem: _ => { });
iconIds: (_,_,_,_,_) => { iconCallCount++; return 0x99u; }, useItem: _ => { });
Assert.Equal(0, iconCallCount); // not called — item absent during initial Populate
Assert.Equal(0u, slots[Row1[1]].Cell.ItemId);
@ -1226,7 +1225,7 @@ public class ToolbarControllerTests
{ new(Index: 3, ObjectId: 0x5004u, SpellId: 0) };
ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0xAAu), useItem: _ => { });
iconIds: (_,_,_,_,_) => 0xAAu, useItem: _ => { });
Assert.Equal(0x5004u, slots[Row1[3]].Cell.ItemId); // bound
@ -1253,7 +1252,7 @@ public class ToolbarControllerTests
int iconCallCount = 0;
ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => { iconCallCount++; return new GpuTextureSlot(0xBBu); }, useItem: _ => { });
iconIds: (_,_,_,_,_) => { iconCallCount++; return 0xBBu; }, useItem: _ => { });
int callsAfterBind = iconCallCount; // 1 call for the shortcut item
@ -1275,7 +1274,7 @@ public class ToolbarControllerTests
var ctrl = ToolbarController.Bind(layout, repo,
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { });
for (int i = 0; i < Row1.Length; i++)
{
@ -1300,7 +1299,7 @@ public class ToolbarControllerTests
var (layout, slots, _) = FakeToolbar();
var ctrl = ToolbarController.Bind(layout, new ClientObjectTable(),
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { });
var list = slots[Row1[0]];
var payload = new ItemDragPayload(0x5001u, ItemDragSource.Inventory, 0, new UiItemSlot());
@ -1315,7 +1314,7 @@ public class ToolbarControllerTests
var (layout, slots, _) = FakeToolbar();
var ctrl = ToolbarController.Bind(layout, new ClientObjectTable(),
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { });
var list = slots[Row1[0]];
var payload = new ItemDragPayload(0u, ItemDragSource.Inventory, 0, new UiItemSlot());
Assert.Equal(ItemDragAcceptance.None, ctrl.OnDragOver(list, list.Cell, payload));
@ -1344,7 +1343,7 @@ public class ToolbarControllerTests
uint selected = 0;
var ctrl = ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x77u), useItem: _ => { },
iconIds: (_,_,_,_,_) => 0x77u, useItem: _ => { },
sendAddShortcut: add, sendRemoveShortcut: rem,
selectItem: item => selected = item, selectedObjectId: () => selected);
Assert.Equal(0x5001u, slots[Row1[3]].Cell.ItemId);
@ -1369,7 +1368,7 @@ public class ToolbarControllerTests
new(Index: 5, ObjectId: 0x5002u, SpellId: 0) };
var (adds, removes) = NewSpies(out var add, out var rem);
var ctrl = ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x77u), useItem: _ => { },
iconIds: (_,_,_,_,_) => 0x77u, useItem: _ => { },
sendAddShortcut: add, sendRemoveShortcut: rem);
var payload = new ItemDragPayload(0x5001u, ItemDragSource.ShortcutBar, 3, slots[Row1[3]].Cell);
@ -1398,7 +1397,7 @@ public class ToolbarControllerTests
var (adds, _) = NewSpies(out var add, out var remove);
var controller = ToolbarController.Bind(
layout, repo, Store(shortcuts),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(1u),
iconIds: (_, _, _, _, _) => 1u,
useItem: _ => { },
sendAddShortcut: add,
sendRemoveShortcut: remove);
@ -1421,7 +1420,7 @@ public class ToolbarControllerTests
{ new(Index: 3, ObjectId: 0x5001u, SpellId: 0) };
var (adds, removes) = NewSpies(out var add, out var rem);
var ctrl = ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x77u), useItem: _ => { },
iconIds: (_,_,_,_,_) => 0x77u, useItem: _ => { },
sendAddShortcut: add, sendRemoveShortcut: rem);
var payload = new ItemDragPayload(0x5001u, ItemDragSource.ShortcutBar, 3, slots[Row1[3]].Cell);
@ -1447,7 +1446,7 @@ public class ToolbarControllerTests
};
var wire = new List<string>();
var ctrl = ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(1u),
iconIds: (_, _, _, _, _) => 1u,
useItem: _ => { },
sendAddShortcut: entry => wire.Add($"add:{entry.Index}:{entry.ObjectId:X8}:{entry.SpellId:X8}"),
sendRemoveShortcut: slot => wire.Add($"remove:{slot}"));
@ -1480,7 +1479,7 @@ public class ToolbarControllerTests
};
var wire = new List<string>();
var ctrl = ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_, _, _, _, _) => new GpuTextureSlot(1u),
iconIds: (_, _, _, _, _) => 1u,
useItem: _ => { },
sendAddShortcut: entry => wire.Add($"add:{entry.Index}:{entry.ObjectId:X8}:{entry.SpellId:X8}"),
sendRemoveShortcut: slot => wire.Add($"remove:{slot}"));
@ -1505,7 +1504,7 @@ public class ToolbarControllerTests
{ new(Index: 3, ObjectId: 0x5001u, SpellId: 0) };
var (adds, removes) = NewSpies(out var add, out var rem);
var ctrl = ToolbarController.Bind(layout, repo, Store(shortcuts),
iconIds: (_,_,_,_,_) => new GpuTextureSlot(0x77u), useItem: _ => { },
iconIds: (_,_,_,_,_) => 0x77u, useItem: _ => { },
sendAddShortcut: add, sendRemoveShortcut: rem);
var payload = new ItemDragPayload(0x5001u, ItemDragSource.ShortcutBar, 3, slots[Row1[3]].Cell);
@ -1524,7 +1523,7 @@ public class ToolbarControllerTests
var (layout, slots, _) = FakeToolbar();
ToolbarController.Bind(layout, new ClientObjectTable(),
new ShortcutStore(),
iconIds: (_,_,_,_,_) => GpuTextureSlot.Unassigned, useItem: _ => { });
iconIds: (_,_,_,_,_) => 0u, useItem: _ => { });
Assert.Equal(0x060011FAu, slots[Row1[0]].Cell.DragAcceptSprite); // green cross, not the ring F9
}
}

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
namespace AcDream.App.Tests.UI.Layout;
@ -11,7 +10,7 @@ public class UiDatElementTests
var info = new ElementInfo();
info.StateMedia[""] = (0x06000001, 1); // DirectState (DrawMode Normal=1)
info.StateMedia["ShowDetail"] = (0x06000002, 3); // named (Alphablend=3)
var e = new UiDatElement(info, _ => (GpuTextureSlot.Unassigned, 0, 0)) { ActiveState = "ShowDetail" };
var e = new UiDatElement(info, _ => (0, 0, 0)) { ActiveState = "ShowDetail" };
Assert.Equal(0x06000002u, e.ActiveMedia().File);
Assert.Equal(3, e.ActiveMedia().DrawMode);
e.ActiveState = "";
@ -22,7 +21,7 @@ public class UiDatElementTests
[Fact]
public void ActiveMedia_NoMedia_ReturnsZero()
{
var e = new UiDatElement(new ElementInfo(), _ => (GpuTextureSlot.Unassigned, 0, 0));
var e = new UiDatElement(new ElementInfo(), _ => (0, 0, 0));
Assert.Equal(0u, e.ActiveMedia().File);
Assert.Equal(0, e.ActiveMedia().DrawMode);
}
@ -32,7 +31,7 @@ public class UiDatElementTests
{
var info = new ElementInfo();
info.StateMedia[""] = (0x06000005, 1);
var e = new UiDatElement(info, _ => (GpuTextureSlot.Unassigned, 0, 0)) { ActiveState = "NoSuchState" };
var e = new UiDatElement(info, _ => (0, 0, 0)) { ActiveState = "NoSuchState" };
Assert.Equal(0x06000005u, e.ActiveMedia().File);
}
@ -50,7 +49,7 @@ public class UiDatElementTests
info.StateMedia["Normal"] = (0x0000AAAAu, 1);
info.StateMedia["Hover"] = (0x0000BBBBu, 1);
var e = new UiDatElement(info, _ => (GpuTextureSlot.Unassigned, 0, 0));
var e = new UiDatElement(info, _ => (0, 0, 0));
// Should have defaulted to "Normal" state.
Assert.Equal(0x0000AAAAu, e.ActiveMedia().File);
@ -68,7 +67,7 @@ public class UiDatElementTests
info.StateMedia["Maximized"] = (0x0000CCCCu, 1);
info.StateMedia["Normal"] = (0x0000DDDDu, 1);
var e = new UiDatElement(info, _ => (GpuTextureSlot.Unassigned, 0, 0));
var e = new UiDatElement(info, _ => (0, 0, 0));
// DefaultStateName "Minimized" wins over "Normal" implicit default.
Assert.Equal(0x0000BBBBu, e.ActiveMedia().File);
@ -84,7 +83,7 @@ public class UiDatElementTests
var info = new ElementInfo();
info.StateMedia[""] = (0x06007777u, 1); // DirectState only (e.g. vitals chrome corner)
var e = new UiDatElement(info, _ => (GpuTextureSlot.Unassigned, 0, 0));
var e = new UiDatElement(info, _ => (0, 0, 0));
// No DefaultStateName, no "Normal" state → ActiveState stays "" (DirectState).
Assert.Equal(0x06007777u, e.ActiveMedia().File);
@ -101,7 +100,7 @@ public class UiDatElementTests
Image = new UiImageMedia(0x06000009u, 3),
};
info.StateMedia["ShowDetail"] = (0x06000009u, 3);
var element = new UiDatElement(info, _ => (GpuTextureSlot.Unassigned, 0, 0))
var element = new UiDatElement(info, _ => (0u, 0, 0))
{
Left = info.X,
Top = info.Y,
@ -122,7 +121,7 @@ public class UiDatElementTests
{
var info = new ElementInfo { DefaultStateName = "Normal" };
info.StateMedia["Normal"] = (0x06000001u, 1);
var element = new UiDatElement(info, _ => (GpuTextureSlot.Unassigned, 0, 0));
var element = new UiDatElement(info, _ => (0u, 0, 0));
Assert.False(element.TrySetRetailState(RetailUiStateIds.ShowDetail));
Assert.Equal("Normal", element.ActiveState);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -6,7 +5,7 @@ namespace AcDream.App.Tests.UI.Layout;
public class UiViewportFactoryTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0, 0, 0);
[Fact]
public void Factory_builds_UiViewport_for_dat_type_0xD()

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
namespace AcDream.App.Tests.UI;
@ -23,7 +22,7 @@ public class MarkupDocumentTests
" <meter id=\"health\" x=\"8\" y=\"24\" w=\"200\" h=\"14\" fill=\"{HealthPercent}\" cur=\"{HealthCurrent}\" max=\"{HealthMax}\" color=\"#FFFF0000\"/>" +
"</panel>";
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => (new GpuTextureSlot(1), 32, 32));
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)1, 32, 32));
Assert.IsType<UiNineSlicePanel>(panel);
Assert.Equal(10f, panel.Left);
@ -43,7 +42,7 @@ public class MarkupDocumentTests
"<panel id=\"v\" x=\"0\" y=\"0\" w=\"10\" h=\"10\" title=\"V\">" +
" <meter id=\"mana\" x=\"0\" y=\"0\" w=\"10\" h=\"2\" fill=\"{ManaPercent}\" cur=\"{ManaCurrent}\" max=\"{ManaMax}\" color=\"#FF0000FF\"/>" +
"</panel>";
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => (new GpuTextureSlot(1), 32, 32));
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)1, 32, 32));
var meter = Assert.IsType<UiMeter>(panel.Children[1]);
Assert.Null(meter.Fill());
Assert.Null(meter.Label());
@ -53,7 +52,7 @@ public class MarkupDocumentTests
public void Build_ResizeAttrX_SetsHorizontalOnly()
{
const string xml = "<panel id=\"v\" x=\"0\" y=\"0\" w=\"100\" h=\"50\" title=\"V\" resize=\"x\"></panel>";
var panel = MarkupDocument.Build(xml, new object(), _ => (new GpuTextureSlot(1), 32, 32));
var panel = MarkupDocument.Build(xml, new object(), _ => ((uint)1, 32, 32));
Assert.True(panel.ResizeX);
Assert.False(panel.ResizeY);
}
@ -66,7 +65,7 @@ public class MarkupDocumentTests
"backleft=\"0x06001141\" backtile=\"0x06001140\" backright=\"0x0600113F\" " +
"frontleft=\"0x06001131\" fronttile=\"0x06001132\" frontright=\"0x06001133\"/>" +
"</panel>";
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => (new GpuTextureSlot(7), 32, 32));
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)7, 32, 32));
var meter = Assert.IsType<UiMeter>(panel.Children[1]);
Assert.Equal(0x06001141u, meter.BackLeft);
Assert.Equal(0x06001140u, meter.BackTile);

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Collections.Generic;
using System.IO;
using AcDream.App.UI;
@ -97,7 +96,7 @@ public sealed class RetailUiAutomationProbeTests
var root = new UiRoot { Width = 240, Height = 120 };
var objects = new ClientObjectTable();
var source = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1))
var source = new UiItemList(_ => (1u, 1, 1))
{
DatElementId = 0x10000010u,
Left = 10,
@ -107,9 +106,9 @@ public sealed class RetailUiAutomationProbeTests
};
source.Cell.SlotIndex = 0;
source.Cell.SourceKind = ItemDragSource.Inventory;
source.Cell.SetItem(0x5001u, new GpuTextureSlot(0x99u));
source.Cell.SetItem(0x5001u, 0x99u);
var target = new UiItemList(_ => (new GpuTextureSlot(1u), 1, 1))
var target = new UiItemList(_ => (1u, 1, 1))
{
DatElementId = 0x10000020u,
Left = 70,

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Collections.Generic;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
@ -69,7 +68,7 @@ public sealed class RetailUiInteractionFlowTests
height: 32);
var slotsButton = new UiButton(
new ElementInfo { Id = SlotsButtonId, Type = 1 },
static _ => (GpuTextureSlot.Unassigned, 0, 0))
static _ => (0u, 0, 0))
{
DatElementId = SlotsButtonId,
Left = 270,
@ -87,7 +86,7 @@ public sealed class RetailUiInteractionFlowTests
};
var dollDragMask = new UiButton(
new ElementInfo { Id = PaperdollController.DollDragMaskId, Type = 1 },
static _ => (GpuTextureSlot.Unassigned, 0, 0))
static _ => (0u, 0, 0))
{
DatElementId = PaperdollController.DollDragMaskId,
Left = 270,
@ -179,7 +178,7 @@ public sealed class RetailUiInteractionFlowTests
Layout,
Objects,
playerGuid: () => Player,
iconIds: static (_, _, _, _, _) => new GpuTextureSlot(0x1234u),
iconIds: static (_, _, _, _, _) => 0x1234u,
strength: () => 100,
selection: Selection,
datFont: null,
@ -213,7 +212,7 @@ public sealed class RetailUiInteractionFlowTests
Layout,
Objects,
playerGuid: () => Player,
iconIds: static (_, _, _, _, _) => new GpuTextureSlot(0x1234u),
iconIds: static (_, _, _, _, _) => 0x1234u,
selection: Selection,
itemInteraction: itemInteraction,
emptySlotSprite: 0x06004D20u,
@ -266,7 +265,7 @@ public sealed class RetailUiInteractionFlowTests
}
private static UiItemList ItemList(uint id, float left, float top, float width, float height)
=> new(static _ => (new GpuTextureSlot(1u), 32, 32))
=> new(static _ => (1u, 32, 32))
{
DatElementId = id,
Left = left,

View file

@ -1,11 +1,10 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using AcDream.App.UI.Layout;
namespace AcDream.App.Tests.UI;
public class UiButtonTests
{
private static (GpuTextureSlot, int, int) NoTex(uint _) => (GpuTextureSlot.Unassigned, 0, 0);
private static (uint, int, int) NoTex(uint _) => (0, 0, 0);
private bool _clicked;
[Fact]

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
using Xunit;
@ -8,7 +7,7 @@ public class UiCollapsibleFrameTests
{
private static UiCollapsibleFrame MakeFrame(out UiPanel row2a, out UiPanel row2b)
{
var f = new UiCollapsibleFrame(_ => (new GpuTextureSlot(1u), 1, 1))
var f = new UiCollapsibleFrame(_ => (1u, 1, 1))
{
CollapsedHeight = 96f,
ExpandedHeight = 128f,
@ -45,7 +44,7 @@ public class UiCollapsibleFrameTests
[Fact]
public void Tick_notConfigured_isNoOp()
{
var f = new UiCollapsibleFrame(_ => (new GpuTextureSlot(1u), 1, 1)); // Collapsed==Expanded==0
var f = new UiCollapsibleFrame(_ => (1u, 1, 1)); // Collapsed==Expanded==0
f.Height = 50f;
f.TickForTest(0.016);
Assert.Equal(50f, f.Height); // unchanged, no divide/no forced height

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Collections.Generic;
using AcDream.App.UI;
using DatReaderWriter.Types;
@ -92,10 +91,10 @@ public class UiDatFontTests
['B'] = Glyph('B', width: 7, before: 1, after: 1),
};
var font = new UiDatFont(
fgTex: GpuTextureSlot.Unassigned,
fgTex: 0,
fgW: 0,
fgH: 0,
bgTex: GpuTextureSlot.Unassigned,
bgTex: 0,
bgW: 0,
bgH: 0,
lineHeight: 16f,

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using AcDream.App.UI;
namespace AcDream.App.Tests.UI;
@ -22,26 +21,26 @@ public class UiItemSlotTests
{
var s = new UiItemSlot();
Assert.Equal(0u, s.ItemId);
Assert.Equal(GpuTextureSlot.Unassigned, s.IconTexture);
Assert.Equal(0u, s.IconTexture);
}
[Fact]
public void SetItem_setsIdAndTexture()
{
var s = new UiItemSlot();
s.SetItem(0x5001u, new GpuTextureSlot(0x99u));
s.SetItem(0x5001u, 0x99u);
Assert.Equal(0x5001u, s.ItemId);
Assert.Equal(new GpuTextureSlot(0x99u), s.IconTexture);
Assert.Equal(0x99u, s.IconTexture);
}
[Fact]
public void Clear_afterSetItem_resetsToEmpty()
{
var s = new UiItemSlot();
s.SetItem(0x5001u, new GpuTextureSlot(0x99u));
s.SetItem(0x5001u, 0x99u);
s.Clear();
Assert.Equal(0u, s.ItemId);
Assert.Equal(GpuTextureSlot.Unassigned, s.IconTexture);
Assert.Equal(0u, s.IconTexture);
}
[Fact]
@ -59,7 +58,7 @@ public class UiItemSlotTests
[Fact]
public void CatalogSlot_keeps_catalog_identity_separate_from_object_guid()
{
var slot = new UiCatalogSlot { EntryId = 1234u, CatalogIconTexture = new GpuTextureSlot(99u) };
var slot = new UiCatalogSlot { EntryId = 1234u, CatalogIconTexture = 99u };
Assert.Equal(1234u, slot.EntryId);
Assert.Equal(0u, slot.ItemId);
@ -148,7 +147,7 @@ public class UiItemSlotTests
public void ActiveDigitArray_occupiedSlot_regular_returnsRegularDigits()
{
var s = new UiItemSlot { RegularDigits = Regular, GhostedDigits = Ghosted, EmptyDigits = Empty };
s.SetItem(0x5001u, new GpuTextureSlot(0x99u));
s.SetItem(0x5001u, 0x99u);
s.SetShortcutNum(0, ghosted: false);
Assert.Same(Regular, s.ActiveDigitArray());
}
@ -157,7 +156,7 @@ public class UiItemSlotTests
public void ActiveDigitArray_occupiedSlot_ghosted_returnsGhostedDigits()
{
var s = new UiItemSlot { RegularDigits = Regular, GhostedDigits = Ghosted, EmptyDigits = Empty };
s.SetItem(0x5001u, new GpuTextureSlot(0x99u));
s.SetItem(0x5001u, 0x99u);
s.SetShortcutNum(0, ghosted: true);
Assert.Same(Ghosted, s.ActiveDigitArray());
}
@ -209,7 +208,7 @@ public class UiItemSlotTests
CooldownSprites = sprites,
CooldownStepProvider = id => id == 0x5001u ? 6 : 0,
};
slot.SetItem(0x5001u, new GpuTextureSlot(99u));
slot.SetItem(0x5001u, 99u);
Assert.Equal(0x06000006u, slot.ActiveCooldownSprite());
}
@ -224,7 +223,7 @@ public class UiItemSlotTests
};
Assert.Equal(0u, slot.ActiveCooldownSprite());
slot.SetItem(0x5001u, new GpuTextureSlot(99u));
slot.SetItem(0x5001u, 99u);
Assert.Equal(0u, slot.ActiveCooldownSprite());
}
}

View file

@ -1,4 +1,3 @@
using AcDream.App.Rendering.Gpu;
using System.Numerics;
using AcDream.App.UI;
@ -11,7 +10,7 @@ public class UiRootInputTests
{
// Regression: the per-frame anchor pass must NOT reset a window's rect,
// or move/resize get undone every frame. Windows are user-positioned.
var panel = new UiNineSlicePanel(_ => (new GpuTextureSlot(1), 32, 32));
var panel = new UiNineSlicePanel(_ => ((uint)1, 32, 32));
Assert.Equal(AnchorEdges.None, panel.Anchors);
}
@ -120,7 +119,7 @@ public class UiRootInputTests
{
var root = new UiRoot { Width = 800, Height = 600 };
var cell = new UiItemSlot { Left = 0, Top = 0, Width = 32, Height = 32 };
cell.SetItem(0x50000A01u, new GpuTextureSlot(0x99u));
cell.SetItem(0x50000A01u, 0x99u);
root.AddChild(cell);
object? payload = null;
int releaseX = 0;