Files
gplan-2/game/presentation/modal_flow.gd
T
DKChan 6c2dbc37c1 docs: ADR 体系废除 + architecture.md 确立为架构唯一事实源(2026-10-15 用户令:决策记录归 git commit log,不另存决策文档)
- 删除 design/dev/architecture/adr-0001~0007 共 7 份文件(内容留 git 历史可查)
- architecture.md:删「ADR 审计」「ADR 立项清单」两节;清除全文 ADR-000X 注记、QQ 表/S 表 ADR 引用;未决表关闭已落定项(QQ-01/02/03),立项清单在途事项转登记 QQ-11~14;补 A1 生成姿态事实、autoload 四件清单、board_generator 性能姿态;文档状态立「事实源地位」条
- CLAUDE.md:恢复 RNG 单点硬性红线(去 ADR-0007 引用);新增「架构事实唯一源」红线;规范导航架构行标注唯一事实源
- doc-conventions:§5 增「架构事实唯一源」行;§11 活文档清单补架构文档
- registry:architecture.yaml 删 18 处 adr 字段、autoload_set 补 SaveManager/MetaProgression、board_rending 更新为 Node2D 已落地事实;entities.yaml 12 处引用清除
- game/ 代码注释约 60 处清 ADR-000X 引用(事实与日期保留);豁免标记 ADR-0007-exempt → rng-seed-exempt(main.gd/static_scan.sh/architecture.md/06/iter27 五处同步)
- GDD/qa 实现报告/research 卡片/roadmap/tests README 引用全清;死链校验 1206 链接 0 死链、gdd_lint 0 不通过
- 代码中 adr/adr5 等为 adventure_runner 既有局部变量名(非 ADR 引用),未动
2026-10-15 23:52:30 +08:00

90 lines
4.6 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class_name ModalFlow
extends RefCounted
# 模态编排纯逻辑类(迭代 27 T4——审计 P1-5/P2-7:组合根可测化抽取 + 模态互斥域内聚)。
# 依赖仅 ModalStack + 查询 Callable(审计处方原话)——零节点构建、零信号连接、零核心触碰
#(同构:连接归组合根,本类只收注入)。可直接 new() 单测(V6)。
# 职责三件:
# ① 登记与开合编排(遮挡记账单口 / T17 演播后排窗挂起——原 main._open_modal 系逻辑随迁)
# ② 棋盘输入锁谓词(互斥域随层登记——原 main._input_locked 排除式拼装消亡)
# ③ 角标置灰谓词(状态/调试两屏同款守卫判据)
# 排除语义随层登记(ModalStack.register tags):debug_overlay=["non_locking"]、
# level_screen=["screen_state"],其余层零标签——原调用点排除式拼装面消亡(P2-7 修法)。
const ModalStackScript := preload("res://presentation/modal_stack.gd") # 非全局类(main 同款 preload 引用)
var stack = ModalStackScript.new()
# ---- 组合根注入面(查询 Callable 组——依赖仅 ModalStack + 查询 Callable 纪律载体) ----
var start_visible_get: Callable # () -> bool——开始层可见(非模态全屏态例外一)
var inter_visible_get: Callable # () -> bool——过场层可见(例外二)
var settlement_get: Callable # () -> Variant——当前战斗编排器(null=战斗缺位例外三)
var rows_empty_get: Callable # () -> bool——排播队列空(演播后排窗判据)
var flush_rows: Callable # 开层前排空排播(卡⑦——明细带恒完整)
var on_open_sync: Callable # 开侧同步钩子(状态角标+浮窗当局数据)
var on_close_sync: Callable # 关侧同步钩子
var replay_click: Callable # 演播完边沿无挂起时的锁期点击重放(main._replay_locked_click)
var _deferred: Control = null # 演播后开窗挂起(T17——排播放完再开)
func register(m: Control, tags: Array = []) -> void:
stack.register(m, tags)
func open(m: Control) -> void:
# 挂起兜底(T17 演播后排窗):其他路径(如回看)在播期排空队列会使演播完边沿不再触发——
# 此处先结挂起 modal 防永不兑现(m==挂起对象时跳过=本调用自身)。
if _deferred != null and m != _deferred:
var dm: Control = _deferred
_deferred = null
open(dm) # 原语义:先结挂起后继续开本层(不 return——两拍都走)
flush_rows.call() # 卡⑦——任何覆盖层开启前排空排播队列(明细带恒完整,回看/停点面不缺行)
stack.open(m)
on_open_sync.call()
func close(m: Control) -> void:
stack.close(m)
on_close_sync.call()
# 演播后排窗(T17 用户令「伤害过程演完才切结算窗口」):排播队列在播=挂起,演播完边沿
# (pump_ended 派发)再开——旧路径前置 flush 会把击杀轮的伤害/死亡演出同帧倒掉。
# 队列空=立即开(行为同旧路径)。
func open_after_playback(m: Control) -> void:
if rows_empty_get.call():
open(m)
return
_deferred = m
m.visible = false # 挂起含视觉(open_* 已置 visible=true——不压掉则窗在排播期照会上屏,延迟形同虚设)
# 演播完边沿派发(row_pacer.pump_ended 注入口):先开挂起 modal(胜利窗接管呈现),
# 后锁期点击重放——modal 开启后输入锁吞掉重放点击(战斗已收场,重放无意义)。
func pump_ended() -> void:
if _deferred != null:
var m: Control = _deferred
_deferred = null
open(m)
return
replay_click.call()
# 棋盘输入锁谓词(原 main._input_locked 随迁):模态互斥域(non_locking 层开态不计——迭代 18
# 卡⑦ T2 防线)+ 三例外(开始层/过场层非模态全屏态 + 战斗缺位棋盘输入无载体)。
func locks_input() -> bool:
return stack.has_open_excluding_tags([ModalStackScript.TAG_NON_LOCKING]) \
or bool(start_visible_get.call()) or bool(inter_visible_get.call()) or settlement_get.call() == null
# 角标置灰谓词·战斗屏形态(状态/调试两角标同判据):登记册上 non_locking 层外的任一层开着。
# (地图屏此态恒关——屏级互斥,与旧排除式 [debug] 逐位同值)
func badge_greyed_battle() -> bool:
return stack.has_open_excluding_tags([ModalStackScript.TAG_NON_LOCKING])
# 角标置灰谓词·地图屏形态(地图屏自身 screen_state 不计 + 调试浮窗 non_locking 不计——
# 与旧排除式 [level_screen, debug] 逐位同值)。
func badge_greyed_map() -> bool:
return stack.has_open_excluding_tags([ModalStackScript.TAG_NON_LOCKING, ModalStackScript.TAG_SCREEN_STATE])