跳到主要内容

宿主循环与资源管理

安排线程、事件、异步下载与地图输出的生命周期。

一个地图,一个创建线程

在准备长期驱动地图的线程上创建地图,并在该线程调用地图操作。窗口线程可以直接作为创建线程,也可以把地图安排在专用线程;选择后将输入、调整尺寸、资源回传和销毁请求统一送到它。

下载任务可以在其他线程执行,但完成后应把响应交回地图创建线程,再调用地图接口。输出分配可在正确同步的前提下跨线程读取和释放,这不代表地图句柄也可以随意跨线程使用。

循环中需要做什么

  1. 处理宿主输入和已完成的下载,将地图操作串行交给创建线程。
  2. 轮询事件,将需要的内容复制或解析后释放输出。初次创建、后续修改和资源加载的状态应分别处理。
  3. 获取待处理的资源请求,交给宿主的下载与缓存模块。保留请求身份与代际,处理超时、取消和大小限制。
  4. 在创建线程回传下载成功或失败的结果,并检查响应是否仍被接受。地图已切换样式或被销毁时,迟到结果不能当成当前请求。
  5. 按宿主的刷新安排读回画面,把像素送到显示层,然后释放本次输出。

地图接口的参数校验成功、命令已应用和网络资源全部加载完成不是同一个状态。不要只因一次操作返回成功就显示“所有数据加载完毕”。细节见生命周期和原生资源加载。

内存规则

对象宿主责任
sqsm_map_bytes_t.data只在对应分配仍存活时读取;JSON 按 len 个 UTF-8 字节解析,不保证末尾有零字节
sqsm_map_bytes_t.allocation使用 sqsm_map_bytes_free 恰好释放一次;不能对 data 调用 C 的 free
下一次输出参数使用清零结构,或已经释放的输出结构;不要覆盖仍未释放的输出
sqsm_map_last_error()在下一次地图 API 调用前复制或记录;指针归库所有,不释放
地图句柄销毁后不再调用;销毁地图不会替宿主释放已返回的独立输出

对异步显示层,复制像素通常比共享库分配更容易管理。确需跨线程传递输出时,明确谁负责释放,并保证显示线程结束读取前不会释放。

事件与错误处理

通过 sqsm_map_poll_events_json 获取事件数组并释放结果。即使返回空数组也要按输出规则释放。事件队列有界,不持续轮询可能使后续修改返回资源限制;盲目重复修改无法排空队列。

返回状态首先检查
SQSM_MAP_CONFLICT是否在地图创建线程调用,以及是否违反当前操作状态约束
SQSM_MAP_STALE_HANDLE地图或分配是否已经销毁、释放
SQSM_MAP_RESOURCE_LIMIT未消费事件、未释放输出及请求预算
SQSM_MAP_CAPABILITY_UNAVAILABLE当前构建的能力标记、可选模块与所用版本是否匹配
SQSM_MAP_ENGINE_ERROR立即记录当前线程错误,结合初始化或渲染环境排查

关闭时先停止提交新的宿主任务,再在创建线程销毁地图,并释放仍由宿主持有的输出。若启用了持续脚本会话,还需遵循原生脚本模块的停止、保留终态与释放约定;不能仅靠丢弃宿主引用结束会话。