Add XCUI runtime screen stack helper

This commit is contained in:
2026-04-05 06:05:54 +08:00
parent f185663259
commit 0c24c7c611
5 changed files with 273 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
#include <XCEngine/UI/Runtime/UIScreenDocumentHost.h>
#include <XCEngine/UI/Runtime/UIScreenPlayer.h>
#include <XCEngine/UI/Runtime/UIScreenStackController.h>
#include <XCEngine/UI/Runtime/UISystem.h>
#include <chrono>
@@ -15,6 +16,7 @@ using XCEngine::UI::Runtime::UIScreenAsset;
using XCEngine::UI::Runtime::UIScreenFrameInput;
using XCEngine::UI::Runtime::UIScreenPlayer;
using XCEngine::UI::Runtime::UIDocumentScreenHost;
using XCEngine::UI::Runtime::UIScreenStackController;
using XCEngine::UI::Runtime::UISystem;
namespace fs = std::filesystem;
@@ -141,3 +143,65 @@ TEST(UIRuntimeTest, UISystemForwardsActiveScreenToPlayer) {
EXPECT_TRUE(DrawDataContainsText(frame.drawData, "Modal Dialog"));
EXPECT_FALSE(DrawDataContainsText(frame.drawData, "Base Screen"));
}
TEST(UIRuntimeTest, ScreenStackControllerAppliesHudAndMenuLayerPolicies) {
TempFileScope hudView("xcui_runtime_hud", ".xcui", BuildViewMarkup("HUD Screen"));
TempFileScope menuView("xcui_runtime_menu", ".xcui", BuildViewMarkup("Pause Menu", "Paused"));
UIDocumentScreenHost host = {};
UISystem system(host);
UIScreenStackController stack(system);
const auto hudLayer = stack.PushHud(BuildScreenAsset(hudView.Path(), "runtime.hud"), "hud");
const auto menuLayer = stack.PushMenu(BuildScreenAsset(menuView.Path(), "runtime.menu"), "menu");
ASSERT_NE(hudLayer, 0u);
ASSERT_NE(menuLayer, 0u);
ASSERT_EQ(stack.GetEntryCount(), 2u);
ASSERT_NE(stack.GetTop(), nullptr);
EXPECT_EQ(stack.GetTop()->layerId, menuLayer);
const auto* hudOptions = system.FindLayerOptions(hudLayer);
const auto* menuOptions = system.FindLayerOptions(menuLayer);
ASSERT_NE(hudOptions, nullptr);
ASSERT_NE(menuOptions, nullptr);
EXPECT_FALSE(hudOptions->acceptsInput);
EXPECT_FALSE(hudOptions->blocksLayersBelow);
EXPECT_TRUE(menuOptions->acceptsInput);
EXPECT_TRUE(menuOptions->blocksLayersBelow);
const auto& frame = system.Update(BuildInputState(4u));
EXPECT_EQ(frame.presentedLayerCount, 1u);
EXPECT_TRUE(DrawDataContainsText(frame.drawData, "Pause Menu"));
EXPECT_FALSE(DrawDataContainsText(frame.drawData, "HUD Screen"));
}
TEST(UIRuntimeTest, ScreenStackControllerReplaceTopSwapsMenuContent) {
TempFileScope pauseView("xcui_runtime_pause", ".xcui", BuildViewMarkup("Pause Menu"));
TempFileScope settingsView("xcui_runtime_settings", ".xcui", BuildViewMarkup("Settings Menu"));
UIDocumentScreenHost host = {};
UISystem system(host);
UIScreenStackController stack(system);
const auto pauseLayer = stack.PushMenu(BuildScreenAsset(pauseView.Path(), "runtime.pause"), "pause");
ASSERT_NE(pauseLayer, 0u);
XCEngine::UI::Runtime::UIScreenLayerOptions replacementOptions = {};
replacementOptions.debugName = "settings";
replacementOptions.acceptsInput = true;
replacementOptions.blocksLayersBelow = true;
ASSERT_TRUE(stack.ReplaceTop(
BuildScreenAsset(settingsView.Path(), "runtime.settings"),
replacementOptions));
ASSERT_EQ(stack.GetEntryCount(), 1u);
ASSERT_NE(stack.GetTop(), nullptr);
EXPECT_EQ(stack.GetTop()->asset.screenId, "runtime.settings");
EXPECT_NE(stack.GetTop()->layerId, pauseLayer);
const auto& frame = system.Update(BuildInputState(5u));
EXPECT_EQ(frame.presentedLayerCount, 1u);
EXPECT_TRUE(DrawDataContainsText(frame.drawData, "Settings Menu"));
EXPECT_FALSE(DrawDataContainsText(frame.drawData, "Pause Menu"));
}