engine: sync editor rendering and ui changes

This commit is contained in:
2026-04-08 16:09:15 +08:00
parent 31756847ab
commit 162f1cc12e
153 changed files with 4454 additions and 2990 deletions

View File

@@ -106,35 +106,30 @@ TEST(MeshFilterComponent_Test, SetMeshCachesResourceAndPath) {
TEST(MeshFilterComponent_Test, SerializeAndDeserializePreservesPath) {
MeshFilterComponent source;
Mesh* mesh = CreateTestMesh("Quad", "Meshes/serialized.mesh");
source.SetMesh(mesh);
source.SetMeshPath("builtin://meshes/cube");
std::stringstream stream;
source.Serialize(stream);
const std::string serialized = stream.str();
EXPECT_NE(serialized.find("meshRef="), std::string::npos);
EXPECT_NE(serialized.find("meshPath=Meshes/serialized.mesh;"), std::string::npos);
EXPECT_EQ(serialized.find("mesh=Meshes/serialized.mesh;"), std::string::npos);
EXPECT_NE(serialized.find("meshPath=builtin://meshes/cube;"), std::string::npos);
MeshFilterComponent target;
std::stringstream deserializeStream(serialized);
target.Deserialize(deserializeStream);
EXPECT_EQ(target.GetMeshPath(), "Meshes/serialized.mesh");
EXPECT_EQ(target.GetMesh(), nullptr);
EXPECT_EQ(target.GetMeshPath(), "builtin://meshes/cube");
ASSERT_NE(target.GetMesh(), nullptr);
EXPECT_FALSE(target.GetMeshAssetRef().IsValid());
source.ClearMesh();
delete mesh;
}
TEST(MeshFilterComponent_Test, DeserializeSupportsLegacyMeshKey) {
TEST(MeshFilterComponent_Test, DeserializeIgnoresPlainMeshPathWithoutAssetRef) {
MeshFilterComponent target;
std::stringstream stream("mesh=Meshes/legacy.mesh;meshRef=;");
std::stringstream stream("meshPath=Meshes/legacy.mesh;meshRef=;");
target.Deserialize(stream);
EXPECT_EQ(target.GetMeshPath(), "Meshes/legacy.mesh");
EXPECT_TRUE(target.GetMeshPath().empty());
EXPECT_EQ(target.GetMesh(), nullptr);
EXPECT_FALSE(target.GetMeshAssetRef().IsValid());
}
@@ -165,16 +160,16 @@ TEST(MeshFilterComponent_Test, DeferredSceneDeserializeLoadsMeshAsyncByPath) {
{
ResourceManager::ScopedDeferredSceneLoad deferredLoadScope;
EXPECT_TRUE(manager.IsDeferredSceneLoadEnabled());
std::stringstream stream("mesh=Meshes/async.mesh;meshRef=;");
std::stringstream stream("meshPath=test://meshes/async.mesh;meshRef=;");
target.Deserialize(stream);
}
EXPECT_EQ(target.GetMeshPath(), "Meshes/async.mesh");
EXPECT_EQ(target.GetMeshPath(), "test://meshes/async.mesh");
EXPECT_EQ(target.GetMesh(), nullptr);
EXPECT_GT(manager.GetAsyncPendingCount(), pendingBeforeDeserialize);
ASSERT_TRUE(PumpAsyncLoadsUntilIdle(manager));
ASSERT_NE(target.GetMesh(), nullptr);
EXPECT_EQ(target.GetMeshPath(), "Meshes/async.mesh");
EXPECT_EQ(target.GetMeshPath(), "test://meshes/async.mesh");
EXPECT_EQ(target.GetMesh()->GetVertexCount(), 3u);
manager.RegisterLoader(originalLoader);
@@ -209,10 +204,8 @@ TEST(MeshRendererComponent_Test, SetMaterialsKeepsSlotsAndFlags) {
TEST(MeshRendererComponent_Test, SerializeAndDeserializePreservesMaterialPathsAndSettings) {
MeshRendererComponent source;
Material* material0 = CreateTestMaterial("M0", "Materials/serialized0.mat");
Material* material1 = CreateTestMaterial("M1", "Materials/serialized1.mat");
source.SetMaterial(0, material0);
source.SetMaterial(1, material1);
source.SetMaterialPath(0, "builtin://materials/default-primitive");
source.SetMaterialPath(1, "builtin://materials/default-primitive");
source.SetCastShadows(false);
source.SetReceiveShadows(true);
source.SetRenderLayer(3);
@@ -221,33 +214,27 @@ TEST(MeshRendererComponent_Test, SerializeAndDeserializePreservesMaterialPathsAn
source.Serialize(stream);
const std::string serialized = stream.str();
EXPECT_NE(
serialized.find("materialPaths=Materials/serialized0.mat|Materials/serialized1.mat;"),
serialized.find("materialPaths=builtin://materials/default-primitive|builtin://materials/default-primitive;"),
std::string::npos);
EXPECT_NE(serialized.find("materialRefs=|;"), std::string::npos);
EXPECT_EQ(serialized.find("materials="), std::string::npos);
MeshRendererComponent target;
std::stringstream deserializeStream(serialized);
target.Deserialize(deserializeStream);
ASSERT_EQ(target.GetMaterialCount(), 2u);
EXPECT_EQ(target.GetMaterial(0), nullptr);
EXPECT_EQ(target.GetMaterial(1), nullptr);
EXPECT_EQ(target.GetMaterialPaths()[0], "Materials/serialized0.mat");
EXPECT_EQ(target.GetMaterialPaths()[1], "Materials/serialized1.mat");
ASSERT_NE(target.GetMaterial(0), nullptr);
ASSERT_NE(target.GetMaterial(1), nullptr);
EXPECT_EQ(target.GetMaterialPaths()[0], "builtin://materials/default-primitive");
EXPECT_EQ(target.GetMaterialPaths()[1], "builtin://materials/default-primitive");
EXPECT_FALSE(target.GetCastShadows());
EXPECT_TRUE(target.GetReceiveShadows());
EXPECT_EQ(target.GetRenderLayer(), 3u);
source.ClearMaterials();
delete material0;
delete material1;
}
TEST(MeshRendererComponent_Test, SerializeAndDeserializePreservesTrailingEmptyMaterialSlots) {
MeshRendererComponent source;
Material* material0 = CreateTestMaterial("M0", "Materials/serialized0.mat");
source.SetMaterial(0, material0);
source.SetMaterialPath(0, "builtin://materials/default-primitive");
source.SetMaterialPath(1, "");
source.SetCastShadows(false);
source.SetReceiveShadows(true);
@@ -256,25 +243,21 @@ TEST(MeshRendererComponent_Test, SerializeAndDeserializePreservesTrailingEmptyMa
std::stringstream stream;
source.Serialize(stream);
const std::string serialized = stream.str();
EXPECT_NE(serialized.find("materialPaths=Materials/serialized0.mat|;"), std::string::npos);
EXPECT_NE(serialized.find("materialPaths=builtin://materials/default-primitive|;"), std::string::npos);
EXPECT_NE(serialized.find("materialRefs=|;"), std::string::npos);
EXPECT_EQ(serialized.find("materials="), std::string::npos);
MeshRendererComponent target;
std::stringstream deserializeStream(serialized);
target.Deserialize(deserializeStream);
ASSERT_EQ(target.GetMaterialCount(), 2u);
EXPECT_EQ(target.GetMaterial(0), nullptr);
ASSERT_NE(target.GetMaterial(0), nullptr);
EXPECT_EQ(target.GetMaterial(1), nullptr);
EXPECT_EQ(target.GetMaterialPath(0), "Materials/serialized0.mat");
EXPECT_EQ(target.GetMaterialPath(0), "builtin://materials/default-primitive");
EXPECT_EQ(target.GetMaterialPath(1), "");
EXPECT_FALSE(target.GetCastShadows());
EXPECT_TRUE(target.GetReceiveShadows());
EXPECT_EQ(target.GetRenderLayer(), 9u);
source.ClearMaterials();
delete material0;
}
TEST(MeshRendererComponent_Test, SetMaterialPathPreservesPathWithoutLoadedResource) {
@@ -293,15 +276,15 @@ TEST(MeshRendererComponent_Test, SetMaterialPathPreservesPathWithoutLoadedResour
EXPECT_EQ(component.GetMaterial(1), nullptr);
}
TEST(MeshRendererComponent_Test, DeserializeSupportsLegacyMaterialsKey) {
TEST(MeshRendererComponent_Test, DeserializeIgnoresPlainMaterialPathsWithoutAssetRefs) {
MeshRendererComponent target;
std::stringstream stream(
"materials=Materials/legacy0.mat|;materialRefs=|;castShadows=0;receiveShadows=1;renderLayer=5;");
"materialPaths=Materials/legacy0.mat|;materialRefs=|;castShadows=0;receiveShadows=1;renderLayer=5;");
target.Deserialize(stream);
ASSERT_EQ(target.GetMaterialCount(), 2u);
EXPECT_EQ(target.GetMaterialPath(0), "Materials/legacy0.mat");
EXPECT_EQ(target.GetMaterialPath(0), "");
EXPECT_EQ(target.GetMaterialPath(1), "");
EXPECT_EQ(target.GetMaterial(0), nullptr);
EXPECT_EQ(target.GetMaterial(1), nullptr);
@@ -351,7 +334,6 @@ TEST(MeshRendererComponent_Test, SerializeAndDeserializeLoadsProjectMaterialByAs
EXPECT_NE(serialized.find("materialPaths=;"), std::string::npos);
EXPECT_NE(serialized.find("materialRefs="), std::string::npos);
EXPECT_EQ(serialized.find("materialRefs=;"), std::string::npos);
EXPECT_EQ(serialized.find("materials="), std::string::npos);
std::stringstream deserializeStream(serialized);
MeshRendererComponent target;