- 四view新件(自CampOverlay承载面迁移,界面逻辑复用零重设计契约4): forge_view(钥匙门+两区六路线行板)/treasure_view(12件行板+同调装配段+Y升级行+钥匙门)/tree_view(脉分组行板+Fork双态)/codex_view(占位挂起壳,锁文随形态订正『柜台』称谓L2)——各带返回钮发closed(关层归presenter);公共壳CampSubViewBase(实底dim+铭牌+钥石徽+返回钮) - CampRefreshBus新件: 各写口尾→现开界面刷新+场景根HUD一闸(卡⑤HUD同口挂接;非autoload非信号广播——组合根单点推送);presenter八写口尾refresh_camp→bus.refresh(F9:七口+on_camp_buy双尾) - 承载形态(§9-2拍板): 单一内页切换=场景根留底——模态栈open只隐上方登记层(modal_stack.gd:27实测),四子界面登记于场景根之上且实底遮挡,双开互斥靠遮挡天然成立;V2断言按留底派生(T5落) - ui_registry: LAYER_CONTRACT camp_overlay槽→camp_scene(shell camp_screen)+forge/treasure/tree/codex_view四槽;node()改经modals.camp.X二层(卡⑥契约2);ui_camp_modals五枚成员(overlay枚随退役删除——卡⑥契约4) - camp_screen: 持camp_scene取代CampOverlay成员;main_ui_build: 场景装配(布局表ConfigDB注入)+四view实例化+信号接线(意图→presenter/closed bind携视图/object_pressed→组合根路由) - presenter承接面: 五目标改线(ctx.views束——成员预算12≤15)+open_camp_forge/treasure/tree/codex四开层口+on_camp_sub_closed+on_camp_closed关层收闭(营地层与选档层同收+开始层恢复);main_overlay_flow._on_camp_object_pressed五物件路由(gate/campfire归T4)+生涯营地语境关层分支(笔记本改挂——CareerOverlay本体零改);main.gd薄委托零新增成员 - 退役: camp_overlay_view.gd删除(吸收即死);旧形态断言同批摘除(test-conventions §5.5):theme_projection等高源码断言+最近冒险行投影段(卡面削弱申报授权:注销,条带Q4=甲撤下) - 同批迁移: forge_workbench_test承载类camp_overlay_view→forge_view+_forge._X扁平化(断言零改12项绿);system_test三处机械随迁(V2实例化/:108同一性链/:121候选清单——camp_scene句柄更名) - 验证: 冒烟boot PASS(15项0失败——装配全链通)+全流程孤检绿(12项:五句柄/铺层/点选路由四子界面/返回/生涯改挂/营地语境分支/关层收闭——临时件不入库);S9/S10/S13归基线(codex头注日期清偿/_build_shell超局部变量按顶栏底栏拆)
110 lines
5.4 KiB
GDScript
110 lines
5.4 KiB
GDScript
## 界面注册面:呈现层界面元素清单的唯一事实源——哪些层、什么序、地址在哪。
|
||
## 持有三域容器(screens/battle/modals)、LAYER_CONTRACT 合同表、node(key) 合同寻址、
|
||
## apply_layer_contract(root) 唯一落位口(全仓唯一 move_child 点)。
|
||
## RefCounted 不挂树:零信号连接、零会话期引用、零核心写调用——组合根单点装配不变。
|
||
class_name UiRegistry
|
||
extends RefCounted
|
||
|
||
const ModalStack := preload("res://presentation/modal_stack.gd")
|
||
|
||
# ==================== 视觉层合同(唯一事实源——树序=登记序=z 序;改序只改此表) ====================
|
||
# kind: shell=屏壳容器(成员随壳不占独立树位;level_screen 例外另占登记位)/modal=模态层(入登记册,
|
||
# tags 随登记)/state=全屏态(占树位不入登记册)/node=非视觉节点(占树位不入登记册)。
|
||
# host=宿住屏壳(树序随宿主、登记序按本合同);shell=模态成员的屏壳(成员与屏壳同槽:屏壳占该树位、
|
||
# 成员占该登记位)。落位=apply_layer_contract(全仓唯一层序落位点,add_child 之后统一排序+登记)。
|
||
const LAYER_CONTRACT: Array[Dictionary] = [
|
||
{"key": "adventure_screen", "kind": "shell"},
|
||
{"key": "menu_screen", "kind": "shell"},
|
||
{"key": "row_pacer", "kind": "node"},
|
||
{"key": "legend_overlay", "kind": "modal", "tags": []},
|
||
{"key": "node_overlay", "kind": "modal", "tags": []},
|
||
{"key": "level_screen", "kind": "modal", "tags": [ModalStack.TAG_SCREEN_STATE], "host": "adventure_screen"},
|
||
{"key": "curio_overlay", "kind": "modal", "tags": []},
|
||
{"key": "end_overlay", "kind": "modal", "tags": []},
|
||
{"key": "shop_overlay", "kind": "modal", "tags": []},
|
||
{"key": "camp_scene", "kind": "modal", "tags": [], "shell": "camp_screen"}, # 营地场景根(交互式场景图——卡④)
|
||
{"key": "forge_view", "kind": "modal", "tags": []}, # 营地四子界面(独立全屏页——场景根留底形态,卡④ T3)
|
||
{"key": "treasure_view", "kind": "modal", "tags": []},
|
||
{"key": "tree_view", "kind": "modal", "tags": []},
|
||
{"key": "codex_view", "kind": "modal", "tags": []},
|
||
{"key": "settings_overlay", "kind": "modal", "tags": []},
|
||
{"key": "status_panel", "kind": "modal", "tags": []},
|
||
{"key": "career_overlay", "kind": "modal", "tags": []},
|
||
{"key": "save_select_overlay", "kind": "modal", "tags": []}, # 选档界面(营地交互重做卡③——登记生涯同档)
|
||
{"key": "inter_overlay", "kind": "state", "tags": []},
|
||
{"key": "confirm_dialog", "kind": "modal", "tags": []},
|
||
{"key": "debug_overlay", "kind": "modal", "tags": [ModalStack.TAG_NON_LOCKING]},
|
||
{"key": "debug_badge", "kind": "float"}, # 调试入口全局浮层——末位=最顶绘制序;
|
||
# float 类不注册 ModalStack(open() 遮挡记账只隐藏登记层)→ 任何 UI 打开都不遮它
|
||
]
|
||
|
||
var screens: UiScreens
|
||
var battle: UiBattle
|
||
var modals: UiModals
|
||
|
||
|
||
func _init() -> void:
|
||
screens = UiScreens.new()
|
||
battle = UiBattle.new()
|
||
modals = UiModals.new()
|
||
|
||
|
||
# 合同层寻址(key→节点;纯查表不含层序语义——层序唯一事实源=LAYER_CONTRACT)
|
||
func node(key: String) -> Node:
|
||
match key:
|
||
"adventure_screen": return screens.adventure_screen
|
||
"menu_screen": return screens.menu_screen
|
||
"row_pacer": return screens.row_pacer
|
||
"legend_overlay": return modals.legend_overlay
|
||
"node_overlay": return modals.node_overlay
|
||
"level_screen": return modals.level_screen
|
||
"curio_overlay": return modals.curio_overlay
|
||
"end_overlay": return modals.end_overlay
|
||
"shop_overlay": return modals.shop_overlay
|
||
"camp_screen": return screens.camp_screen
|
||
"camp_scene": return modals.camp.scene
|
||
"forge_view": return modals.camp.forge
|
||
"treasure_view": return modals.camp.treasure
|
||
"tree_view": return modals.camp.tree
|
||
"codex_view": return modals.camp.codex
|
||
"settings_overlay": return modals.settings_overlay
|
||
"status_panel": return modals.status_panel
|
||
"career_overlay": return modals.career_overlay
|
||
"save_select_overlay": return modals.save_select_overlay
|
||
"inter_overlay": return screens.inter_overlay
|
||
"confirm_dialog": return modals.confirm_dialog
|
||
"debug_overlay": return modals.debug_overlay
|
||
"debug_badge": return screens.debug_badge
|
||
return null
|
||
|
||
|
||
# 合同装配(_build_ui 尾调用):按 LAYER_CONTRACT 序统一落位——直接子层 move_child 到合同槽、
|
||
# 模态层按合同序登记;宿住层(host)树序随宿主只登记;成员层(shell)与屏壳同槽(屏壳占树位、成员占登记位)。
|
||
# 本函数是全仓唯一层序落位点(move_child 单口)——改层序只改 LAYER_CONTRACT。
|
||
func apply_layer_contract(root: Control) -> void:
|
||
var slot := 0
|
||
for entry: Dictionary in LAYER_CONTRACT:
|
||
var tags: Array[Variant] = entry.get("tags", [])
|
||
if entry.has("shell"):
|
||
var shell: Node = node(String(entry["shell"]))
|
||
var member: Node = node(String(entry["key"]))
|
||
if shell != null:
|
||
root.move_child(shell, slot)
|
||
slot += 1
|
||
if member != null:
|
||
modals.register_layer(member as Control, tags)
|
||
else:
|
||
push_error("[合同装配] 层缺失: %s" % String(entry["key"]))
|
||
continue
|
||
var layer: Node = node(String(entry["key"]))
|
||
if layer == null:
|
||
push_error("[合同装配] 层缺失: %s" % String(entry["key"]))
|
||
continue
|
||
if entry.has("host"):
|
||
modals.register_layer(layer as Control, tags)
|
||
continue
|
||
root.move_child(layer, slot)
|
||
slot += 1
|
||
if String(entry["kind"]) == "modal":
|
||
modals.register_layer(layer as Control, tags)
|