跳到正文

界面基础目录与按需数据准备 ​

本文面向维护者,说明界面如何判断英雄/地图目录是否可信、何时自动准备结构化数据,以及页面、 任务门禁和进度如何保持一致。

1. 三类不同状态 ​

共享目录流程必须与另外两类状态分开:

  • 任务快照:执行中心创建任务时冻结的参数。后续修改设置不会改写已入队任务。
  • 运行时配置:用于构造后续 AppContext 的游戏目录、输出目录和区域等共享设置。
  • 共享实体数据:英雄、地图与可选特殊内容的结构化目录,供主页、执行中心和实体总览共同 使用。

个性化设置(主题、平滑滚动、日志抽屉等)不属于共享目录上下文,不触发目录重建。 “提前准备数据”影响扫描要求,属于共享目录配置签名;保存在 [gui] prepare_data_on_startup, 默认关闭,切换后重新检查当前目录。

2. 单一事实来源 ​

SharedDataController 持有当前 SharedDataState,页面不得再根据中文消息、日志内容或 worker 是否正常结束推断就绪状态。

一次完整扫描由 SharedDataScanWorker 在后台运行,内部调用 EntityDataLoader.scan_catalog(),返回一个 SharedDataScanResult。该结果同时包含:

  • 当前 generation 和版本;
  • 英雄、地图、特殊内容三个 section;
  • 每个 section 的权威 expected IDs、成功 rows、失败项与未准备项;
  • 按稳定问题码聚合的 problems;
  • 由必需目录事实派生的 complete、partial 或 failed readiness。

逐实体异常可以被扫描器收集后继续扫描,但不能只写日志并丢弃。英雄或地图 expected 集合为空、 Map 0 缺失、任一必需 ID 未形成有效行,都不能进入 ready。

默认扫描只要求基础清单可读,尚无资源绑定的普通实体保留“未准备”行,可以选择并创建任务。 已有有效绑定时继续展示真实音频、映射状态;未准备对象的音频预览为空,不触发 BIN 解析。 仅在开启提前准备时,缺失/旧版/不完整的资源绑定和缺失/过期事件缓存才成为共享扫描阻断项。

结构化特殊内容和显式 resource pack 是可选目录。它们未准备不会降低普通英雄/地图的 readiness;默认共享扫描也不会遍历全部历史 FINAL WAD。

3. 状态机 ​

Phase含义阻止新任务
blocked必要配置缺失或无效是
checking正在建立上下文或完整扫描是
waiting配置已变更,等待现有任务队列结束是
preparing正在准备基础目录,或按开启的偏好准备完整资源是
verifyingupdate 完成,正在重建 reader 并完整复检是
ready必需英雄与地图通过当前 generation 对应扫描模式的复检否
partial有可信 rows,但必需目录不完整是
failed无法形成可信必需目录或准备失败是
cancelled准备被权威结果标记为取消是

active、blocks_new_tasks 和语义角色都由 phase 派生。只有 ready 可以创建新任务或把总览选择 发送到执行中心;partial 可以浏览已经验证成功的 rows,但页面持续显示目录不完整状态。

每次 reader 相关配置变化都会增加 generation。旧 worker 的 scan、prepare、failure 和 progress 回调在应用前检查 generation,不允许覆盖新上下文。

4. 检查、准备与复检 ​

首次启动、手动刷新、配置变化和显式重试共用同一条主链:

  1. 校验必要配置并异步建立 AppContext。
  2. 完整扫描当前目录。
  3. complete 时原子发布三类 rows,再发布 ready。
  4. 若全部阻断问题都可自动修复,按失败证据生成 repair scope。
  5. 每个 generation 最多自动准备一次;默认仅调用 prepare_update_data(),开启提前准备时调用 普通 update(),均默认 force_update=False。
  6. 消费 update 返回的真实 StageResult。
  7. success 或 partial 时重建读取上下文并完整复检;failed/cancelled 直接进入对应终态。
  8. 复检 complete 且准备结果不是 partial 时才能进入 ready。

自动可修复问题包括数据缺失/过期/为空、banks 缺失、local resource schema 不兼容、binding 不完整、 Map 0 缺失和可分类的 artifact 损坏。配置、权限或来源不可用不会触发自动循环。

默认共享 readiness 不要求 banks/events;开启提前准备后同时检查两者,以覆盖用户先仅解包、之后 再开启提前准备的情况。最终 mapping 产物不属于就绪条件。当前版本的有效缓存不重建,已成功 解析但没有事件的地图也保存空事件缓存,避免把“没有事件”误判为“未准备”。

用户任务准备规则
解包或映射worker 内对所选范围执行普通 update,转发真实进度
仅映射设置 process_events=True
解包与映射组合共用准备过程与运行时上下文
显式前置强制更新使用强制更新流程
公共 BIN 与合同保留 Map 0、特殊英雄、v2 binding;缓存齐全的地图不重复预处理公共 BIN
单纯 WAV 转码或导出不触发 BIN 准备

自动准备成功不作为用户音频产物阶段参与最终状态聚合,避免依赖检查成功把后续全失败伪装成 部分成功;非成功准备结果保留在任务报告中。failed/cancelled 阻止后续消费,partial 保留逐对象 问题并继续尝试可处理对象。

普通更新后同类可修复问题仍存在时,主页提供“重新生成实体数据”。这是用户显式选择的二级恢复, 才会使用 force_update=True;初次自动迁移不会删除旧文件或默认 force。结构化 artifact 仍通过 同目录临时文件和原子替换发布,失败时保留原文件。

5. StageResult 与扫描各自证明什么 ​

update 的 StageResult 证明准备过程的执行事实,完整扫描证明界面目录的可读事实,两者缺一不可:

  • success:进入 verifying,不直接显示成功;
  • partial:仍进行复检以发布实际 rows,但最终至少为 partial;
  • failed:直接 failed,不调用成功重载路径;
  • cancelled:直接 cancelled,不显示 100% 或成功通知。

worker finished 只表示后台函数返回。进度达到 total 只表示当前阶段已处理完,都不能替代上述 typed 结果。

6. 进度与全局所有权 ​

核心 update 通过可选 OperationProgress 回调发布 data、champion_banks 和 map_banks 阶段; 完整扫描通过 SharedDataProgress 发布 champions、special 和 maps 阶段。

  • total 未知的上下文建立或短阶段使用不确定动画,不显示虚构百分比或 ETA。
  • total 已知时,主页与全局宿主消费同一份归一化 current/total 快照;填充宽度直接跟随真实比值。
  • 普通进度在控制器边界以 50 ms 窗口保留最新值,阶段 started/finished 和终态立即发布。
  • 进度回调不等待 UI 绘制,实体总览也不会因每个计数更新而重建目录模型。
进度宿主规则
用户任务与共享准备重叠用户任务优先;保存共享状态,任务结束后仅恢复最新 generation 的共享进度
共享准备不进入用户任务队列,不显示用户任务取消按钮
主页共享状态已有页内进度,隐藏同源全局条;仍活跃时保留底部布局占位,避免切页改变内容高度
其他页面立即恢复共享全局条
用户任务全局条不受主页对共享进度的抑制影响

7. 页面与恢复动作 ​

  • 主页:显示 phase、动态英雄/地图摘要、单一确定或不确定进度条,以及稳定恢复按钮;计数只在 实体状态卡中出现一次。
  • 执行中心:只有 ready 启用创建任务;活跃阶段显示“准备数据中”,waiting 显示“等待当前任务 结束”,其余终态保留原因 Tooltip。
  • 实体总览:活跃阶段显示加载占位;partial 保留 verified rows,但禁用“发送到执行中心”。
  • 全局进度:除主页外,用户切换标签页后继续展示共享准备状态。

恢复动作使用稳定 action key,由窗口层绑定真实行为:

  • 配置缺失/无效、输出不可写:打开全局设置;
  • 可修复问题:重试更新;普通迁移后仍失败时可重新生成;
  • 来源不可用或未分类错误:先提供重试,日志只作为补充诊断。

通知只提示有意义的状态转折。普通启动直接 ready 不弹成功通知;自动准备开始、准备并复检成功、 initial partial/failed 各按 generation 去重。持久页面状态始终是主要反馈。

8. 队列与刷新边界 ​

运行时配置在队列仍有等待或运行任务时进入 waiting。已有任务继续使用创建时的上下文快照,设置页 锁定后端相关分组;队列清空后,控制器自动继续新 generation 的 checking。

任务完成后的产物增量刷新与共享 readiness 分离:它只按 EntityResult.artifacts 更新已有目录行, 不会把 partial/failed 变成 ready,也不会触发共享自动准备。强制终止拿不到可靠产物快照时不做猜测性 刷新。

9. 验证边界 ​

自动化测试覆盖 phase 映射、完整/部分/失败扫描、Map 0、可选 special、一次自动准备、StageResult 四态、generation 拒旧、队列 waiting、进度模式/节流、恢复动作、ready-only 门禁,以及旧 schema 经 普通 update adapter 后复检为 ready。

布局、颜色、缩放、键盘可达性和主观流畅度不使用像素或源码字面量测试。它们保留在原生 Windows 界面人工验收,通过标准入口 uv run unpack-gui 检查。

共享进度 mock ​

需要反复检查首页页内进度与其他页面底部全局进度时,先正常启动界面,打开全局日志抽屉后按住 Ctrl 点击日志标题,进入开发控制台。输入下列命令即可启动只作用于展示层的循环 mock:

text
shared progress

默认每 50 ms 前进一步,依次模拟 checking、英雄更新、地图更新、英雄复检、地图复检和 ready; 一轮结束后自动重新开始。需要放慢观察时可指定 10–2000 ms 的步进间隔:

text
shared progress 80

再次执行 shared progress <interval_ms> 会按新速度重新开始;shared inspect 查看运行状态, shared stop 停止并恢复最新真实状态。

mock 不会读取、扫描、更新或写入真实实体数据。它只覆盖首页共享状态和底部全局进度条,不改变执行 中心的真实数据与任务门禁;真实共享状态再次发布时,mock 会自动停止,避免遮蔽后台事实。