7.6 KiB
STEP-048 下一阶段规划调查报告
基线与方法
- 分支:
particle/main;本地和origin/particle/mainHEAD 均为46dceb5cb6110c94393b7413465f843844dd6502。 - 使用 Gitea API
api/v1/repos/tei/MapLibreParticleLab/branches/particle%2Fmain确认,不依赖网页缓存。 - 工作区只有用户既有 untracked 任务书、日志和
STEP-046-e48fa087-review.diff;本调查不触碰它们。
当前实际结构
Core Runtime
src/mbgl/style/sources/raster_array_source.cpp的RasterArrayTimelineRuntime持有 entries、cursor (t0/mix)、speed、state、gap/invalid、monotonic clock;play/pause/setSpeed/seek/step/recover是低频 Core 命令。- 同文件的
RasterArraySource::updateRuntimeFieldWindow()是已可作为正式输入窗口 API 的最小接入点:检查 validity/compatibility/content identity/generation,推进 T0/T1 并通知 source changed。advanceRuntimeFieldWindow()、repeatRuntimeFieldWindow()和controlRuntimeTimeline()是 validation convenience/control 面。 tryInitializeTimeline()目前将 initial/next/runtime fixture 解码为 6 个 Source-owned snapshot,Validation cache capacity=8;这是有界 validation preload,并非生产 forecast cache。src/mbgl/renderer/layers/render_particle_validation_layer.cpp的RenderRasterParticleLayer读取RenderRasterArraySource::impl().field/nextField或 shared timeline;Field identity 决定 GPU upload/reuse,window overlap 保留旧 T1 作为新 T0。其ParticleGpuValidationTweaker::execute()State pass 负责连续 tick/UBO mix;无需 Android per-frame JNI。
RasterParticleLayer 与 Renderer
include/mbgl/style/layers/raster_particle_layer.hpp/src/mbgl/style/layers/raster_particle_layer_impl.hpp定义正式 layer 和强类型 active、mask、timeMix、count、streak/trail/color properties。- GPU state/trail/field texture 生命周期在
render_particle_validation_layer.cpp的ParticleGpuResources;visual property 更新只更新 resources/UBO,不要求 Source reload。 - Renderer 已是正式 raster-particle 路径,但同一实现文件仍含 validation coast mask、legacy validation display 和 fixture diagnostics。这些属于验证快捷路径,不应让 provider/network 进入 renderer。
数据输入边界
src/mbgl/particle/field/offline_fixture_particle_adapter.hpp/.cpp的ParticleFieldSnapshot是 backend-neutral immutable value;包含网格、EPSG:4326 bounds、canonical U=east/V=north、NoData、dataVersion、generation、SHA-256、velocity/valid。OfflineFixtureParticleAdapter::load(bytes)已是纯 C++ bytes loader,但它强制 fixture-v1 schema 和knownFixture()(east/north/vortex/nodata)。RasterArraySource::loadDescription()从 FileSource 请求 metadata/field bytes,再调用它。- Android
ParticleCoreLayerValidationActivity.kt::validationStyle()拼asset://integration/particle-fixtures/...与 runtime fixture descriptors;Kotlin 是 Validation Host,不持有 T0/T1/tick/clock,但确实构造 synthetic fixture source。
Android/JNI 与 WeatherColorLayer
- Android 的 Timeline 控制经
MapLibreMap → NativeMapView → native_map_view.cpp::controlRasterArraySourceTimeline()低频进入 Source;没有 per-frame JNI。TIME/VIS/COUNT/MAP/MORE 都是 Test App 验证面,不应进入正式业务链路。 - 当前仓库没有
WeatherColorLayer实现类或 renderer 文件;它只出现在架构规范,故与当前RasterParticleLayer没有运行时 source/field/timeline 耦合。下一阶段不应实现或合并它。
Validation-only 技术债
状态栏自动 MIX、WAITING/INVALID 可观测性不够明显,已验证为 NON-BLOCKING。它适合未来有 Android 综合 APK 时顺带改善,不能单独触发一次 Android build,也不是 Timeline/Renderer failure。
候选阶段
| 候选 | 目标与价值 | 风险/冻结边界 | Android 综合验收 |
|---|---|---|---|
| A:Provider-neutral C++ Data Adapter | 将 fixture-only decode contract 抽为通用 immutable snapshot adapter,保留 offline fixture adapter 为一个实现;使 Weather Service 未来可向 Source 提交数据而不进入 renderer。 | 中等;必须维持 snapshot identity、NoData、U/V、T0/T1/reuse/fail-closed。 | 高,适合一次验证 raw/in-memory T0/T1、A/B→B/C、invalid。 |
| B:生产 Renderer 清理 | 从 renderer 中拆 validation coast/diagnostics。 | 高,容易触碰已验证 particle path,当前没有真实 data input 的收益低。 | 中等,不推荐现在做。 |
| C:Validation UI 可观测性 | 状态行显示真实 playback state。 | 低但仅工具收益,不能单独编译。 | 仅作为 A 的附带项。 |
| D:WeatherColorLayer | 增加量化颜色层。 | 新模块且缺正式输入 contract,会提前耦合两层。 | 不推荐现在做。 |
推荐:STEP-048「Provider-neutral C++ Field Data Adapter 与 Runtime 输入契约」
英文短名:Field Data Adapter Contract。
目标
- 定义 provider-neutral C++ metadata+bytes → immutable
ParticleFieldSnapshotadapter contract,解除knownFixture()对正式输入的限制。 - 保持
OfflineFixtureParticleAdapter为 fixture-v1 validation implementation,不让 Android/asset API 跨入 Core adapter。 - 为 Source 增加面向已解码 snapshot/时间片描述的明确生产入口,复用现有
updateRuntimeFieldWindow()的 T0/T1 identity、reuse、NOOP、fail-closed 语义。 - 为 invalid/incompatible/provider decode failure 给出明确 error,不污染当前窗口。
- 将 Validation UI observability 作为同一 APK 的小附带项,而非单独阶段。
不做什么
不接真实 HTTP/GRIB/provider/vendor;不改 Timeline clock、Particle Renderer/shader、GPU simulation、WeatherColorLayer、iOS/Metal/Vulkan、React Native、容量或独立 UI 重构。
最小修改面(预期)
- Core:新增
src/mbgl/particle/field/下 provider-neutral adapter/interface 与定向 C++ tests;保留ParticleFieldSnapshotownership(adapter 创建 immutable value,Source 接管/复制一次)。 - Source:
raster_array_source.hpp/.cpp仅增加显式 production submit/decode boundary;复用现有 runtime window API。 - Renderer:不需要修改,除非为读取已经存在的 snapshot identity 做极小编译适配。
- Android:Test App 仅增加一次可发现的 in-memory/provider-neutral validation scenario 与状态展示;JNI 只发低频 submit 命令,绝无 per-frame API。
- 文档:STEP/报告/测试矩阵。
接口方向与生命周期
adapter 输入为 provider-neutral descriptor(logical timestamp、field type/domain/grid/vector/NoData/integrity)与 bytes;输出 immutable snapshot 或 structured decode error。Adapter 不拥有 GPU、Style、Renderer 或网络。Source 是当前 T0/T1/timeline authority;Renderer 只消费 snapshot/GPU textures。decode invalid、time interpolation incompatible、generation/content identity conflict 均 fail-closed,继续最后有效 window。
一次 Android 综合验收
Codex 完成完整批次后,用户在 Linux 一次构建,Windows 一次 copy/install,再在设备 192.168.1.146 用 adb -s 192.168.1.146 ... 验收:初始 provider-neutral A/B;A/B→B/C→C/D reuse/only-new-T1;duplicate NOOP;invalid/incompatible fail-closed/recover;PLAY/PAUSE/MIX/VIS/MAP 回归。命令设计为 Windows PowerShell/CMD,不依赖 Linux grep/sed/awk/tee。
结论
推荐直接编写 STEP-048 实现任务书。需要一个小型 C++ adapter contract(新模块/文件,非新 renderer 架构);不需要新的 Renderer、Timeline 或 WeatherColorLayer 架构。