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:
parent
ceec3bc440
commit
9aaf97e785
334 changed files with 3841 additions and 3661 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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!,
|
||||
|
|
|
|||
|
|
@ -218,7 +218,6 @@ public sealed class SettingsDevToolsCompositionTests
|
|||
null!,
|
||||
null!,
|
||||
null!,
|
||||
null!,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ public sealed class GlRenderStateCacheTests
|
|||
GpuCullMode.Back,
|
||||
GpuFrontFace.CounterClockwise,
|
||||
AlphaToCoverage: false,
|
||||
ColorWrite: true,
|
||||
Multisample: false);
|
||||
ColorWrite: true);
|
||||
|
||||
[Fact]
|
||||
public void FirstApplyReportsEveryDimensionChanged()
|
||||
|
|
|
|||
|
|
@ -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);");
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ──────────────────────────────────────────────────────────
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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) ─────
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ─────────────
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue