动态图片与重绘
阶段73生产源码已冻结,必要CPU/GPU与编译检查通过。匹配Native/WASM/JNI、同一公共宿主脚本与SDK归档已通过本机验收;网站HTTP及应用Git为最后交付步骤,外部平台和正式发行仍未完成。
动态图片通过 map.addImage(id, image, options) 的第二参数提供 onAdd(map, id)、render()、onRemove(),第三参数继续是静态图片选项。回调的this是原图片对象。仅同步CPU RGBA回调在本批范围;Promise、任意GPU句柄和renderWithWebGL不开放。
固定官方MapLibre GL JS 6.14.0原创参考已经核定:初始显示来自登记输入快照,onAdd修改data不会立即上传;render返回true才提交新的像素,false或undefined保留旧显示。true不自动持续动画,继续下一帧需要显式 map.triggerRepaint()。同图多个图标/图案消费者在一个实际frame只调用一次,无需求/全隐藏不调用,重复重绘请求合并。updateImage保留provider并更新其data。
显式removeImage调用onRemove;参考full/null样式替换及map.remove未调用它,项目会静默清除内部引用与迟到token,不能因此泄漏provider。context loss与永久移除不同:onRemove之后恢复provider不会再次onAdd。最后受检像素、失败帧候选与错误恢复按项目明确合同保护,不承诺回滚任意用户JavaScript副作用。
共同核心管理provider身份、实际需求批次和像素应答,函数留在创建它的宿主。DLL/SO使用下文真实image JSON请求/应答通道。Native持续运行时、APP实际UI泵、SDK main/Worker与网页script-host已接入同一算法;宿主在注册成功时独立保存身份,onAdd被中断也能释放,公共宿主与匹配SDK产物的本机验收已通过。一次性脚本结束不承诺回调继续存活。
原生QuickJS或独立脚本Worker可使用实际中断/终止机制。SDK主线程用户JavaScript无法由同一线程强制抢占,只能在回调返回后计时、拒绝超额结果并取消owner;不得把后置计时说成能阻止任意无限循环。此边界随真实宿主接点记录。
原图片/atlas及图案联合额度不放宽:每实际frame最多128个需求provider、dirty像素16MiB、一个在途批次和一个合并pending重绘;地图共128张图片,单图512边长/1MiB,地图原始RGBA总16MiB,atlas2048。SDK最多32个回调scope,整图JSON仍限8MiB。外机、设备、移动GIS/iOS、完整样式/矢量/DEM、正式发行和线上部署继续待完成。
动态库宿主的冻结协议复用 sqsm_map_image_json,仍采用 {method,args} 与原有输出分配/释放规则。原子 sqs.dynamicImage.add 同时检查初始图片和提供者绑定,返回不透明 epoch、providerId、imageInstanceId;不把语言运行时的函数指针存进地图核心。如下是一像素示意,真实示例使用32×32 RGBA。
{"method":"sqs.dynamicImage.add","args":["pulse",{"width":1,"height":1,"data":[0,255,0,255]},{},"host:1"]}
宿主按实际需求调用 sqs.dynamicImage.requests,得到 null 或 {epoch,token,frame,images};每项包含 id、imageInstanceId、providerId、width、height。批次未应答前再次读取仍为同一批次。宿主在自身运行时执行同步回调,再提交 sqs.dynamicImage.reply,参数是 {token,updates,errors},更新项为 {id,imageInstanceId,image:{width,height,data}}。只有checked联合候选成功后替换像素。过期token返回 accepted:false,同名新图片不会接受旧身份更新。
repaint 合并下一帧请求;state 可读pending/inFlight。release 接收提供者ID数组,脚本停止时静默解绑并保留最后成功像素。既有 register 必须同时提供期望imageInstanceId,防止异步晚绑到同名新图片。RGBA原始字节16MiB是批上界;JSON编码仍受原通道8MiB上限约束,编码先超限就拒绝,不能把16MiB说成一定可传的有效载荷。epoch/token/imageInstanceId/providerId是字符串,frame是数值观察项,回复必须用token匹配,不能把frame当精确身份。公开C ABI示例已在匹配库实际通过,证据见下文。
flush({render:true}) 继续只确认一个真实未来帧。有限动画必须在触发前订阅并等待真正idle;不能把flush说成排空整条动画链。外部宿主在pendingRender或动画需要时推进绘制;主动调用render本身也是新帧,不能用主动不断绘制证明“自行循环”。
上下文通知描述的是图片提供者的回调生命期;不代表底层wgpu设备丢失后整张地图已经能够自动重建。实际渲染设备恢复仍遵循地图核心已有支持边界。
执行边界:Native QuickJS每VM heap32MiB、stack512KiB,整图多个VM共用2秒真实中断期限;APP每task heap32MiB、stack256KiB、回调turn最多2秒,各task并行,不能称整图总CPU限2秒。SDK整帧回复期限2秒,主线程只能返回后检查;网页脚本RPC期限2秒并由现有5秒Worker watchdog终止无响应owner。原256次普通调用/32个pendingRPC不放宽,内部回调使用单独有界通道。
失败回复丢弃整批dirty候选,保留最后受检像素,终止该批次且不自动重试;需要显式新triggerRepaint恢复。宿主repaint必须等真实presentation回执,不能用UI轮次当绘制完成。
完整HTML/CSS/JS示例 · 同一跨端脚本。原始C ABI示例随匹配SDK的native/examples/dynamic-images.py提供。
共同面/线图案继续要求每边2..512且为2次幂;公开示例使用32×32原始图片。
本批核心 ddfb4f29b73fa597bcf9c4f946b5e069dd58d669,开发SDK 0.3.0-dev.ddfb4f29。同步StyleImageInterface与triggerRepaint共同实现通过本机公开验收:同一51项/12阶段脚本在Native、主线程、Worker DPR1/2通过,共216个观察帧。实际C ABI调用检查共同提供者批次、20次请求合并、无效候选保留最后像素并停止批次、显式恢复、迟到回复和同名身份隔离。完整HTML四个真实按钮、五段显示与原始ID73点击通过(15帧)。综合CPU/串行真实GPU及必要源码检查见core-results.json;软件GPU不等于设备验收。
归档 SqsMap-SDK-0.3.0-dev.ddfb4f29-resumed.tar.gz:620清单文件加bundle.json,38104788字节,SHA256 55a1c058bdd73c3ae03db30c9691f920e71a9529019e1db6df38e95355558617。独立重开tar逐文件核对长度/SHA;Native、核心/应用/脚本WASM和Android API24 ARM64/JNI匹配当前核心,同源JavaScript也计入构建输入。生产HTTP与四仓Git为最后交付步骤;Windows/macOS外机、手机设备、移动GIS/iOS、完整样式/矢量/DEM、正式发布与线上部署仍未完成。
共同能力名为 commonDynamicStyleImages。脚本通过 await map.sqs.getCapabilities() 查询;独立SDK也可读取 map.capabilities。APP实际UI路径已接入并编译通过;本机公开Native验收使用独立动态库,不等于Windows/macOS桌面窗口或手机设备已验收。