Files
MapLibreParticleLab/docs/50_Step记录/STEP-045_Runtime_Field动态更新接口_v1.md
OpenAI Codex 4e31163516
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
test: add runtime field duplicate noop control
2026-09-03 19:02:21 +08:00

4.3 KiB
Raw Permalink Blame History

STEP-045 Runtime Field 动态更新接口

  • 状态:IMPLEMENTED / WAITING FOR ANDROID VALIDATION
  • 前置:40-03 / STEP-044 已 CLOSED / PASS。
  • 范围:唯一正式链路 RasterArraySource -> RasterParticleLayer -> GPU State/Trail/Composite 的低频内存 Field 时间窗推进;不接网络或真实天气 Provider。

实现

  • RasterArraySource::updateRuntimeFieldWindow(ParticleFieldSnapshot) 是正式强类型入口。它验证 Source 已加载、Snapshot 有效、grid/bounds/NoData 等插值契约兼容且 runtime generation 单调递增;成功时只把 Source 的权威窗口从 T0/T1 原子推进为 T1/newT1,并发出 onSourceChanged()。
  • 已有的 RasterArraySource::Impl::field/nextField 继续是正式 T0/T1 权威状态。Kotlin 不保存 T0/T1,JNI 不保存窗口或管理 renderer/GPU;Android 仅以 source id 调用薄桥 advanceRasterArraySourceFieldWindow()。
  • 为离线 Android 验证,Style 的 runtime-fields 在 Source 内预加载 C=vortex、D=nodata。advanceRuntimeFieldWindow() 只从该 Source-owned 队列取候选;候选资源完成顺序不影响 revision,因为 candidate 进入权威 T1 时才取得 process-wide generation。
  • A=uniform-east、B=uniform-north、C=vortex、D=nodata。因此两次按钮推进是 A/B→B/C→C/D;不调用 setStyle(),不重建 Layer/Source。
  • Renderer 继续使用已有 content identity 与双 Field slot:旧 T1 成为新 T0 时记录 FIELD_REUSE from=OLD_T1 to=NEW_T0;只有新 T1 按 FIELD_UPLOAD reason=NEW_CONTENT 上传。窗口有重叠时既有逻辑保持 simulationRebuild=false、trailCleared=false。
  • raster-particle-time-mix 未改,仍仅更新 Core paint property/UBO;它不上传 Field、不清 trail、不 reset simulation、不 reload Style。

失败与重复语义

  • 当前 T1 内容重复提交:NOOP,不发出 Source change、upload 或 reset。
  • 缺失/非法 Snapshot、未加载 Source、不兼容 grid、非单调 generation、候选未完成或耗尽:FIELD_WINDOW_UPDATE_REJECTED reason=...,当前有效窗口和 simulation 原样保留。
  • 更新是低频事件;没有每帧 Field copy、hash、Snapshot 创建或 texture upload。

Android 待验收

  1. 点击 TIME WINDOW 建立 A/B,检查 MIX 0/50/100。
  2. 第一次 ADVANCE:检查 B→新 T0 reuse、只上传 C、没有 style/layer/source recreate、simulationRebuild=false、trailCleared=false。
  3. 第二次 ADVANCE:同样检查 C→新 T0 reuse、只上传 D。
  4. 在 C/D 再检查 MIX 0/50/100;Field upload/reset/trail clear 计数不应因 MIX 改变。
  5. 第三次 ADVANCE 应明确拒绝 NO_PRELOADED_FIELD,不中断当前窗口。

本地验证边界

  • Linux/OpenGL 精确编译:raster_array_source.cpp.o、style/conversion/source.cpp.o、source.test.cpp.o。
  • 新增 Source 定向测试对象覆盖 A/B→B/C→C/D、重复 Snapshot NOOP、无效 Snapshot fail-closed,并已精确编译;当前 build tree 缺少大量无关测试依赖,未把完整 mbgl-test 二进制执行误报为通过。
  • 未运行 Android Gradle、ADB、APK 安装、设备测试或 Jest。
  • 实现提交:45502a53f4fc486bd24cb0008d1ab0ff221e7e63(feat: add runtime particle field updates);文档收尾另行提交。

T-RUNTIME-05 Duplicate NOOP 补验收入口

  • 用户已完成 T-RUNTIME-01~04 与 T-RUNTIME-06 Android 手工验证;本轮只补 T-RUNTIME-05 的真实触发入口,状态仍为 IMPLEMENTED / WAITING FOR ANDROID VALIDATION。
  • DUPLICATE T1 按钮经 MapLibreMap -> NativeMapView -> JNI -> RasterArraySource::repeatRuntimeFieldWindow() 重提 Source 当前 T1;它不调用 setStyle()、不推进 candidate queue,也不改变 Kotlin 的 MIX/窗口状态。
  • repeatRuntimeFieldWindow() 只把已存在的 Impl::nextField 交给既有 updateRuntimeFieldWindow()。在 T0=vortex/T1=nodata,content identity 命中既有 T1,正式 API 返回 Noop,不发 Source change,因而不触发 Field upload、GPU slot 交换、simulation reset 或 trail clear。
  • 新增 Source test assertion 在 C/D 后调用该入口并验证返回 Noop、T0/T1 未变、sourceChangedCount 未增加。Linux/OpenGL 的 raster_array_source.cpp.o 与 source.test.cpp.o 以 -Werror 精确编译;Android Gradle、ADB、设备和 Jest 未执行。