## VERTICAL SLICE - NOT FOR PRODUCTION ## 模态层级状态机:登记序 = 树序 = z 遮挡序,打开显式隐藏其上方可见层、关闭恢复。 ## 层必须先 register 方可 open/close;遮挡由本类显式记账,不得靠树序巧合。 ## 纯逻辑类——Control 层由组合根喂入 register。 extends RefCounted var _list: Array[Control] = [] # 登记序 = z 遮挡序(低 → 高) var _occluded := {} # modal → 被其隐藏的上方层(关闭恢复) var _tags := {} # modal → 排除组标签集(互斥域随层登记) # 排除组封闭词表(组合根登记用——新标签=改此处+评审,防调用点拼装回潮) const TAG_NON_LOCKING := "non_locking" # 开态不计入棋盘输入锁与角标置灰(调试浮窗默认开×遮挡复活×has_open 组合=棋盘永久锁死) const TAG_SCREEN_STATE := "screen_state" # 常驻屏态(关卡地图屏——自身开态不计入本屏角标判据) func register(m: Control, tags: Array = []) -> void: _list.append(m) _tags[m] = tags func open(m: Control) -> void: var idx := _list.find(m) if idx < 0: push_error("ModalStack.open: 未登记层不可打开(register 先行)") return var hidden: Array[Control] = [] for i in range(idx + 1, _list.size()): var higher: Control = _list[i] if is_instance_valid(higher) and higher.visible: higher.visible = false hidden.append(higher) # 遮挡账合并非覆盖:同层重复 open 时上方已隐、hidden 为空,旧账须保留 # (空表覆盖会让先前被隐层在本层 close 后永不恢复) var merged: Array[Control] = [] for h in _occluded.get(m, []): if not merged.has(h): merged.append(h) for h in hidden: if not merged.has(h): merged.append(h) _occluded[m] = merged m.visible = true func close(m: Control) -> void: if _list.find(m) < 0: push_error("ModalStack.close: 未登记层不可关闭(register 先行)") return m.visible = false for h in _occluded.get(m, []): if is_instance_valid(h): h.visible = true _occluded.erase(m) # 开态查询(组合根输入锁唯一判据:登记册上是否有任一层处于开态; # 可见性即开态,与 open/close 记账同源——组合根不再手工罗列各层) func has_open() -> bool: for m in _list: if is_instance_valid(m) and m.visible: return true return false # 排除组开态查询(模态协议内聚:排除语义随层登记(register tags), # 查询按组名集合表达,禁在调用点拼装 has_open_excluding/has_open_excluding_any。 # 只读查询零副作用——登记序/开合记账语义不变;空标签集=全计(与 has_open 同形)。 func has_open_excluding_tags(exclude_tags: Array) -> bool: for m in _list: if is_instance_valid(m) and m.visible: var mt: Array[Variant] = _tags.get(m, []) var excluded := false for t in exclude_tags: if mt.has(t): excluded = true break if not excluded: return true return false