Files
XCEngine/docs/api/XCEngine/Scene/RuntimeLoop/RuntimeLoop.md

88 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RuntimeLoop
**命名空间**: `XCEngine::Components`
**类型**: `class`
**头文件**: `XCEngine/Scene/RuntimeLoop.h`
**描述**: 在 `SceneRuntime` 之上提供 fixed step、暂停、单帧步进和最大追帧限制的轻量运行时主循环。
## 概览
如果说 [SceneRuntime](../SceneRuntime/SceneRuntime.md) 负责“把一个场景跑起来”,那么 `RuntimeLoop` 负责“按什么节拍去跑”。
它在 `SceneRuntime` 外面再包了一层时间控制逻辑,解决的是:
- fixed update 累积
- 超大帧时间钳制
- 每帧最多执行多少次 fixed step
- 暂停、恢复和单帧步进
## Settings
`RuntimeLoop::Settings` 当前包含三个字段:
| 字段 | 默认值 | 作用 |
|------|------|------|
| `fixedDeltaTime` | `1/50` | 每次 `FixedUpdate` 的时间步长。 |
| `maxFrameDeltaTime` | `0.1` | 单帧输入 `deltaTime` 的最大钳制值。 |
| `maxFixedStepsPerFrame` | `4` | 一帧内最多补跑多少次 fixed step。 |
构造函数和 `SetSettings()` 都会先做一次 sanitize
- `fixedDeltaTime <= 0` 时回退到 `1/50`
- `maxFrameDeltaTime < 0` 时回退到 `0`
- `maxFixedStepsPerFrame == 0` 时回退到 `1`
## 生命周期
### `Start()`
- 清空 fixed accumulator
- 清空暂停 / 单步状态
- 把场景交给内部 `SceneRuntime`
### `Stop()`
- 停止内部 `SceneRuntime`
- 清空 fixed accumulator
- 清空暂停 / 单步状态
## Tick 规则
`Tick(deltaTime)` 的当前行为是:
1. 如果没有运行中的场景,直接返回。
2. 如果处于暂停状态且没有请求单帧步进,直接返回。
3. 把输入 `deltaTime` 钳制到 `[0, maxFrameDeltaTime]`
4. 累加到 `m_fixedAccumulator`
5. 在 accumulator 足够且未超过 `maxFixedStepsPerFrame` 时,重复执行 `SceneRuntime::FixedUpdate(fixedDeltaTime)`
6. 无论 fixed step 执行了多少次,只要本次 tick 没被早退,就各执行一次 `Update(clampedDeltaTime)``LateUpdate(clampedDeltaTime)`
7. 清除单帧步进标记。
## 暂停与单帧步进
- `Pause()` 只在运行中生效,并把 `m_paused` 置为 `true`
- `Resume()` 只在运行中生效,并取消暂停
- `StepFrame()` 会保持暂停状态,但允许下一次 `Tick()` 放行一帧
执行完单帧步进后loop 仍保持暂停。
## 真实使用位置
- `editor/src/Core/PlaySessionController.h` 持有一个 `RuntimeLoop`,用于 play mode 控制。
- `tests/Scene/test_runtime_loop.cpp` 覆盖了 fixed step 累积、delta 钳制、最大 fixed 次数、暂停与单帧步进行为。
## 当前实现边界
- 它当前只包着一个 [SceneRuntime](../SceneRuntime/SceneRuntime.md),不是全引擎级 player loop。
- 没有独立的渲染、输入或音频阶段调度,只处理场景运行时更新。
- 暂停语义只阻止 `Tick()` 自动推进,不会冻结外部系统的时间源。
## 相关文档
- [当前模块](../Scene.md)
- [SceneRuntime](../SceneRuntime/SceneRuntime.md)
- [Scene](../Scene/Scene.md)