1、废弃UIMap对象

2、添加弱网情况打开窗口失败的异常事件
This commit is contained in:
dgflash
2024-08-04 19:21:47 +08:00
parent dec5385718
commit 45ac750ebd
8 changed files with 83 additions and 168 deletions

View File

@@ -10,6 +10,10 @@ import { ViewParams } from "./Defines";
const { ccclass } = _decorator;
const EventOnAdded: string = "onAdded";
const EventOnBeforeRemove: string = "onBeforeRemove";
const EventOnRemoved: string = "onRemoved";
/** 窗口事件触发组件 */
@ccclass('DelegateComponent')
export class DelegateComponent extends Component {
@@ -22,13 +26,23 @@ export class DelegateComponent extends Component {
add(): Promise<boolean> {
return new Promise(async (resolve, reject) => {
// 触发窗口组件上添加到父节点后的事件
const r = await this.applyComponentsFunction(this.node, "onAdded", this.vp.params);
for (let i = 0; i < this.node.components.length; i++) {
const component: any = this.node.components[i];
const func = component[EventOnAdded];
if (func) {
if (await func.call(component, this.vp.params) == false) {
resolve(false);
return;
}
}
}
// 触发外部窗口显示前的事件(辅助实现自定义动画逻辑)
if (typeof this.vp.callbacks.onAdded === "function") {
this.vp.callbacks.onAdded(this.node, this.vp.params);
}
resolve(r);
resolve(true);
});
}
@@ -36,7 +50,7 @@ export class DelegateComponent extends Component {
remove(isDestroy?: boolean) {
if (this.vp.valid) {
// 触发窗口移除舞台之前事件
this.applyComponentsFunction(this.node, "onBeforeRemove", this.vp.params);
this.applyComponentsFunction(this.node, EventOnBeforeRemove, this.vp.params);
// 通知外部对象窗口组件上移除之前的事件(关闭窗口前的关闭动画处理)
if (typeof this.vp.callbacks.onBeforeRemove === "function") {
@@ -82,24 +96,17 @@ export class DelegateComponent extends Component {
onDestroy() {
// 触发窗口组件上窗口移除之后的事件
this.applyComponentsFunction(this.node, "onRemoved", this.vp.params);
this.applyComponentsFunction(this.node, EventOnRemoved, this.vp.params);
this.vp = null!;
}
protected applyComponentsFunction(node: Node, funName: string, params: any): Promise<boolean> {
return new Promise(async (resolve, reject) => {
var r = true;
for (let i = 0; i < node.components.length; i++) {
const component: any = node.components[i];
const func = component[funName];
if (func) {
r = await func.call(component, params);
if (r == false) {
break;
}
}
protected applyComponentsFunction(node: Node, funName: string, params: any) {
for (let i = 0; i < node.components.length; i++) {
const component: any = node.components[i];
const func = component[funName];
if (func) {
func.call(component, params);
}
resolve(r);
});
}
}
}

View File

@@ -6,7 +6,6 @@ import { LayerDialog } from "./LayerDialog";
import { LayerNotify } from "./LayerNotify";
import { LayerPopUp } from "./LayerPopup";
import { LayerUI } from "./LayerUI";
import { UIMap } from "./UIMap";
/** 界面层类型 */
export enum LayerType {
@@ -71,8 +70,6 @@ export class LayerManager {
game!: Node;
/** 新手引导层 */
guide!: Node;
/** 界面地图 */
uiMap!: UIMap;
/** 界面层 */
private ui!: LayerUI;
@@ -100,6 +97,14 @@ export class LayerManager {
this.configs = configs;
}
/**
* 设置窗口打开失败回调
* @param callback 回调方法
*/
setOpenFailure(callback: Function) {
this.ui.onOpenFailure = this.popup.onOpenFailure = this.dialog.onOpenFailure = this.system.onOpenFailure = callback;
}
/**
* 渐隐飘过提示
* @param content 文本表示
@@ -130,17 +135,6 @@ export class LayerManager {
this.configs[uiId] = config;
}
/**
* 设置界面地图配置
* @param data 界面地图数据
*/
setUIMap(data: any) {
if (this.uiMap == null) {
this.uiMap = new UIMap();
}
this.uiMap.init(this, data);
}
/**
* 同步打开一个窗口
* @param uiId 窗口唯一编号
@@ -221,8 +215,13 @@ export class LayerManager {
replaceAsync(removeUiId: number, openUiId: number, uiArgs: any = null): Promise<Node | null> {
return new Promise<Node | null>(async (resolve, reject) => {
var node = await this.openAsync(openUiId, uiArgs);
this.remove(removeUiId);
resolve(node);
if (node) {
this.remove(removeUiId);
resolve(node);
}
else {
resolve(null);
}
});
}
@@ -254,6 +253,7 @@ export class LayerManager {
result = this.system.has(config.prefab);
break;
}
return result;
}

View File

@@ -30,14 +30,16 @@ export class LayerPopUp extends LayerUI {
this.black.enabled = false;
}
protected async showUi(vp: ViewParams) {
await super.showUi(vp);
protected async showUi(vp: ViewParams): Promise<boolean> {
var r = await super.showUi(vp);
if (r) {
// 界面加载完成显示时,启动触摸非窗口区域关闭
this.openVacancyRemove(vp.config);
// 界面加载完成显示时,启动触摸非窗口区域关闭
this.openVacancyRemove(vp.config);
// 界面加载完成显示时,层级事件阻挡
this.black.enabled = true;
// 界面加载完成显示时,层级事件阻挡
this.black.enabled = true;
}
return r;
}
protected onCloseWindow(vp: ViewParams) {
@@ -59,6 +61,8 @@ export class LayerPopUp extends LayerUI {
/** 关闭遮罩 */
protected closeMask() {
if (this.mask == null) return;
var flag = true;
for (var value of this.ui_nodes.values()) {
if (value.config.mask) {

View File

@@ -6,6 +6,8 @@ import { UIConfig } from "./LayerManager";
/** 界面层对象 */
export class LayerUI extends Node {
/** 全局窗口打开失败 */
onOpenFailure: Function = null!;
/** 显示界面节点集合 */
protected ui_nodes = new Map<string, ViewParams>();
/** 被移除的界面缓存数据 */
@@ -62,6 +64,7 @@ export class LayerUI extends Node {
protected async load(vp: ViewParams, bundle?: string) {
// 加载界面资源超时提示
const timerId = setTimeout(this.onLoadingTimeoutGui, oops.config.game.loadingTimeoutGui);
if (vp && vp.node) {
await this.showUi(vp);
}
@@ -106,10 +109,11 @@ export class LayerUI extends Node {
* 创建界面节点
* @param vp 视图参数
*/
protected async showUi(vp: ViewParams) {
protected async showUi(vp: ViewParams): Promise<boolean> {
// 触发窗口添加事件
const comp = vp.node.getComponent(DelegateComponent)!;
if (await comp.add()) {
const r: boolean = await comp.add();
if (r) {
vp.node.parent = this;
// 标记界面为使用状态
@@ -119,11 +123,14 @@ export class LayerUI extends Node {
console.warn(`路径为【${vp.config.prefab}】的自定义预处理逻辑异常.检查预制上绑定的组件中 onAdded 方法,返回true才能正确完成窗口显示流程`);
this.failure(vp);
}
return r;
}
private failure(vp: ViewParams) {
this.ui_nodes.delete(vp.config.prefab);
/** 打开窗口失败逻辑 */
protected failure(vp: ViewParams) {
this.onCloseWindow(vp);
vp.callbacks && vp.callbacks.onLoadFailure && vp.callbacks.onLoadFailure();
this.onOpenFailure && this.onOpenFailure();
}
/**
@@ -161,7 +168,7 @@ export class LayerUI extends Node {
private removeCache(prefabPath: string) {
let vp = this.ui_cache.get(prefabPath);
if (vp) {
this.ui_nodes.delete(vp.config.prefab);
this.onCloseWindow(vp);
this.ui_cache.delete(prefabPath);
var childNode = vp.node;
childNode.destroy();

View File

@@ -1,93 +0,0 @@
/*
* @Author: dgflash
* @Date: 2022-06-14 19:35:16
* @LastEditors: dgflash
* @LastEditTime: 2022-09-02 13:27:20
*/
import { LayerManager } from "./LayerManager";
/** 界面关系树节点 */
class TreeNode {
id!: number;
/** 父节点编号 */
pid!: number;
/** 父节点 */
parent: TreeNode | null = null;
/** 子节点 */
child: Array<TreeNode> = [];
/** 界面名 */
name!: string;
/** 界面代号(用于同一界面有多条路径时) */
panel!: string;
}
/** 用于树形结构两节点之间的寻路功能 */
export class UIMap {
/** UI层级管理器 */
private manager!: LayerManager;
/** 界面节点树 */
private nodes: Map<number, TreeNode> = new Map<number, TreeNode>();
/** 创建UI关系树 */
init(manager: LayerManager, data: any) {
this.manager = manager;
// 解析数据
for (var key in data) {
var d = data[key];
var n = new TreeNode();
n.id = parseInt(key);
n.pid = d.parent;
n.name = d.name;
n.panel = d.panel;
this.nodes.set(n.id, n);
}
// 设置节点关系
this.nodes.forEach((value: TreeNode, key: number) => {
value.parent = this.nodes.get(value.pid)!;
if (value.parent)
value.parent.child.push(value);
});
}
/**
* 树节点寻路
* @param startId 起始节点编号
* @param endId 结束节点编号
* @returns
*/
pathFinding(startId: number, endId: number): any {
var start: TreeNode = this.nodes.get(startId)!;
var end: TreeNode = this.nodes.get(endId)!;
var close: Array<TreeNode> = this.findUp(start);
var open: Array<TreeNode> = this.findUp(end);
close.forEach(value => {
this.manager.remove(value.id, true);
});
open.forEach(value => {
this.manager.open(value.id);
});
return { paths_close: close, paths_open: open };
}
/** 向上寻找子节点直到根节点停止,并返回节点路径数组 */
private findUp(start: TreeNode): TreeNode[] {
var paths: TreeNode[] = [];
var current: TreeNode = start;
while (current.parent != null) { // 父级为空时为根节点
paths.push(current);
current = current.parent!;
}
return paths;
}
/** 释放所有节点 */
release() {
this.nodes.clear();
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "1bd03820-b48b-4821-a8e8-a9dd08e1518b",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -103,15 +103,14 @@ export class ViewUtil {
*/
static createPrefabNodeAsync(path: string): Promise<Node> {
return new Promise(async (resolve, reject) => {
resLoader.load(path, Prefab, (err: Error | null, content: Prefab) => {
if (err) {
console.error(`名为【${path}】的资源加载失败`);
return;
}
var prefab = await resLoader.loadAsync(path, Prefab)
if (prefab) {
var node = this.createPrefabNode(path);
resolve(node);
});
}
else {
resolve(null!);
}
});
}

View File

@@ -58,19 +58,7 @@ export class ModuleUtil {
}
/**
* 业务实体上移除界面组件
* @param ent 模块实体
* @param ctor 界面逻辑组件
* @param uiId 界面资源编号
* @param isDestroy 是否释放界面缓存(默认为释放界面缓存)
*/
public static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: number, isDestroy: boolean = true) {
ent.remove(ctor, isDestroy);
oops.gui.remove(uiId, isDestroy);
}
/**
* 添加界面组件
* 通过资源内存中获取预制上的组件添加到ECS实体中
* @param ent 模块实体
* @param ctor 界面逻辑组件
* @param parent 显示对象父级
@@ -86,4 +74,16 @@ export class ModuleUtil {
ent.add(comp);
node.parent = parent;
}
/**
* 业务实体上移除界面组件
* @param ent 模块实体
* @param ctor 界面逻辑组件
* @param uiId 界面资源编号
* @param isDestroy 是否释放界面缓存(默认为释放界面缓存)
*/
public static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: number, isDestroy: boolean = true) {
ent.remove(ctor, isDestroy);
oops.gui.remove(uiId, isDestroy);
}
}