88 lines
2.9 KiB
Markdown
88 lines
2.9 KiB
Markdown
# 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)
|