脚本更新

This commit is contained in:
Rowland 2026-06-09 15:44:44 +08:00
parent 84446d0060
commit a1cd721203
2 changed files with 51 additions and 52 deletions

View File

@ -6977,12 +6977,15 @@ public:
ComponentSystemRegistry_.reset();
State_ = MetaCorePlayModeState::Edit;
HasPrePlaySnapshot_ = false;
HasPendingStopRestoreSnapshot_ = false;
CommandRecordingSuppressed_ = false;
ElapsedTimeSeconds_ = 0.0;
FixedTimeAccumulatorSeconds_ = 0.0;
}
[[nodiscard]] bool EnterPlayMode(MetaCoreEditorContext& editorContext) override {
ApplyPendingStopRestore(editorContext);
if (State_ != MetaCorePlayModeState::Edit) {
MetaCoreDebugLog(
"PlayMode",
@ -7045,17 +7048,13 @@ public:
}
if (HasPrePlaySnapshot_) {
MetaCoreDebugLog("PlayMode", "Exit capturing current snapshot");
const MetaCoreEditorStateSnapshot currentSnapshot = editorContext.CaptureStateSnapshot();
MetaCoreDebugLog(
"PlayMode",
"Exit committing undo preObjects=" +
std::to_string(PrePlaySnapshot_.SceneSnapshot.GameObjects.size()) +
" currentObjects=" +
std::to_string(currentSnapshot.SceneSnapshot.GameObjects.size())
"Exit queueing prePlaySnapshot restore objects=" +
std::to_string(PrePlaySnapshot_.SceneSnapshot.GameObjects.size())
);
(void)editorContext.CommitStateTransition("播放模式改动", PrePlaySnapshot_, currentSnapshot);
MetaCoreDebugLog("PlayMode", "Exit undo committed " + MetaCoreDebugSceneSummary(editorContext));
PendingStopRestoreSnapshot_ = PrePlaySnapshot_;
HasPendingStopRestoreSnapshot_ = true;
} else {
MetaCoreDebugLog("PlayMode", "Exit no prePlaySnapshot, refresh dirty state");
RefreshSceneDirtyState(editorContext);
@ -7064,7 +7063,7 @@ public:
HasPrePlaySnapshot_ = false;
ElapsedTimeSeconds_ = 0.0;
FixedTimeAccumulatorSeconds_ = 0.0;
editorContext.AddConsoleMessage(MetaCoreLogLevel::Info, "PlayMode", "已停止播放模式,播放期改动已保留");
editorContext.AddConsoleMessage(MetaCoreLogLevel::Info, "PlayMode", "已停止播放模式,已恢复播放前场景状态");
MetaCoreDebugLog("PlayMode", "Exit end " + MetaCoreDebugSceneSummary(editorContext));
return true;
}
@ -7128,6 +7127,11 @@ public:
}
void Tick(MetaCoreEditorContext& editorContext, double deltaSeconds) override {
if (HasPendingStopRestoreSnapshot_) {
ApplyPendingStopRestore(editorContext);
return;
}
if (State_ != MetaCorePlayModeState::Playing) {
return;
}
@ -7235,10 +7239,29 @@ private:
}
}
void ApplyPendingStopRestore(MetaCoreEditorContext& editorContext) {
if (!HasPendingStopRestoreSnapshot_) {
return;
}
MetaCoreDebugLog(
"PlayMode",
"Apply pending stop restore begin objects=" +
std::to_string(PendingStopRestoreSnapshot_.SceneSnapshot.GameObjects.size()) +
" " + MetaCoreDebugSceneSummary(editorContext)
);
editorContext.RestoreStateSnapshot(PendingStopRestoreSnapshot_);
HasPendingStopRestoreSnapshot_ = false;
PendingStopRestoreSnapshot_ = {};
MetaCoreDebugLog("PlayMode", "Apply pending stop restore end " + MetaCoreDebugSceneSummary(editorContext));
}
std::shared_ptr<MetaCoreIPlayModeComponentSystemRegistry> ComponentSystemRegistry_{};
MetaCorePlayModeState State_ = MetaCorePlayModeState::Edit;
MetaCoreEditorStateSnapshot PrePlaySnapshot_{};
MetaCoreEditorStateSnapshot PendingStopRestoreSnapshot_{};
bool HasPrePlaySnapshot_ = false;
bool HasPendingStopRestoreSnapshot_ = false;
bool CommandRecordingSuppressed_ = false;
double ElapsedTimeSeconds_ = 0.0;
double FixedTimeStepSeconds_ = 1.0 / 60.0;

View File

@ -705,12 +705,13 @@ void MetaCoreTestPlayModeStateMachineAndLifecycle() {
MetaCoreExpect(playMode->ExitPlayMode(editorContext), "应能退出播放模式");
MetaCoreExpect(playMode->GetState() == MetaCore::MetaCorePlayModeState::Edit, "退出后应回到 Edit");
MetaCoreExpect(countingSystem->StopCount == 1, "OnPlayStop 应只调用一次");
playMode->Tick(editorContext, 0.0);
coreServicesModule->Shutdown(moduleRegistry);
moduleRegistry.ShutdownServices();
}
void MetaCoreTestPlayModeRotatorRetainsChangesAsSingleUndoStep() {
void MetaCoreTestPlayModeRotatorRestoresPrePlaySnapshotOnStop() {
_putenv_s("METACORE_PROJECT_PATH", "");
MetaCore::MetaCoreWindow window;
@ -736,9 +737,7 @@ void MetaCoreTestPlayModeRotatorRetainsChangesAsSingleUndoStep() {
);
const auto playMode = moduleRegistry.ResolveService<MetaCore::MetaCoreIPlayModeService>();
const auto scenePersistence = moduleRegistry.ResolveService<MetaCore::MetaCoreIScenePersistenceService>();
MetaCoreExpect(playMode != nullptr, "应解析到 PlayModeService");
MetaCoreExpect(scenePersistence != nullptr, "应解析到 ScenePersistenceService");
MetaCoreExpect(editorContext.GetCommandService().GetUndoCount() == 0, "播放前 Undo 栈应为空");
MetaCoreExpect(playMode->EnterPlayMode(editorContext), "应能进入播放模式");
@ -783,34 +782,21 @@ void MetaCoreTestPlayModeRotatorRetainsChangesAsSingleUndoStep() {
MetaCoreExpect(playMode->ExitPlayMode(editorContext), "应能停止播放");
MetaCoreExpect(playMode->GetState() == MetaCore::MetaCorePlayModeState::Edit, "停止后应回到 Edit");
MetaCoreExpect(editorContext.GetCommandService().GetUndoCount() == 1, "停止后播放期差异应合并为一个 Undo 步");
MetaCoreExpect(scenePersistence->IsSceneDirty(), "停止并保留播放改动后场景应标记为脏");
MetaCoreExpect(editorContext.GetCommandService().GetUndoCount() == 0, "停止后不应把播放期差异写入 Undo 栈");
playMode->Tick(editorContext, 0.0);
updatedSpinner = scene.FindGameObject(spinnerId);
MetaCoreExpectVec3Near(
updatedSpinner.GetComponent<MetaCore::MetaCoreTransformComponent>().RotationEulerDegrees,
glm::vec3(0.0F, 31.0F, 0.0F),
"停止后 Rotator 结果应保留"
);
MetaCoreExpectVec3Near(
updatedSpinner.GetComponent<MetaCore::MetaCoreTransformComponent>().Position,
glm::vec3(2.0F, 0.0F, 0.0F),
"停止后播放期手动改动应保留"
);
MetaCoreExpect(editorContext.UndoCommand(), "Undo 应能回到播放前快照");
updatedSpinner = scene.FindGameObject(spinnerId);
MetaCoreExpectVec3Near(
updatedSpinner.GetComponent<MetaCore::MetaCoreTransformComponent>().RotationEulerDegrees,
glm::vec3(0.0F, 0.0F, 0.0F),
"Undo 后 Rotator 旋转应回到播放前"
"停止后 Rotator 旋转应恢复播放前"
);
MetaCoreExpectVec3Near(
updatedSpinner.GetComponent<MetaCore::MetaCoreTransformComponent>().Position,
glm::vec3(0.0F, 0.0F, 0.0F),
"Undo 后播放期手动改动应回到播放前"
"停止后播放期手动改动应丢弃"
);
MetaCoreExpect(updatedSpinner.HasComponent<MetaCore::MetaCoreRotatorComponent>(), "Undo 后 Rotator 组件应保留");
MetaCoreExpect(updatedSpinner.HasComponent<MetaCore::MetaCoreRotatorComponent>(), "停止恢复后 Rotator 组件应保留");
coreServicesModule->Shutdown(moduleRegistry);
moduleRegistry.ShutdownServices();
@ -1008,12 +994,13 @@ void MetaCoreTestNativeScriptLifecycle() {
MetaCoreExpect(playMode->ExitPlayMode(editorContext), "脚本生命周期测试应能退出播放模式");
MetaCoreExpect(counters->StopCount == 1, "脚本 OnPlayStop 应调用一次并清理运行时实例");
playMode->Tick(editorContext, 0.0);
coreServicesModule->Shutdown(moduleRegistry);
moduleRegistry.ShutdownServices();
}
void MetaCoreTestNativeScriptBehavioursRetainChangesAsSingleUndoStep() {
void MetaCoreTestNativeScriptBehavioursRestorePrePlaySnapshotOnStop() {
_putenv_s("METACORE_PROJECT_PATH", "");
MetaCore::MetaCoreWindow window;
@ -1051,9 +1038,7 @@ void MetaCoreTestNativeScriptBehavioursRetainChangesAsSingleUndoStep() {
);
const auto playMode = moduleRegistry.ResolveService<MetaCore::MetaCoreIPlayModeService>();
const auto scenePersistence = moduleRegistry.ResolveService<MetaCore::MetaCoreIScenePersistenceService>();
MetaCoreExpect(playMode != nullptr, "应解析到 PlayModeService");
MetaCoreExpect(scenePersistence != nullptr, "应解析到 ScenePersistenceService");
MetaCoreExpect(editorContext.GetCommandService().GetUndoCount() == 0, "脚本播放前 Undo 栈应为空");
MetaCoreExpect(playMode->EnterPlayMode(editorContext), "脚本行为测试应能进入播放模式");
@ -1101,30 +1086,21 @@ void MetaCoreTestNativeScriptBehavioursRetainChangesAsSingleUndoStep() {
);
MetaCoreExpect(playMode->ExitPlayMode(editorContext), "脚本行为测试应能退出播放模式");
MetaCoreExpect(editorContext.GetCommandService().GetUndoCount() == 1, "脚本播放期差异应合并为一个 Undo 步");
MetaCoreExpect(scenePersistence->IsSceneDirty(), "脚本播放结果保留后场景应标记为脏");
updatedObject = scene.FindGameObject(objectId);
MetaCoreExpect(updatedObject.HasComponent<MetaCore::MetaCoreScriptComponent>(), "停止后 Script 组件应保留");
MetaCoreExpectVec3Near(
updatedObject.GetComponent<MetaCore::MetaCoreTransformComponent>().RotationEulerDegrees,
glm::vec3(0.0F, 31.0F, 0.0F),
"停止后 RotatorScript 结果应保留"
);
MetaCoreExpect(editorContext.UndoCommand(), "Undo 应能回到脚本播放前快照");
MetaCoreExpect(editorContext.GetCommandService().GetUndoCount() == 0, "停止脚本播放后不应写入 Undo 步");
playMode->Tick(editorContext, 0.0);
updatedObject = scene.FindGameObject(objectId);
MetaCoreExpect(updatedObject.HasComponent<MetaCore::MetaCoreScriptComponent>(), "停止恢复后 Script 组件应保留");
MetaCoreExpectVec3Near(
updatedObject.GetComponent<MetaCore::MetaCoreTransformComponent>().RotationEulerDegrees,
glm::vec3(0.0F, 0.0F, 0.0F),
"Undo 后 RotatorScript 旋转应回到播放前"
"停止后 RotatorScript 旋转应恢复播放前"
);
MetaCoreExpectVec3Near(
updatedObject.GetComponent<MetaCore::MetaCoreTransformComponent>().Position,
glm::vec3(0.0F, 0.0F, 0.0F),
"Undo 后 MoverScript 位移应回到播放前"
"停止后 MoverScript 位移应恢复播放前"
);
MetaCoreExpect(updatedObject.HasComponent<MetaCore::MetaCoreScriptComponent>(), "Undo 后 Script 组件应保留");
MetaCoreExpect(updatedObject.GetComponent<MetaCore::MetaCoreScriptComponent>().Instances.size() == 2, "Undo 后脚本实例列表应保留");
MetaCoreExpect(updatedObject.GetComponent<MetaCore::MetaCoreScriptComponent>().Instances.size() == 2, "停止恢复后脚本实例列表应保留");
coreServicesModule->Shutdown(moduleRegistry);
moduleRegistry.ShutdownServices();
@ -4003,16 +3979,16 @@ int main() {
MetaCoreTestComponentRegistryDescriptors();
std::cout << "[RUN] MetaCoreTestPlayModeStateMachineAndLifecycle..." << std::endl;
MetaCoreTestPlayModeStateMachineAndLifecycle();
std::cout << "[RUN] MetaCoreTestPlayModeRotatorRetainsChangesAsSingleUndoStep..." << std::endl;
MetaCoreTestPlayModeRotatorRetainsChangesAsSingleUndoStep();
std::cout << "[RUN] MetaCoreTestPlayModeRotatorRestoresPrePlaySnapshotOnStop..." << std::endl;
MetaCoreTestPlayModeRotatorRestoresPrePlaySnapshotOnStop();
std::cout << "[RUN] MetaCoreTestNativeScriptRegistryAndDefaults..." << std::endl;
MetaCoreTestNativeScriptRegistryAndDefaults();
std::cout << "[RUN] MetaCoreTestScriptComponentSerializationSnapshotAndJson..." << std::endl;
MetaCoreTestScriptComponentSerializationSnapshotAndJson();
std::cout << "[RUN] MetaCoreTestNativeScriptLifecycle..." << std::endl;
MetaCoreTestNativeScriptLifecycle();
std::cout << "[RUN] MetaCoreTestNativeScriptBehavioursRetainChangesAsSingleUndoStep..." << std::endl;
MetaCoreTestNativeScriptBehavioursRetainChangesAsSingleUndoStep();
std::cout << "[RUN] MetaCoreTestNativeScriptBehavioursRestorePrePlaySnapshotOnStop..." << std::endl;
MetaCoreTestNativeScriptBehavioursRestorePrePlaySnapshotOnStop();
std::cout << "[RUN] MetaCoreTestSceneRenderSyncBuildsRenderableCameraLightSnapshot..." << std::endl;
MetaCoreTestSceneRenderSyncBuildsRenderableCameraLightSnapshot();
std::cout << "[RUN] MetaCoreTestJsonSceneSaveCurrentSceneUsesMcsceneJson..." << std::endl;