fix: serialize WeatherV2 particle loads
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
OpenAI Codex
2026-09-09 20:42:17 +08:00
parent e15f583c65
commit 266ef6a184
3 changed files with 28 additions and 3 deletions

View File

@@ -6,6 +6,7 @@
- 包含 WeatherColor、RasterParticle、HostField binary file ingress、Timeline / Playback 与 React Native WeatherRuntime。
- Native/RN binary ingress 已在 STEP-061 验证;GSI + 真实 WeatherV2 + Particle Android 综合验证已在 STEP-062 完成。
- 发布前 Consumer 验证修正 MLRN 依赖为 peer dependency,避免嵌套 native module 与 Windows codegen 长路径。
- WeatherV2 HTTP 全帧加载增加按 map `reactTag` 的 single-flight 保护,避免重复点击造成并发 clear/submit 与非单调快照拒绝。
- 新增纯 JS/TS WeatherV2 HTTP 客户端:manifest/time-index → WVECBIN1 full wind frame → canonical interleaved U/V。
- 新增 `loadWeatherV2WindIntoRuntime()`:顺序下载、转换、写临时 binary file 并通过现有 WeatherRuntime 提交,不建立第二套 Timeline/MIX。
- WeatherV2 文件存储通过 `WeatherV2BinaryFileStore` 注入,包本身不强依赖 Expo FileSystem,NavSea 可复用自己的缓存实现。

View File

@@ -21,7 +21,9 @@ function expectedSubmit(index: number): FieldSubmitResult {
* U/V contract and submits it through the existing map-owned WeatherRuntime.
* Core remains the sole owner of T0/T1/MIX and playback interpolation.
*/
export async function loadWeatherV2WindIntoRuntime(
const inFlightLoads = new Map<number, Promise<LoadWeatherV2WindResult>>();
async function loadWeatherV2WindIntoRuntimeInternal(
options: LoadWeatherV2WindOptions,
): Promise<LoadWeatherV2WindResult> {
const { reactTag, client, fileStore } = options;
@@ -93,3 +95,20 @@ export async function loadWeatherV2WindIntoRuntime(
}
return { context, frames: loaded, runtime };
}
/**
* Serializes full WeatherV2 loads per map view. Repeated taps while a load is in flight
* reuse the same Promise instead of clearing/submitting a second overlapping timeline.
*/
export function loadWeatherV2WindIntoRuntime(
options: LoadWeatherV2WindOptions,
): Promise<LoadWeatherV2WindResult> {
const existing = inFlightLoads.get(options.reactTag);
if (existing != null) return existing;
const task = loadWeatherV2WindIntoRuntimeInternal(options).finally(() => {
if (inFlightLoads.get(options.reactTag) === task) inFlightLoads.delete(options.reactTag);
});
inFlightLoads.set(options.reactTag, task);
return task;
}