From 8592dae3ab9a8be906f125caa90b6ddcf61d55de Mon Sep 17 00:00:00 2001 From: OpenAI Codex Date: Thu, 10 Sep 2026 08:44:30 +0800 Subject: [PATCH] docs: add STEP-064 RN field renderer task --- ...-064_RN纯FieldRenderer接口V2_Codex任务_v1.md | 517 ++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 docs/40_任务/STEP-064_RN纯FieldRenderer接口V2_Codex任务_v1.md diff --git a/docs/40_任务/STEP-064_RN纯FieldRenderer接口V2_Codex任务_v1.md b/docs/40_任务/STEP-064_RN纯FieldRenderer接口V2_Codex任务_v1.md new file mode 100644 index 000000000..61f1185bf --- /dev/null +++ b/docs/40_任务/STEP-064_RN纯FieldRenderer接口V2_Codex任务_v1.md @@ -0,0 +1,517 @@ +# STEP-064 RN 纯 Field Renderer 接口 V2 — Codex 任务 v1 + +## 0. 任务定位 + +本任务把 `@navsea/maplibre-particle-rn` 从当前开发期的 Weather/Wind 导向 RN API,整理为正式宿主可使用的**纯 Field Renderer RN SDK**。 + +目标 RN 包版本: + +```text +13.4.1-particle.2 +``` + +本任务不是粒子算法升级,不是 WeatherV2 功能扩展,也不是 Native/Core 重构。 + +核心原则只有一条: + +> React/宿主负责业务、数据获取、provider、数据类型和显示策略;Particle RN SDK 只接收 canonical Field 并控制 MapLibre Native 图场与粒子渲染。 + +当前除了 Test App 没有正式消费者,因此本任务**不承担旧 RN 公共 API 兼容责任**,允许直接删除旧接口并同步修改测试宿主。 +## 1. 仓库与当前基线 + +仓库: + +```text +/mnt/sda1/MapLibreParticleLab +``` + +分支: + +```text +particle/main +``` + +任务书编写时源码基线: + +```text +f31c0ea1571aa3429ec170fbf38bdecf45c847ae +``` + +开始执行时必须重新确认 `git status --short`、当前分支、`HEAD` 与 `origin/particle/main`。若远端已合法推进,先阅读新增提交,不得 reset 或覆盖。 + +当前工作树存在与本任务无关的 modified/untracked 文件。禁止 `git add .`、`git add -A`,禁止恢复、删除、覆盖或提交这些无关文件。 +## 2. 执行前必须阅读 + +至少阅读以下实际文件: + +```text +AGENTS.md +PARTICLE_BASELINE.md +docs/00_项目规范/01_Codex协作规范_v1.md +docs/00_项目规范/02_构建与验证规范_v1.md +docs/00_项目规范/03_Step阶段记录规范_v1.md +docs/00_项目规范/05_粒子架构原则_v1.md +packages/maplibre-particle-rn/package.json +packages/maplibre-particle-rn/src/index.ts +packages/maplibre-particle-rn/src/types.ts +packages/maplibre-particle-rn/src/NativeWeatherRuntimeBridge.ts +packages/maplibre-particle-rn/src/weatherV2/* +packages/maplibre-particle-rn/app.plugin.js +integration/react-native/MapLibreParticlePackageConsumerTestHost/* +release/maplibre-particle/release-manifest.json +docs/30_设计/MapLibre粒子ReactNative使用说明_v2.md +``` + +实现必须依据当前实际源码,不得根据任务书示例猜接口或目录。 +## 3. 冻结的架构边界 + +### 3.1 SDK 不理解业务 + +`@navsea/maplibre-particle-rn` 的正式 RN 公共接口不得出现或要求调用方传入以下业务含义: + +```text +WeatherV2 +ECMWF +wind +wave +rain +tide +weather layer +dataset +manifest +time_index +HTTP URL/provider/cache/retry +Route / ETA +NavSea 业务状态 +``` + +这些全部属于 React/宿主层。 + +### 3.2 数据只有一份 + +同一份 canonical Field 进入 Runtime 一次。图场 Renderer 与 Particle Renderer 是对同一 Field 的两种独立显示方式,不建立两套 Field 数据、不要求重复提交。 +逻辑必须保持: + +```text +Canonical Field + ├─ Field Renderer ON / OFF + └─ Particle Renderer ON / OFF +``` + +宿主可以任意组合两个 Renderer 的显示状态。SDK 不根据业务类型自动决定是否显示粒子。 + +### 3.3 本任务不改变 canonical / Native 技术 + +本任务保持当前已验证 Native/Core 能力: + +```text +maplibre-particle-field/v1 +metadataJson + local file payload +float32-le / interleaved-uv +Timeline / T0-T1 Runtime Field Window +GPU 时间插值 +WeatherColorLayer +RasterParticleLayer +Particle State / Trail +Playback / target FPS +``` + +不得为了 RN 命名整理修改 C++、shader、JNI、Java/Kotlin WeatherRuntime、MapLibre Native renderer 或 Android AAR 内容。 +## 4. 必做项 A:建立最终 RN 公共 API + +新增纯渲染公共入口,建议名称: + +```ts +FieldRuntime +``` + +正式调用方应从包根入口使用它。目标公开方法至少包括: + +```text +attach() +detach() +getState() +clearFields() +submitField() +setEnabled() +setFieldVisible() +setParticleVisible() +setTargetFps() +setTargetTime() +setPlaybackState() +setPlaybackSpeed() +setFieldColorStops() +setParticleColor() +setTrailColor() +setParticleCount() +setParticleLineWidth() +setParticleLength() +setParticleOpacity() +setTrailOpacity() +setTrailFade() +setFieldOpacity() +``` + +这些方法可以在 RN/TS 层薄映射到当前已验证的 Native bridge 方法,不得因此修改 Native 方法名。 +公共 API 中不得继续暴露以下旧名称: + +```text +WeatherRuntime +submitWindField +clearWindFields +setWeatherEnabled +setWeatherColorVisible +setWeatherColorStops +setWeatherColorOpacity +setForecastTime +``` + +当前内部 `NativeWeatherRuntimeBridge.ts`、TurboModule 名 `WeatherRuntimeBridge`、Native 生成类名等若属于既有 Native ABI/Codegen 接缝,可作为本任务内部实现细节保留;但不得从包根入口继续暴露,也不得要求宿主使用这些名字。 + +由于没有正式消费者,不建立 deprecated alias,不增加 compatibility wrapper,不同时维护两套公共 API。 + +## 5. 必做项 B:公共类型去业务化 + +将面向宿主的类型改为纯 Field Renderer 语义。 + +例如当前 `ColorStop.speedMps` 不应继续作为最终 RN 公共命名;建议公开为: + +```ts +type FieldColorStop = Readonly<{ + value: number; + red: number; + green: number; + blue: number; + alpha: number; +}>; +``` + +RN 内部可把 `value` 薄转换成当前 Native bridge 所需字段,不修改 Native/Core。 +以下现有类型可在确认无业务耦合后继续使用或适当重命名: + +```text +RuntimeState +PlaybackState +TargetFps +CommandResult +FieldSubmitResult +RuntimeSnapshot +``` + +不得新增: + +```text +WeatherLayer +WindLayer +RainLayer +WaveLayer +TideLayer +ProviderType +DatasetType +``` + +`submitField()` 仍只负责把当前 canonical metadata 与本地 binary payload 交给既有 Native ingress。RN SDK 不解析业务类型,也不根据 field 内容决定 Renderer 组合。 + +当前 canonical metadata 中若存在 Native/Core 已冻结的历史字段名,本任务不为追求命名纯净而修改其 schema;RN 层只把它视为 Native 数据契约,不增加业务解释。 +## 6. 必做项 C:WeatherV2 完全移出正式 package + +当前 package 根入口存在: + +```ts +export * from "./weatherV2"; +``` + +且 `packages/maplibre-particle-rn/src/weatherV2/` 内包含 HTTP、manifest、time index、WVECBIN1 decoder 和高层 loader。 + +这些全部属于宿主业务/数据适配,不属于纯 Renderer SDK。 + +必须: + +1. 从正式 package 根导出删除 WeatherV2 API; +2. 从正式 package 源码中移除 `src/weatherV2/`; +3. 不在 package 内留下其他 provider/network/weather helper 替代品; +4. Consumer Test Host 若仍要验证真实 WeatherV2,可以把必要 WeatherV2 逻辑放到 Test Host 自己的 `src/` 中; +5. Test Host 的业务代码最终只把 canonical Field 交给 `FieldRuntime.submitField()`。 + +禁止新增诸如 `loadWeatherV2IntoRuntime()`、`loadLayer()`、`WeatherFieldType` 等换名后的业务包装。 +## 7. 必做项 D:MapLibre RN 与 Style Helper 收口 + +正式 package 不再把自己伪装成完整 MapLibre RN facade。 + +包根入口应停止: + +```ts +export * from "@maplibre/maplibre-react-native"; +``` + +宿主继续直接安装并使用固定 peer dependency: + +```text +@maplibre/maplibre-react-native@11.3.6 +``` + +宿主地图组件从官方包导入;粒子/图场 Runtime 从 `@navsea/maplibre-particle-rn` 导入。必须确认这不会引入第二份 MLRN native module。 + +删除业务化的 `particleWeatherIds`、`createParticleWeatherStyle()` 公共命名。建议提供纯渲染命名: + +```text +particleFieldIds +createParticleFieldStyleFragment() +``` + +Style helper 只能返回/描述 Particle 所需 source + Field layer + Particle layer,不得内置 GSI、WeatherV2 或任何业务底图。 +当前 Native attach 依赖的内部 style ID 若仍是: + +```text +rn-weather-fields +rn-weather-color +rn-weather-particles +``` + +本任务不得为了字符串改名进入 Native/Core。允许 `particleFieldIds` 暂时映射这些既有内部 ID;README 必须要求宿主使用导出的常量/helper,不要自行硬编码这些历史字符串。 + +## 8. 必做项 E:RN import 在无 Native module 平台安全 + +当前 `NativeWeatherRuntimeBridge.ts` 使用 `TurboModuleRegistry.getEnforcing()`,会让不具备 `WeatherRuntimeBridge` 的平台在 import 阶段直接失败。 + +本任务只在 RN/TS 层解决: + +- 包根入口被 import 时,不得因为 Native module 缺失立即 throw; +- `FieldRuntime` 真正执行 Native 方法时,若 bridge 不存在,应以清楚、稳定的错误失败; +- 不为此新增 iOS Native 实现; +- 不修改 Android Native bridge ABI; +- 不允许静默返回伪 `ACCEPTED` 或伪 Runtime state。 + +具体实现应依据 RN 0.85.2 TurboModule API 做最小改动。 +## 9. 必做项 F:版本关系必须真实 + +RN package 版本升级为: + +```text +@navsea/maplibre-particle-rn@13.4.1-particle.2 +``` + +但本任务不修改 Native,因此 Android Native artifact 继续使用当前已验证版本: + +```text +cc.navsea.maplibre:android-sdk-particle-opengl:13.4.1-particle.1 +``` + +不得仅为了数字一致而复制、重编或发布内容相同的 `.2` AAR。 + +`app.plugin.js` 的 dependency substitution 必须继续解析到 Native `.1` AAR,除非实际调查发现当前正式 AAR 坐标已经合法变化。 + +更新 release manifest,使其明确区分: + +```text +RN package version = 13.4.1-particle.2 +Native artifact version = 13.4.1-particle.1 +``` + +并注明 `.2` 是 RN-only public API revision,Native/Core source 与已验证 `.1` AAR 不变。 +不得覆盖或重新上传现有: + +```text +navsea-maplibre-particle-rn-13.4.1-particle.1.tgz +``` + +本任务只生成新的 `.2` 本地 pack 产物供后续验证,不负责正式静态 HTTPS 上传或 release tag。 + +## 10. 必做项 G:Consumer Test Host 同步到最终 API + +修改: + +```text +integration/react-native/MapLibreParticlePackageConsumerTestHost/ +``` + +要求: + +- `Map` / `Camera` 改为直接从 `@maplibre/maplibre-react-native` 导入; +- Renderer Runtime 只从 `@navsea/maplibre-particle-rn` 导入 `FieldRuntime` 和纯渲染类型/helper; +- 本地真实 WeatherV2 测试能力可以继续存在,但 WeatherV2 HTTP、decoder、选帧、临时文件管理全部位于 Test Host 自己的业务目录; +- 最终提交给 SDK 的仍是 canonical metadata + local binary file; +- Test Host 不得反向依赖 package 内部源码路径; +- Test Host UI 可以继续使用 Weather/ECMWF 文案,因为它是测试宿主,不是 SDK 公共接口。 +旧 `MapLibreParticleRNTestHost` 属于历史 bridge 验证宿主,不要求为了本任务全部重构;除非它参与当前 package 构建/类型检查并形成 blocker,否则不要扩大范围。 + +## 11. 必做项 H:文档更新 + +保留现有: + +```text +docs/30_设计/MapLibre粒子ReactNative使用说明_v2.md +``` + +作为 `.1` 历史接口说明,不覆盖。 + +新增: + +```text +docs/30_设计/MapLibre粒子ReactNative使用说明_v3.md +``` + +v3 必须以 `13.4.1-particle.2` 最终真实代码为准,说明: + +- 安装 `.2` RN package 与 MLRN 11.3.6; +- RN `.2` 对应 Native AAR `.1`; +- Map/Camera 从官方 MLRN 导入; +- `FieldRuntime` 全部公共方法、参数和返回值; +- canonical Field submission; +- 图场与粒子独立显示开关; +- Style fragment 如何合入宿主现有 style; +- React/宿主负责业务数据,SDK 不负责 provider/network/weather。 +同步更新: + +```text +packages/maplibre-particle-rn/README.md +packages/maplibre-particle-rn/CHANGELOG.md +packages/maplibre-particle-rn/package.json +``` + +README 不得继续推荐 WeatherV2 高层 loader,也不得把 SDK 描述成天气客户端。 + +CHANGELOG 必须明确 `.2`: + +```text +- RN 公共接口去 Weather/Wind 业务化 +- WeatherV2 helper 移出正式 package +- 图场与粒子继续消费同一 canonical Field,并可独立开关 +- Native/Core/GPU 未修改 +- 继续复用 Android AAR 13.4.1-particle.1 +``` + +## 12. 明确禁止范围 + +本任务禁止修改: + +```text +include/mbgl/** +src/mbgl/** +platform/android/MapLibreAndroid/** +shaders/** +CMake / Core renderer +Android AAR 内容与 publication 源码 +NavSea 仓库 +``` + +若实现纯 RN API 时发现必须修改以上任一 Native/Core 文件,立即停止扩大修改,在完成报告中写明 blocker 和原因。 +## 13. 静态与包验证 + +Codex 必须完成以下非 Android 验证: + +```text +1. package TypeScript typecheck +2. Consumer Test Host TypeScript typecheck +3. npm pack +4. tarball 内容审计 +5. package 根导出审计 +6. 业务语义残留审计 +7. git diff --check +``` + +`npm pack` 生成的新 `.2` tgz 不提交 Git,除非仓库当前发布规则明确要求;不得碰现有未跟踪 `.1` tgz。 + +包内容必须确认不存在: + +```text +src/weatherV2/ +WeatherV2HttpClient +loadWeatherV2WindIntoRuntime +decodeWeatherV2WindFrame +NavSea 业务源码 +Test Host +node_modules +临时日志/构建缓存 +``` + +允许内部保留 Native ABI 接缝中的 `WeatherRuntimeBridge` 名称和现有 `rn-weather-*` style ID,但这些不得作为新的业务 API 暴露。 +## 14. Android 验证边界 + +本任务不得执行 Android Gradle、AAR build/publish、APK build/install、ADB 或设备操作。 + +因为 Native AAR 不变,本任务完成后优先采用既有包含 `.1` Native bridge/AAR 的 Consumer APK,通过 Metro 验证新的 `.2` JS/TS API;只有后续确认 Native 文件或 Android 构建配置实际发生变化时,才需要用户重新编译 APK。 + +Codex 最终必须给出用户后续最小验证步骤,但不得自行执行 Android 操作。 + +## 15. Step、开发记录与完成报告 + +执行完成后新增/更新: + +```text +docs/50_Step记录/STEP-064_RN纯FieldRenderer接口V2_v1.md +docs/报告/STEP-064_RN纯FieldRenderer接口V2_Codex完成报告_v1.md +粒子开发记录.md +``` + +Step 状态在未完成人工 Consumer 验证前写为: + +```text +进行中(代码完成,待 Consumer 验证) +``` + +完成报告可使用: + +```text +IMPLEMENTED / WAITING_CONSUMER_VALIDATION +``` + +不得提前写 RELEASED、CLOSED / PASS 或 Android validated。 +## 16. Git 收尾 + +完成代码、文档和静态验证后,必须只精确 stage 本任务文件并提交,随后 push: + +```text +origin/particle/main +``` + +禁止把当前已有无关 modified/untracked 文件带入提交。 + +建议代码提交信息: + +```text +refactor: make RN particle API field-renderer only +``` + +如文档单独提交,建议: + +```text +docs: record STEP-064 RN field renderer API v2 +``` + +Push 后必须确认: + +```text +HEAD == origin/particle/main +``` + +Push 失败不得声称任务完成。 +## 17. 最终必做清单 + +- [ ] 确认 `particle/main`、HEAD、远端 HEAD 与工作树 +- [ ] 阅读任务要求与当前 `.1` 实际 package/Consumer 源码 +- [ ] RN package version 升为 `13.4.1-particle.2` +- [ ] 建立 `FieldRuntime` 纯渲染公共入口 +- [ ] 公共 API 删除 Weather/Wind 专用名称 +- [ ] 不建立旧 API 兼容 wrapper +- [ ] `submitField()` / `clearFields()` 继续薄映射既有 Native ingress +- [ ] 图场与粒子保持同一 Field、独立显示开关 +- [ ] `FieldColorStop.value` 等公共类型去业务化 +- [ ] `WeatherV2` 完全移出正式 package +- [ ] package 不再 re-export 整个 MLRN +- [ ] Style helper 改为纯 Particle Field fragment,不内置业务底图 +- [ ] 无 Native module 平台 import package 不立即崩溃 +- [ ] Consumer Test Host 改用最终 `.2` API +- [ ] WeatherV2 测试逻辑如需保留,仅存在于 Test Host 业务层 +- [ ] Native/Core/JNI/shader/AAR 无功能修改 +- [ ] Android AAR 继续为 `13.4.1-particle.1` +- [ ] release manifest 明确 RN `.2` ↔ Native `.1` +- [ ] README、CHANGELOG、React Native 使用说明 v3 更新 +- [ ] package/Consumer TypeScript 检查通过 +- [ ] `.2` `npm pack` 与 tarball 内容审计通过 +- [ ] `git diff --check` 通过 +- [ ] 更新 STEP-064、完成报告、粒子开发记录 +- [ ] 精确 commit 并 push `origin/particle/main` +- [ ] 最终报告 commit hash、message、push result、Final HEAD + +Codex 不需要在开工前提交实施计划。结束时直接按本清单逐项报告“已完成 / 未完成 / 无法验证”,任何未完成项必须说明原因,不得静默跳过。 \ No newline at end of file