Add enum script field support

This commit is contained in:
2026-04-03 15:55:47 +08:00
parent c7eb9857cb
commit 76f1a8e9b2
7 changed files with 290 additions and 25 deletions

View File

@@ -180,6 +180,7 @@ TEST_F(MonoScriptRuntimeTest, ClassFieldMetadataListsSupportedPublicInstanceFiel
{"Label", ScriptFieldType::String},
{"SpawnPoint", ScriptFieldType::Vector3},
{"Speed", ScriptFieldType::Float},
{"State", ScriptFieldType::Int32},
{"Target", ScriptFieldType::GameObject},
};
@@ -212,6 +213,23 @@ TEST_F(MonoScriptRuntimeTest, ClassFieldDefaultValueQueryReturnsManagedInitializ
EXPECT_EQ(std::get<int32_t>(fieldIt->value), -1);
}
TEST_F(MonoScriptRuntimeTest, ClassFieldDefaultValueQueryReturnsEnumInitializersAsInt32) {
std::vector<ScriptFieldDefaultValue> fields;
EXPECT_TRUE(runtime->TryGetClassFieldDefaultValues("GameScripts", "Gameplay", "FieldMetadataProbe", fields));
const auto fieldIt = std::find_if(
fields.begin(),
fields.end(),
[](const ScriptFieldDefaultValue& field) {
return field.fieldName == "State";
});
ASSERT_NE(fieldIt, fields.end());
EXPECT_EQ(fieldIt->type, ScriptFieldType::Int32);
EXPECT_EQ(std::get<int32_t>(fieldIt->value), 2);
}
TEST_F(MonoScriptRuntimeTest, ScriptEngineAppliesStoredFieldsAndInvokesLifecycleMethods) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");
@@ -786,6 +804,66 @@ TEST_F(MonoScriptRuntimeTest, ManagedFieldChangesWriteBackToStoredCacheAndPersis
EXPECT_EQ(observedTargetName, "Target");
}
TEST_F(MonoScriptRuntimeTest, EnumScriptFieldsApplyStoredValuesAndPersistAcrossSceneRoundTrip) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");
ScriptComponent* component = AddScript(host, "Gameplay", "EnumFieldProbe");
component->GetFieldStorage().SetFieldValue("State", int32_t(5));
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
int32_t observedInitialState = 0;
bool observedStoredStateApplied = false;
int32_t observedUpdatedState = 0;
int32_t runtimeState = 0;
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedInitialState", observedInitialState));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedStoredStateApplied", observedStoredStateApplied));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "ObservedUpdatedState", observedUpdatedState));
EXPECT_TRUE(runtime->TryGetFieldValue(component, "State", runtimeState));
EXPECT_EQ(observedInitialState, 5);
EXPECT_TRUE(observedStoredStateApplied);
EXPECT_EQ(observedUpdatedState, 9);
EXPECT_EQ(runtimeState, 9);
int32_t storedState = 0;
EXPECT_TRUE(component->GetFieldStorage().TryGetFieldValue("State", storedState));
EXPECT_EQ(storedState, 9);
const std::string serializedScene = runtimeScene->SerializeToString();
engine->OnRuntimeStop();
scene = std::make_unique<Scene>("ReloadedEnumScene");
scene->DeserializeFromString(serializedScene);
Scene* reloadedScene = scene.get();
GameObject* loadedHost = reloadedScene->Find("Host");
ASSERT_NE(loadedHost, nullptr);
ScriptComponent* loadedComponent = FindScriptComponentByClass(loadedHost, "Gameplay", "EnumFieldProbe");
ASSERT_NE(loadedComponent, nullptr);
int32_t loadedStoredState = 0;
EXPECT_TRUE(loadedComponent->GetFieldStorage().TryGetFieldValue("State", loadedStoredState));
EXPECT_EQ(loadedStoredState, 9);
engine->OnRuntimeStart(reloadedScene);
engine->OnUpdate(0.016f);
int32_t loadedObservedInitialState = 0;
int32_t loadedRuntimeState = 0;
EXPECT_TRUE(runtime->TryGetFieldValue(loadedComponent, "ObservedInitialState", loadedObservedInitialState));
EXPECT_TRUE(runtime->TryGetFieldValue(loadedComponent, "State", loadedRuntimeState));
EXPECT_EQ(loadedObservedInitialState, 9);
EXPECT_EQ(loadedRuntimeState, 9);
}
TEST_F(MonoScriptRuntimeTest, ScriptEngineFieldApiUpdatesLiveManagedInstanceAndStoredCache) {
Scene* runtimeScene = CreateScene("MonoRuntimeScene");
GameObject* host = runtimeScene->CreateGameObject("Host");