fix(scripting): stabilize mono wrapper test teardown

This commit is contained in:
2026-04-15 14:27:21 +08:00
parent 982a877714
commit 65cb212020
8 changed files with 351 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
#include <XCEngine/Core/Math/Vector2.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Core/Math/Vector4.h>
#include <XCEngine/Core/Asset/ResourceManager.h>
#include <XCEngine/Input/InputManager.h>
#include <XCEngine/Physics/PhysicsWorld.h>
#include <XCEngine/Input/InputTypes.h>
@@ -97,6 +98,7 @@ protected:
engine->OnRuntimeStop();
engine->SetRuntimeFixedDeltaTime(ScriptEngine::DefaultFixedDeltaTime);
XCEngine::Input::InputManager::Get().Shutdown();
XCEngine::Resources::ResourceManager::Get().Shutdown();
XCEngine::Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
runtime = std::make_unique<MonoScriptRuntime>(CreateMonoSettings());
@@ -112,6 +114,7 @@ protected:
XCEngine::Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
runtime.reset();
scene.reset();
XCEngine::Resources::ResourceManager::Get().Shutdown();
}
Scene* CreateScene(const std::string& sceneName) {
@@ -2036,6 +2039,180 @@ TEST_F(MonoScriptRuntimeTest, ManagedBuiltInComponentWrappersReadAndWriteCameraA
EXPECT_TRUE(light->GetCastsShadows());
}
TEST_F(MonoScriptRuntimeTest, ManagedBuiltInComponentLookupOnlyCameraAndLight) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");
host->AddComponent<CameraComponent>();
host->AddComponent<LightComponent>();
ScriptComponent* component = AddScript(host, "Gameplay", "CameraLightLookupProbe");
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
bool hasCamera = false;
bool hasLight = false;
bool cameraLookupSucceeded = false;
bool lightLookupSucceeded = false;
EXPECT_TRUE(runtime->TryGetFieldValue(component, "HasCamera", hasCamera));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "HasLight", hasLight));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "CameraLookupSucceeded", cameraLookupSucceeded));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "LightLookupSucceeded", lightLookupSucceeded));
EXPECT_TRUE(hasCamera);
EXPECT_TRUE(hasLight);
EXPECT_TRUE(cameraLookupSucceeded);
EXPECT_TRUE(lightLookupSucceeded);
}
TEST_F(MonoScriptRuntimeTest, ManagedCameraWrapperReadAndWriteProperties) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");
CameraComponent* camera = host->AddComponent<CameraComponent>();
ScriptComponent* component = AddScript(host, "Gameplay", "CameraPropertyProbe");
camera->SetFieldOfView(52.0f);
camera->SetNearClipPlane(0.2f);
camera->SetFarClipPlane(300.0f);
camera->SetDepth(1.5f);
camera->SetPrimary(true);
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
bool cameraLookupSucceeded = false;
bool observedPrimary = false;
float observedFieldOfView = 0.0f;
float observedNearClipPlane = 0.0f;
float observedFarClipPlane = 0.0f;
float observedDepth = 0.0f;
EXPECT_TRUE(runtime->TryGetFieldValue(component, "CameraLookupSucceeded", cameraLookupSucceeded));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedFieldOfView", observedFieldOfView));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedNearClipPlane", observedNearClipPlane));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedFarClipPlane", observedFarClipPlane));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedDepth", observedDepth));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedPrimary", observedPrimary));
EXPECT_TRUE(cameraLookupSucceeded);
EXPECT_FLOAT_EQ(observedFieldOfView, 52.0f);
EXPECT_FLOAT_EQ(observedNearClipPlane, 0.2f);
EXPECT_FLOAT_EQ(observedFarClipPlane, 300.0f);
EXPECT_FLOAT_EQ(observedDepth, 1.5f);
EXPECT_TRUE(observedPrimary);
EXPECT_FLOAT_EQ(camera->GetFieldOfView(), 75.0f);
EXPECT_FLOAT_EQ(camera->GetNearClipPlane(), 0.3f);
EXPECT_FLOAT_EQ(camera->GetFarClipPlane(), 500.0f);
EXPECT_FLOAT_EQ(camera->GetDepth(), 3.0f);
EXPECT_FALSE(camera->IsPrimary());
}
TEST_F(MonoScriptRuntimeTest, ManagedLightWrapperReadAndWriteProperties) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");
LightComponent* light = host->AddComponent<LightComponent>();
ScriptComponent* component = AddScript(host, "Gameplay", "LightPropertyProbe");
light->SetIntensity(1.25f);
light->SetRange(12.0f);
light->SetSpotAngle(33.0f);
light->SetCastsShadows(false);
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
bool lightLookupSucceeded = false;
bool observedCastsShadows = true;
float observedIntensity = 0.0f;
float observedRange = 0.0f;
float observedSpotAngle = 0.0f;
EXPECT_TRUE(runtime->TryGetFieldValue(component, "LightLookupSucceeded", lightLookupSucceeded));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedIntensity", observedIntensity));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedRange", observedRange));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedSpotAngle", observedSpotAngle));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedCastsShadows", observedCastsShadows));
EXPECT_TRUE(lightLookupSucceeded);
EXPECT_FLOAT_EQ(observedIntensity, 1.25f);
EXPECT_FLOAT_EQ(observedRange, 12.0f);
EXPECT_FLOAT_EQ(observedSpotAngle, 33.0f);
EXPECT_FALSE(observedCastsShadows);
EXPECT_FLOAT_EQ(light->GetIntensity(), 2.5f);
EXPECT_FLOAT_EQ(light->GetRange(), 42.0f);
EXPECT_FLOAT_EQ(light->GetSpotAngle(), 55.0f);
EXPECT_TRUE(light->GetCastsShadows());
}
TEST_F(MonoScriptRuntimeTest, ManagedMeshRendererWrapperReadAndWriteFlagsOnly) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");
MeshRendererComponent* meshRenderer = host->AddComponent<MeshRendererComponent>();
ScriptComponent* component = AddScript(host, "Gameplay", "MeshRendererFlagsProbe");
meshRenderer->SetCastShadows(true);
meshRenderer->SetReceiveShadows(false);
meshRenderer->SetRenderLayer(7);
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
bool meshRendererLookupSucceeded = false;
bool observedCastShadows = false;
bool observedReceiveShadows = true;
int32_t observedRenderLayer = 0;
EXPECT_TRUE(runtime->TryGetFieldValue(component, "MeshRendererLookupSucceeded", meshRendererLookupSucceeded));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedCastShadows", observedCastShadows));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedReceiveShadows", observedReceiveShadows));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedRenderLayer", observedRenderLayer));
EXPECT_TRUE(meshRendererLookupSucceeded);
EXPECT_TRUE(observedCastShadows);
EXPECT_FALSE(observedReceiveShadows);
EXPECT_EQ(observedRenderLayer, 7);
EXPECT_FALSE(meshRenderer->GetCastShadows());
EXPECT_TRUE(meshRenderer->GetReceiveShadows());
EXPECT_EQ(meshRenderer->GetRenderLayer(), 11u);
}
TEST_F(MonoScriptRuntimeTest, ManagedMeshRendererWrapperReadAndWriteMaterialPathsOnly) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");
MeshRendererComponent* meshRenderer = host->AddComponent<MeshRendererComponent>();
ScriptComponent* component = AddScript(host, "Gameplay", "MeshRendererPathProbe");
meshRenderer->SetMaterialPath(0, "Materials/initial.mat");
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
bool meshRendererLookupSucceeded = false;
int32_t observedInitialMaterialCount = 0;
std::string observedInitialMaterial0Path;
int32_t observedUpdatedMaterialCount = 0;
std::string observedUpdatedMaterial1Path;
EXPECT_TRUE(runtime->TryGetFieldValue(component, "MeshRendererLookupSucceeded", meshRendererLookupSucceeded));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedInitialMaterialCount", observedInitialMaterialCount));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedInitialMaterial0Path", observedInitialMaterial0Path));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedUpdatedMaterialCount", observedUpdatedMaterialCount));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedUpdatedMaterial1Path", observedUpdatedMaterial1Path));
EXPECT_TRUE(meshRendererLookupSucceeded);
EXPECT_EQ(observedInitialMaterialCount, 1);
EXPECT_EQ(observedInitialMaterial0Path, "Materials/initial.mat");
EXPECT_EQ(observedUpdatedMaterialCount, 2);
EXPECT_EQ(observedUpdatedMaterial1Path, "Materials/runtime_override.mat");
ASSERT_EQ(meshRenderer->GetMaterialCount(), 2u);
EXPECT_EQ(meshRenderer->GetMaterialPath(0), "Materials/initial.mat");
EXPECT_EQ(meshRenderer->GetMaterialPath(1), "Materials/runtime_override.mat");
}
TEST_F(MonoScriptRuntimeTest, ManagedMeshComponentWrappersReadAndWritePathsAndFlags) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");