生命周期与异步加载¶
GFUIUtility 在关闭、替换和异步加载时维护面板栈一致性。项目层可以复用这些状态信号,但不应把业务页面历史写入 UI 栈本身。
关闭与释放¶
pop_panel()、clear_layer() 和替换层入口会先把旧面板从 UI 根节点移除,再按需释放实例,因此关闭后的面板会立即脱离 GFUILayer_*。默认 pop_panel() 会释放面板;pop_panel(layer, false) 只移除但不释放,适合项目层自行复用实例。如果面板被外部 queue_free(),工具会在 tree_exited 后从栈中移除并恢复下层面板。
异步请求保护¶
push_panel_async() 和 replace_layer_async() 会优先使用 GFAssetUtility,未注册时回退同步加载。每个 UI 层都有请求序号保护:pop_panel()、clear_layer()、替换层或释放工具后,迟到的异步加载回调会被忽略,不会把旧面板重新压回已经取消或清空的栈。同一层级同一路径的重复异步压栈请求会在资源返回前合并,避免按钮连点时叠出多层相同面板。
加载状态信号¶
异步加载的视觉 Loading 属于项目 UI。框架不创建默认遮罩、进度条或转场动画,但会通过信号报告请求状态:
panel_async_load_started:报告push/replace请求开始。panel_async_load_finished:报告请求结束,状态为AsyncPanelLoadStatus.OPENED、FAILED或CANCELLED。has_pending_async_panel():查询指定层级是否仍有等待资源回调的请求。get_pending_async_panel_requests():返回当前 pending 请求快照。
常见做法是只在同层没有 pending 请求时关闭项目自己的 loading 面板:
ui_util.panel_async_load_started.connect(func(_path: String, layer: int, _operation: StringName) -> void:
if layer == GFUIUtility.Layer.POPUP:
show_popup_loading()
)
ui_util.panel_async_load_finished.connect(func(
_path: String,
layer: int,
_operation: StringName,
_status: int,
_panel: Node
) -> void:
if layer == GFUIUtility.Layer.POPUP and not ui_util.has_pending_async_panel(layer):
hide_popup_loading()
)
panel_opened、panel_closed 和 navigation_changed 适合把 UI 栈变化同步给焦点系统、音效、诊断面板或项目自己的路由层。get_panel_stack()、get_stack_count()、is_panel_open() 和 get_debug_snapshot() 只返回当前栈状态,不保存业务历史;route id 到面板场景的通用映射见 UI 路由与导航历史。