docs: record STEP-058A cadence lifecycle fix

This commit is contained in:
OpenAI Codex
2026-09-07 15:16:18 +08:00
parent ab86eb8f67
commit 7188040e87
4 changed files with 66 additions and 0 deletions

View File

@@ -23,3 +23,11 @@ target 切换仅更新 source/timeline cadence,不 reload Style、不重提交
## 测试策略
cadence deadline 通过显式 `steady_clock::time_point`/duration 的 deterministic 测试验证,不使用 sleep:AUTO always due、30/60 deadline 前后、target switch 和 single-authority 行为。Android popup 仅作为 Host 模拟器提供 FPS AUTO/30/60 与 HUD 显示;Android Gradle/设备验收另行执行。
## STEP-058A shared advance 与 Runtime 生命周期修正
`RasterArrayTimelineRuntime::advanceIfDue(now)` 在同一 mutex 内完成 due 判定、cadence revision、真实 wall-time Timeline 推进和 frame 返回。Particle 与 WeatherColor 均可作为 consumer;先到者推进,后到者收到相同 `cadenceRevision` 且不会再次推进。Particle 用 revision 判断是否运行 State/Trail,因而 WeatherColor-only PLAY 不再依赖 Particle pass,也不会发生双 tick。
WeatherColor 在 PLAY 时参与 shared advance;PAUSE 时仅显示当前 frame,`needsRepaint()` 不主动保持连续刷新。Particle 保持 active 时,即使 Timeline PAUSE,仍按 cadence 推进自身 simulation。两层 hidden 时 facade 不再安装 delayed wake-up。
`WeatherRuntime.dispose()` 是 map/style-scoped、幂等的 ownership 结束接口:取消 Handler callback,旧 Runnable 被执行时也不会 repaint 或再次 schedule,后续 control API 拒绝或 fail-fast。Test App 在 style reload、离开 REAL WEATHER 与 Activity destroy 前都先 dispose 旧 Runtime。

View File

@@ -31,3 +31,12 @@ canonical field、field bytes、submit result、timestamp、playback、WeatherCo
## 剩余风险
Android JNI/Java compile 与设备上 30/60 tick、camera 并发、visibility/off wake-up 仍需统一人工验收;天气 camera skipped-frame composite 的具体 GPU 视觉连续性需实机确认。
## STEP-058A Shared Cadence 与 WeatherRuntime 生命周期修正
状态:`IMPLEMENTED / WAITING_ANDROID_VALIDATION`。
- 以 `RasterArrayTimelineRuntime::advanceIfDue()` 取代 renderer 单独 `tick()`,在 timeline 锁内原子完成 deadline claim、revision 标记和 wall-time 推进。WeatherColor-only + PLAY 可独立推进 MIX;同一 deadline Particle 后到仅消费相同 frame/revision,不会双推进。
- WeatherColor-only + PAUSE 不主动持续 repaint;Particle visible + PAUSE 保持粒子 cadence;两层 hidden、clear/disable 不再由 facade 保留 delayed wake-up。
- 新增幂等 `WeatherRuntime.dispose()`;disposed 后取消 callback、旧 Runnable 不 repaint/不重排,控制 API 拒绝或 fail-fast。Test App 在 style reload、leave REAL WEATHER、Activity destroy 前显式释放旧 Runtime。
- Linux/OpenGL 增量 build、`Source.RasterArray*` deterministic/source 定向测试和 `git diff --check` 通过;Android Gradle/APK/ADB/设备/Jest 未执行。

View File

@@ -0,0 +1,44 @@
# STEP-058A Shared Cadence 与 WeatherRuntime 生命周期修正 — Codex 完成报告
状态:`IMPLEMENTED / WAITING_ANDROID_VALIDATION`
## 实际修正
- shared cadence advance 收敛至 `RasterArrayTimelineRuntime::advanceIfDue(now)`:同一 mutex 内完成 due 判断、cadence revision、真实 monotonic elapsed 的 Timeline 推进和 frame 返回。
- Particle 与 WeatherColor 都可消费 shared advance。WeatherColor-only + PLAY 首先到达 deadline 时可独立推进 MIX;Particle 在同一 cadence window 后到只读取已推进 revision,不会双 tick。
- WeatherColor-only + PAUSE 的 `needsRepaint()` 不再主动持续刷新;Particle visible + PAUSE 仍以自身 simulation cadence 运作;两层 hidden 时 facade 不调度 wake-up。
- 新增幂等 `WeatherRuntime.dispose()`。它取消 pending Handler callback;旧 Runnable 即使执行也不会 `triggerRepaint()` 或再次 schedule;dispose 后 Command API 拒绝、submit/playback/seek fail-fast。
- Test App 在 style reload、离开 REAL WEATHER、Activity destroy 之前显式 dispose 旧 Runtime。
## 修改文件
- `include/mbgl/style/sources/raster_array_source.hpp`
- `src/mbgl/style/sources/raster_array_source.cpp`
- `src/mbgl/renderer/layers/render_particle_validation_layer.cpp`
- `src/mbgl/renderer/layers/render_raster_particle_layer.hpp`
- `src/mbgl/renderer/layers/render_weather_color_layer.cpp`
- `platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/WeatherRuntime.java`
- `platform/android/MapLibreAndroid/src/test/java/org/maplibre/android/maps/WeatherRuntimeStateTest.java`
- `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/ParticleCoreLayerValidationActivity.kt`
- `test/style/source.test.cpp`
- STEP-058 设计/Step 记录、`粒子开发记录.md` 与本报告。
## 验证
- throttle 下 Linux/OpenGL `ninja -C build-linux-opengl mbgl-test-runner mbgl-render-test-runner`:PASS。
- throttle 下 `mbgl-test-runner --gtest_filter='Source.RasterArray*'`:PASS,包含 shared cadence deterministic deadline、单 consumer advance、PAUSE、target switch 与 missed deadline no-busy-loop 覆盖。
- `git diff --check`:PASS。
- 未执行 Android Gradle、APK、ADB、设备/虚拟机测试或 Jest。
## 风险与人工验收
Android JNI/Java 编译、Handler callback 与真机 30/60 FPS、Particle OFF/WeatherColor ON PLAY/PAUSE、两层 OFF、style reload/remount 下旧 Runtime wake 停止仍需后续人工验收。Core 的 T0/T1/MIX、field reuse、normal boundary `simulationRebuild=false`/`trailCleared=false` 未重写。
## Git
- Starting HEAD:`8d12a4b361fe0b59a03327ea4ee782f01c554533`
- 功能 commit:待提交后记录
- 文档 commit:待提交后记录
- Push:待提交后记录
- Remote branch:`origin/particle/main`
- Final HEAD:待提交后记录

View File

@@ -488,6 +488,11 @@ WeatherColorLayer 的 `ParticleGpuValidationUBO` designated initializer 补齐 `
- Android `WeatherRuntime.setTargetFps()` 通过 typed MapLibreMap/JNI source setter 接线;使用已有 `triggerRepaint()` 做目标间隔 delayed wake-up,不使用全局 `MapView#setMaximumFps()`,REAL WEATHER popup 提供 FPS AUTO/30/60 与 HUD。
- 未到 deadline 的 camera frame 不推进天气 State/Trail/Timeline;两层 visibility、PLAY/PAUSE、clear/disabled 组合按 shared cadence 规则处理。Linux/OpenGL 增量构建与 deterministic/source 定向测试通过,Android Gradle/设备/Jest 未执行。
## 2026-09-07 — STEP-058A Shared Cadence 与 WeatherRuntime 生命周期修正
- `advanceIfDue()` 将 shared deadline claim、cadence revision、真实 wall-time MIX 推进合为 Source-owned 原子操作;WeatherColor-only PLAY 能推进 timeline,Particle 后到同一 deadline 不重复推进 State/Trail/Timeline。
- WeatherColor-only PAUSE 不维持连续 repaint;Particle PAUSE 仍可独立按 cadence 运动。`WeatherRuntime.dispose()` 幂等取消 Handler wake,Test App 在 style reload、leave REAL WEATHER、Activity destroy 显式释放旧 facade。
## 2026-09-07 — STEP-057D 审计后小修正
- 独立代码审计发现 REAL WEATHER 下 `WeatherRuntime` timeline 命令被拒绝时,TestApp 原条件表达式会跳过 reject 分支并误记为成功。