mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-06-07 18:52:23 +08:00
重构GUI模块打开界面与关闭界面的参数,方便后续扩展新功能,而保持接口不变
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2023-07-24 17:14:57
|
||||
*/
|
||||
|
||||
import { Node } from "cc";
|
||||
import { LayerPopUp } from "./LayerPopup";
|
||||
import { UICallbacks, UIParams } from "./LayerUIElement";
|
||||
import { UIParam, UIState } from "./LayerUIElement";
|
||||
import { UIConfig } from "./UIConfig";
|
||||
|
||||
/** 模式弹窗数据 */
|
||||
@@ -16,9 +16,7 @@ type DialogParam = {
|
||||
/** 窗口配置 */
|
||||
config: UIConfig;
|
||||
/** 窗口附加参数 */
|
||||
params?: any;
|
||||
/** 窗口回调 */
|
||||
callbacks?: UICallbacks;
|
||||
params?: UIParam;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -27,54 +25,55 @@ type DialogParam = {
|
||||
export class LayerDialog extends LayerPopUp {
|
||||
/** 窗口调用参数队列 */
|
||||
private params: Array<DialogParam> = [];
|
||||
/** 当前打开的界面 */
|
||||
private current: Node = null!;
|
||||
|
||||
add(uiid: string, config: UIConfig, params?: any, callbacks?: UICallbacks) {
|
||||
// 控制同一时间只能显示一个模式窗口
|
||||
if (this.ui_nodes.size > 0) {
|
||||
this.params.push({
|
||||
uiid: uiid,
|
||||
config: config,
|
||||
params: params,
|
||||
callbacks: callbacks,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.show(uiid, config, params, callbacks);
|
||||
/**
|
||||
* 添加模式窗口
|
||||
* 1. 同时添加多个模式窗口时,第一个之后的窗口会先队列起来,在第一个关闭后在加载与显示第二个;同时方法返回节点保持只返回当前显示的界面节点
|
||||
*/
|
||||
add(uiid: string, config: UIConfig, params?: UIParam): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
// 控制同一时间只能显示一个模式窗口
|
||||
if (this.ui_nodes.size > 0) {
|
||||
this.params.push({
|
||||
uiid: uiid,
|
||||
config: config,
|
||||
params: params
|
||||
});
|
||||
resolve(this.current);
|
||||
}
|
||||
else {
|
||||
this.current = await this.showDialog(uiid, config, params);
|
||||
resolve(this.current);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 显示模式弹窗 */
|
||||
private show(uiid: string, config: UIConfig, params?: any, callbacks?: UICallbacks) {
|
||||
let uip = this.ui_cache.get(config.prefab);
|
||||
if (uip == null) {
|
||||
uip = new UIParams();
|
||||
uip.uiid = uiid;
|
||||
uip.valid = true;
|
||||
uip.config = config;
|
||||
}
|
||||
|
||||
uip.params = params || {};
|
||||
uip.callbacks = callbacks ?? {};
|
||||
this.ui_nodes.set(uip.config.prefab, uip);
|
||||
|
||||
this.load(uip, config.bundle);
|
||||
private showDialog(uiid: string, config: UIConfig, param?: UIParam): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
let state = this.initUIConfig(uiid, config, param);
|
||||
let node = await this.load(state, config.bundle);
|
||||
resolve(node);
|
||||
});
|
||||
}
|
||||
|
||||
protected onCloseWindow(uip: UIParams) {
|
||||
super.onCloseWindow(uip);
|
||||
protected uiClose(state: UIState) {
|
||||
super.uiClose(state);
|
||||
setTimeout(this.next.bind(this), 0);
|
||||
}
|
||||
|
||||
protected closeUI() {
|
||||
protected closeBlack() {
|
||||
if (this.params.length == 0) {
|
||||
super.closeUI();
|
||||
super.closeBlack();
|
||||
}
|
||||
}
|
||||
|
||||
private next() {
|
||||
if (this.params.length > 0) {
|
||||
let param = this.params.shift()!;
|
||||
this.show(param.uiid, param.config, param.params, param.callbacks);
|
||||
this.showDialog(param.uiid, param.config, param.params);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import { LayerHelper } from "./LayerHelper";
|
||||
import { LayerNotify } from "./LayerNotify";
|
||||
import { LayerPopUp } from "./LayerPopup";
|
||||
import { LayerUI } from "./LayerUI";
|
||||
import { LayerUIElement, UICallbacks } from "./LayerUIElement";
|
||||
import { LayerUIElement, UIParam } from "./LayerUIElement";
|
||||
import { UIConfig } from "./UIConfig";
|
||||
|
||||
/** 界面层级管理器 */
|
||||
@@ -171,13 +171,13 @@ export class LayerManager {
|
||||
this.notify.waitClose();
|
||||
}
|
||||
|
||||
/** 获取界面信息 */
|
||||
private getInfo(uiid: Uiid): { key: string; config: UIConfig } {
|
||||
let key = "";
|
||||
let config: UIConfig = null!;
|
||||
|
||||
// 界面配置
|
||||
if (typeof uiid === 'object') {
|
||||
if (uiid.bundle == null) uiid.bundle = resLoader.defaultBundleName;
|
||||
key = uiid.bundle + "_" + uiid.prefab;
|
||||
config = gui.internal.getConfig(key);
|
||||
if (config == null) {
|
||||
@@ -205,8 +205,7 @@ export class LayerManager {
|
||||
/**
|
||||
* 同步打开一个窗口
|
||||
* @param uiid 窗口唯一编号
|
||||
* @param uiArgs 窗口参数
|
||||
* @param callbacks 回调对象
|
||||
* @param param 窗口参数
|
||||
* @example
|
||||
var uic: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
@@ -218,50 +217,43 @@ export class LayerManager {
|
||||
};
|
||||
oops.gui.open(UIID.Loading, null, uic);
|
||||
*/
|
||||
open(uiid: Uiid, uiArgs: any = null, callbacks?: UICallbacks): void {
|
||||
open(uiid: Uiid, param?: UIParam): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
let info = this.getInfo(uiid);
|
||||
let layer = this.uiLayers.get(info.config.layer);
|
||||
if (layer) {
|
||||
let node = await layer.add(info.key, info.config, param);
|
||||
resolve(node);
|
||||
}
|
||||
else {
|
||||
console.error(`打开编号为【${uiid}】的界面失败,界面层不存在`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 显示指定界面 */
|
||||
show(uiid: Uiid) {
|
||||
let info = this.getInfo(uiid);
|
||||
let layer = this.uiLayers.get(info.config.layer);
|
||||
if (layer) {
|
||||
layer.add(info.key, info.config, uiArgs, callbacks);
|
||||
layer.show(info.config.prefab);
|
||||
}
|
||||
else {
|
||||
console.error(`打开编号为【${uiid}】的界面失败,界面层不存在`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步打开一个窗口
|
||||
* @param uiid 窗口唯一编号
|
||||
* @param uiArgs 窗口参数
|
||||
* @example
|
||||
* var node = await oops.gui.openAsync(UIID.Loading);
|
||||
*/
|
||||
async openAsync(uiid: Uiid, uiArgs: any = null): Promise<Node | null> {
|
||||
return new Promise<Node | null>((resolve, reject) => {
|
||||
const callbacks: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
resolve(node);
|
||||
},
|
||||
onLoadFailure: () => {
|
||||
resolve(null);
|
||||
}
|
||||
};
|
||||
this.open(uiid, uiArgs, callbacks);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定标识的窗口
|
||||
* @param uiid 窗口唯一标识
|
||||
* @param isDestroy 移除后是否释放(默认释放内存)
|
||||
* @example
|
||||
* oops.gui.remove(UIID.Loading);
|
||||
*/
|
||||
remove(uiid: Uiid, isDestroy: boolean = true) {
|
||||
remove(uiid: Uiid) {
|
||||
let info = this.getInfo(uiid);
|
||||
let layer = this.uiLayers.get(info.config.layer);
|
||||
if (layer) {
|
||||
layer.remove(info.config.prefab, isDestroy);
|
||||
layer.remove(info.config.prefab);
|
||||
}
|
||||
else {
|
||||
console.error(`移除编号为【${uiid}】的界面失败,界面层不存在`);
|
||||
@@ -271,25 +263,24 @@ export class LayerManager {
|
||||
/**
|
||||
* 通过界面节点移除
|
||||
* @param node 窗口节点
|
||||
* @param isDestroy 移除后是否释放资源(默认释放内存)
|
||||
* @example
|
||||
* oops.gui.removeByNode(cc.Node);
|
||||
*/
|
||||
removeByNode(node: Node, isDestroy: boolean = true) {
|
||||
removeByNode(node: Node) {
|
||||
if (node instanceof Node) {
|
||||
let comp = node.getComponent(LayerUIElement);
|
||||
if (comp && comp.params) {
|
||||
if (comp && comp.state) {
|
||||
// 释放显示的界面
|
||||
if (node.parent) {
|
||||
let uiid = gui.internal.getConfig(comp.params.uiid);
|
||||
this.remove(uiid, isDestroy);
|
||||
let uiid = gui.internal.getConfig(comp.state.uiid);
|
||||
this.remove(uiid);
|
||||
}
|
||||
// 释放缓存中的界面
|
||||
else if (isDestroy) {
|
||||
let layer = this.uiLayers.get(comp.params.config.layer);
|
||||
else {
|
||||
let layer = this.uiLayers.get(comp.state.config.layer);
|
||||
if (layer) {
|
||||
// @ts-ignore 注:不对外使用
|
||||
layer.removeCache(comp.params.config.prefab);
|
||||
layer.removeCache(comp.state.config.prefab);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,34 +294,14 @@ export class LayerManager {
|
||||
/**
|
||||
* 场景替换
|
||||
* @param removeUiId 移除场景编号
|
||||
* @param openUiId 新打开场景编号
|
||||
* @param uiArgs 新打开场景参数
|
||||
* @param openUiid 新打开场景编号
|
||||
* @param param 新打开场景参数
|
||||
*/
|
||||
replace(removeUiId: Uiid, openUiId: Uiid, uiArgs: any = null) {
|
||||
const callbacks: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
this.remove(removeUiId);
|
||||
}
|
||||
};
|
||||
this.open(openUiId, uiArgs, callbacks);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步场景替换
|
||||
* @param removeUiId 移除场景编号
|
||||
* @param openUiId 新打开场景编号
|
||||
* @param uiArgs 新打开场景参数
|
||||
*/
|
||||
replaceAsync(removeUiId: Uiid, openUiId: Uiid, uiArgs: any = null): Promise<Node | null> {
|
||||
return new Promise<Node | null>(async (resolve, reject) => {
|
||||
const node = await this.openAsync(openUiId, uiArgs);
|
||||
if (node) {
|
||||
this.remove(removeUiId);
|
||||
resolve(node);
|
||||
}
|
||||
else {
|
||||
resolve(null);
|
||||
}
|
||||
replace(removeUiId: Uiid, openUiid: Uiid, param?: UIParam): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
let node = await this.open(openUiid, param);
|
||||
this.remove(removeUiId);
|
||||
resolve(node);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { BlockInputEvents, EventTouch, Node } from "cc";
|
||||
import { ViewUtil } from "../../utils/ViewUtil";
|
||||
import { PromptResType } from "../GuiEnum";
|
||||
import { LayerUI } from "./LayerUI";
|
||||
import { UIParams } from "./LayerUIElement";
|
||||
import { UIState } from "./LayerUIElement";
|
||||
import { UIConfig } from "./UIConfig";
|
||||
|
||||
/* 弹窗层,允许同时弹出多个窗口 */
|
||||
@@ -32,12 +32,12 @@ export class LayerPopUp extends LayerUI {
|
||||
if (this.mask) this.mask.setSiblingIndex(this.children.length - 2);
|
||||
}
|
||||
|
||||
protected showUi(uip: UIParams): Promise<boolean> {
|
||||
protected uiInit(state: UIState): Promise<boolean> {
|
||||
return new Promise(async (resolve) => {
|
||||
const r = await super.showUi(uip);
|
||||
const r = await super.uiInit(state);
|
||||
if (r) {
|
||||
// 界面加载完成显示时,启动触摸非窗口区域关闭
|
||||
this.openVacancyRemove(uip.config);
|
||||
this.openVacancyRemove(state.config);
|
||||
|
||||
// 界面加载完成显示时,层级事件阻挡
|
||||
this.black.enabled = true;
|
||||
@@ -46,15 +46,15 @@ export class LayerPopUp extends LayerUI {
|
||||
});
|
||||
}
|
||||
|
||||
protected onCloseWindow(uip: UIParams) {
|
||||
super.onCloseWindow(uip);
|
||||
protected uiClose(state: UIState) {
|
||||
super.uiClose(state);
|
||||
|
||||
// 界面关闭后,关闭触摸事件阻挡、关闭触摸非窗口区域关闭、关闭遮罩
|
||||
this.closeUI();
|
||||
this.closeBlack();
|
||||
}
|
||||
|
||||
/** 设置触摸事件阻挡 */
|
||||
protected closeUI() {
|
||||
protected closeBlack() {
|
||||
// 所有弹窗关闭后,关闭事件阻挡功能
|
||||
if (this.ui_nodes.size == 0) {
|
||||
if (this.black) this.black.enabled = false;
|
||||
@@ -120,13 +120,13 @@ export class LayerPopUp extends LayerUI {
|
||||
if (this.ui_nodes.size > 0) {
|
||||
let vp = this.ui_nodes.array[this.ui_nodes.size - 1];
|
||||
if (vp.valid && vp.config.vacancy) {
|
||||
this.remove(vp.config.prefab, vp.config.destroy);
|
||||
this.remove(vp.config.prefab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear(isDestroy: boolean) {
|
||||
super.clear(isDestroy)
|
||||
this.closeUI();
|
||||
this.closeBlack();
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,20 @@
|
||||
import { instantiate, Node, Prefab, SafeArea } from "cc";
|
||||
import { Collection } from "db://oops-framework/libs/collection/Collection";
|
||||
import { resLoader } from "../../common/loader/ResLoader";
|
||||
import { oops } from "../../Oops";
|
||||
import { Uiid } from "./LayerEnum";
|
||||
import { LayerHelper } from "./LayerHelper";
|
||||
import { LayerUIElement, UICallbacks, UIParams } from "./LayerUIElement";
|
||||
import { LayerUIElement, UIParam, UIState } from "./LayerUIElement";
|
||||
import { UIConfig } from "./UIConfig";
|
||||
|
||||
/** 界面层对象 */
|
||||
export class LayerUI extends Node {
|
||||
/** 全局窗口打开失败 */
|
||||
/** 全局窗口打开失败事件 */
|
||||
onOpenFailure: Function = null!;
|
||||
/** 显示界面节点集合 */
|
||||
protected ui_nodes = new Collection<string, UIParams>();
|
||||
protected ui_nodes = new Collection<string, UIState>();
|
||||
/** 被移除的界面缓存数据 */
|
||||
protected ui_cache = new Map<string, UIParams>();
|
||||
protected ui_cache = new Map<string, UIState>();
|
||||
|
||||
/**
|
||||
* UI基础层,允许添加多个预制件节点
|
||||
@@ -28,71 +29,101 @@ export class LayerUI extends Node {
|
||||
* 添加一个预制件节点到层容器中,该方法将返回一个唯一`uuid`来标识该操作节点
|
||||
* @param config 界面配置数据
|
||||
* @param params 自定义参数
|
||||
* @param callbacks 回调函数对象,可选
|
||||
* @returns ture为成功,false为失败
|
||||
*/
|
||||
add(uiid: Uiid, config: UIConfig, params?: any, callbacks?: UICallbacks) {
|
||||
if (this.ui_nodes.has(config.prefab)) {
|
||||
console.warn(`路径为【${config.prefab}】的预制重复加载`);
|
||||
return;
|
||||
add(uiid: Uiid, config: UIConfig, params?: UIParam): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
if (this.ui_nodes.has(config.prefab)) {
|
||||
console.warn(`路径为【${config.prefab}】的预制重复加载`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查缓存中是否存界面
|
||||
let state = this.initUIConfig(uiid, config, params);
|
||||
await this.load(state, config.bundle);
|
||||
resolve(state.node);
|
||||
});
|
||||
}
|
||||
|
||||
/** 初始化界面配置初始值 */
|
||||
protected initUIConfig(uiid: Uiid, config: UIConfig, params?: UIParam) {
|
||||
let state = this.ui_cache.get(config.prefab);
|
||||
if (state == null) {
|
||||
if (config.bundle == null) config.bundle = resLoader.defaultBundleName;
|
||||
if (config.destroy == null) config.destroy = true;
|
||||
if (config.vacancy == null) config.vacancy = false;
|
||||
if (config.mask == null) config.mask = false;
|
||||
if (config.safeArea == null) config.safeArea = false;
|
||||
|
||||
state = new UIState();
|
||||
state.uiid = uiid.toString();
|
||||
state.config = config;
|
||||
}
|
||||
|
||||
// 检查缓存中是否存界面
|
||||
let uip = this.ui_cache.get(config.prefab);
|
||||
if (uip == null) {
|
||||
uip = new UIParams();
|
||||
uip.uiid = uiid.toString();
|
||||
uip.config = config;
|
||||
}
|
||||
this.ui_nodes.set(config.prefab, uip);
|
||||
|
||||
uip.params = params ?? {};
|
||||
uip.callbacks = callbacks ?? {};
|
||||
uip.valid = true;
|
||||
|
||||
this.load(uip, config.bundle)
|
||||
state.params = params ?? {};
|
||||
state.valid = true;
|
||||
this.ui_nodes.set(config.prefab, state);
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载界面资源
|
||||
* @param uip 显示参数
|
||||
* @param state 显示参数
|
||||
* @param bundle 远程资源包名,如果为空就是默认本地资源包
|
||||
*/
|
||||
protected async load(uip: UIParams, bundle?: string) {
|
||||
// 加载界面资源超时提示
|
||||
const timerId = setTimeout(this.onLoadingTimeoutGui, oops.config.game.loadingTimeoutGui);
|
||||
protected async load(state: UIState, bundle: string = resLoader.defaultBundleName): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
// 加载界面资源超时提示
|
||||
let timerId = setTimeout(this.onLoadingTimeoutGui, oops.config.game.loadingTimeoutGui);
|
||||
if (state.node == null) {
|
||||
// 优先加载配置的指定资源包中资源,如果没配置则加载默认资源包资源
|
||||
const res = await resLoader.loadAsync(bundle, state.config.prefab, Prefab);
|
||||
if (res) {
|
||||
state.node = instantiate(res);
|
||||
|
||||
if (uip && uip.node) {
|
||||
await this.showUi(uip);
|
||||
}
|
||||
else {
|
||||
// 优先加载配置的指定资源包中资源,如果没配置则加载默认资源包资源
|
||||
bundle = bundle || oops.res.defaultBundleName;
|
||||
const res = await oops.res.loadAsync(bundle, uip.config.prefab, Prefab);
|
||||
if (res) {
|
||||
uip.node = instantiate(res);
|
||||
// 是否启动真机安全区域显示
|
||||
if (state.config.safeArea) state.node.addComponent(SafeArea);
|
||||
|
||||
// 是否启动真机安全区域显示
|
||||
if (uip.config.safeArea) uip.node.addComponent(SafeArea);
|
||||
// 窗口事件委托
|
||||
const comp = state.node.addComponent(LayerUIElement);
|
||||
comp.state = state;
|
||||
}
|
||||
else {
|
||||
console.warn(`路径为【${state.config.prefab}】的预制加载失败`);
|
||||
this.failure(state);
|
||||
}
|
||||
}
|
||||
|
||||
// 窗口事件委托
|
||||
const dc = uip.node.addComponent(LayerUIElement);
|
||||
dc.params = uip;
|
||||
//@ts-ignore
|
||||
dc.onCloseWindow = this.onCloseWindow.bind(this);
|
||||
// 关闭界面资源超时提示
|
||||
oops.gui.waitClose();
|
||||
clearTimeout(timerId);
|
||||
|
||||
// 显示界面
|
||||
await this.showUi(uip);
|
||||
await this.uiInit(state);
|
||||
|
||||
resolve(state.node);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建界面节点
|
||||
* @param state 视图参数
|
||||
*/
|
||||
protected uiInit(state: UIState): Promise<boolean> {
|
||||
return new Promise<boolean>(async (resolve, reject) => {
|
||||
const comp = state.node.getComponent(LayerUIElement)!;
|
||||
const r: boolean = await comp.add();
|
||||
if (r) {
|
||||
state.valid = true; // 标记界面为使用状态
|
||||
if (!state.params.preload) {
|
||||
state.params.preload = false;
|
||||
state.node.parent = this;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn(`路径为【${uip.config.prefab}】的预制加载失败`);
|
||||
this.failure(uip);
|
||||
console.warn(`路径为【${state.config.prefab}】的自定义预处理逻辑异常.检查预制上绑定的组件中 onAdded 方法,返回true才能正确完成窗口显示流程`);
|
||||
this.failure(state);
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭界面资源超时提示
|
||||
oops.gui.waitClose();
|
||||
clearTimeout(timerId);
|
||||
resolve(r);
|
||||
});
|
||||
}
|
||||
|
||||
/** 加载超时事件*/
|
||||
@@ -101,74 +132,52 @@ export class LayerUI extends Node {
|
||||
}
|
||||
|
||||
/** 窗口关闭事件 */
|
||||
protected onCloseWindow(vp: UIParams) {
|
||||
this.ui_nodes.delete(vp.config.prefab);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建界面节点
|
||||
* @param uip 视图参数
|
||||
*/
|
||||
protected async showUi(uip: UIParams): Promise<boolean> {
|
||||
// 触发窗口添加事件
|
||||
const comp = uip.node.getComponent(LayerUIElement)!;
|
||||
const r: boolean = await comp.add();
|
||||
if (r) {
|
||||
uip.node.parent = this;
|
||||
|
||||
// 标记界面为使用状态
|
||||
uip.valid = true;
|
||||
}
|
||||
else {
|
||||
console.warn(`路径为【${uip.config.prefab}】的自定义预处理逻辑异常.检查预制上绑定的组件中 onAdded 方法,返回true才能正确完成窗口显示流程`);
|
||||
this.failure(uip);
|
||||
}
|
||||
return r;
|
||||
protected uiClose(state: UIState) {
|
||||
this.ui_nodes.delete(state.config.prefab);
|
||||
}
|
||||
|
||||
/** 打开窗口失败逻辑 */
|
||||
protected failure(uip: UIParams) {
|
||||
this.onCloseWindow(uip);
|
||||
uip.callbacks && uip.callbacks.onLoadFailure && uip.callbacks.onLoadFailure();
|
||||
protected failure(state: UIState) {
|
||||
this.uiClose(state);
|
||||
this.onOpenFailure && this.onOpenFailure();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据预制件路径删除,预制件如在队列中也会被删除,如果该预制件存在多个也会一起删除
|
||||
* @param prefabPath 预制路径
|
||||
* @param isDestroy 移除后是否释放
|
||||
*/
|
||||
remove(prefabPath: string, isDestroy?: boolean): void {
|
||||
let release: any = undefined;
|
||||
if (isDestroy !== undefined) release = isDestroy;
|
||||
remove(prefabPath: string): void {
|
||||
let release: boolean = true;
|
||||
|
||||
// 界面移出舞台
|
||||
const uip = this.ui_nodes.get(prefabPath);
|
||||
if (uip) {
|
||||
const state = this.ui_nodes.get(prefabPath);
|
||||
if (state) {
|
||||
// 优先使用参数中控制的释放条件,如果未传递参数则用配置中的释放条件,默认不缓存关闭的界面
|
||||
if (release === undefined) {
|
||||
release = uip.config.destroy !== undefined ? uip.config.destroy : true;
|
||||
}
|
||||
release = state.config.destroy !== undefined ? state.config.destroy : true;
|
||||
|
||||
// 不释放界面,缓存起来待下次使用
|
||||
if (release === false) {
|
||||
this.ui_cache.set(uip.config.prefab, uip);
|
||||
this.ui_cache.set(state.config.prefab, state);
|
||||
}
|
||||
|
||||
const node = uip.node;
|
||||
const node = state.node;
|
||||
const comp = node.getComponent(LayerUIElement)!;
|
||||
comp.remove(release);
|
||||
}
|
||||
|
||||
// 验证是否删除后台缓存界面
|
||||
if (release === true) this.removeCache(prefabPath);
|
||||
// 清理界面缓存
|
||||
const cache = this.ui_cache.get(prefabPath);
|
||||
if (cache) {
|
||||
// 验证是否删除后台缓存界面
|
||||
if (release) this.removeCache(prefabPath);
|
||||
}
|
||||
}
|
||||
|
||||
/** 删除缓存的界面,当缓存界面被移除舞台时,可通过此方法删除缓存界面 */
|
||||
private removeCache(prefabPath: string) {
|
||||
let vp = this.ui_cache.get(prefabPath);
|
||||
if (vp) {
|
||||
this.onCloseWindow(vp);
|
||||
this.uiClose(vp);
|
||||
this.ui_cache.delete(prefabPath);
|
||||
const node = vp.node;
|
||||
const comp = node.getComponent(LayerUIElement)!;
|
||||
@@ -177,6 +186,12 @@ export class LayerUI extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
/** 显示界面 */
|
||||
show(prefabPath: string) {
|
||||
const vp = this.ui_nodes.get(prefabPath);
|
||||
if (vp) vp.node.parent = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据预制路径获取已打开界面的节点对象
|
||||
* @param prefabPath 预制路径
|
||||
@@ -204,13 +219,13 @@ export class LayerUI extends Node {
|
||||
const length = this.ui_nodes.array.length - 1;
|
||||
for (let i = length; i >= 0; i--) {
|
||||
const uip = this.ui_nodes.array[i];
|
||||
this.remove(uip.config.prefab, isDestroy);
|
||||
this.remove(uip.config.prefab);
|
||||
}
|
||||
this.ui_nodes.clear();
|
||||
|
||||
// 清除缓存中的界面
|
||||
if (isDestroy) {
|
||||
this.ui_cache.forEach((value: UIParams, prefabPath: string) => {
|
||||
this.ui_cache.forEach((value: UIState, prefabPath: string) => {
|
||||
this.removeCache(prefabPath);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,11 +18,9 @@ const { ccclass } = _decorator;
|
||||
@ccclass('LayerUIElement')
|
||||
export class LayerUIElement extends Component {
|
||||
/** 视图参数 */
|
||||
params: UIParams = null!;
|
||||
state: UIState = null!;
|
||||
/** 关闭窗口之前 */
|
||||
onCloseWindowBefore: Function = null!;
|
||||
/** 界面关闭回调 - 包括关闭动画播放完(辅助框架内存业务流程使用) */
|
||||
private onCloseWindow: Function = null!;
|
||||
onClose: Function = null!;
|
||||
|
||||
/** 添加界面且界面设置到父节点之前 */
|
||||
add(): Promise<boolean> {
|
||||
@@ -32,7 +30,7 @@ export class LayerUIElement extends Component {
|
||||
const component: any = this.node.components[i];
|
||||
const func = component[EventOnAdded];
|
||||
if (func) {
|
||||
if (await func.call(component, this.params.params) == false) {
|
||||
if (await func.call(component, this.state.params.data) == false) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
@@ -40,8 +38,8 @@ export class LayerUIElement extends Component {
|
||||
}
|
||||
|
||||
// 触发外部窗口显示前的事件(辅助实现自定义动画逻辑)
|
||||
if (typeof this.params.callbacks.onAdded === "function") {
|
||||
this.params.callbacks.onAdded(this.node, this.params.params);
|
||||
if (typeof this.state.params.onAdded === "function") {
|
||||
this.state.params.onAdded(this.node, this.state.params.data);
|
||||
}
|
||||
|
||||
resolve(true);
|
||||
@@ -49,14 +47,14 @@ export class LayerUIElement extends Component {
|
||||
}
|
||||
|
||||
/** 删除节点,该方法只能调用一次,将会触发onBeforeRemoved回调 */
|
||||
remove(isDestroy?: boolean) {
|
||||
if (this.params.valid) {
|
||||
remove(isDestroy: boolean) {
|
||||
if (this.state.valid) {
|
||||
// 触发窗口移除舞台之前事件
|
||||
this.applyComponentsFunction(this.node, EventOnBeforeRemove, this.params.params);
|
||||
this.applyComponentsFunction(this.node, EventOnBeforeRemove, this.state.params.data);
|
||||
|
||||
// 通知外部对象窗口组件上移除之前的事件(关闭窗口前的关闭动画处理)
|
||||
if (typeof this.params.callbacks.onBeforeRemove === "function") {
|
||||
this.params.callbacks.onBeforeRemove(this.node, this.onBeforeRemoveNext.bind(this, isDestroy));
|
||||
if (typeof this.state.params.onBeforeRemove === "function") {
|
||||
this.state.params.onBeforeRemove(this.node, this.onBeforeRemoveNext.bind(this, isDestroy));
|
||||
}
|
||||
else {
|
||||
this.onBeforeRemoveNext(isDestroy);
|
||||
@@ -68,28 +66,26 @@ export class LayerUIElement extends Component {
|
||||
}
|
||||
|
||||
/** 窗口关闭前动画处理完后的回调方法,主要用于释放资源 */
|
||||
private onBeforeRemoveNext(isDestroy?: boolean) {
|
||||
this.onCloseWindowBefore && this.onCloseWindowBefore();
|
||||
this.removed(this.params, isDestroy);
|
||||
}
|
||||
private onBeforeRemoveNext(isDestroy: boolean) {
|
||||
this.state.valid = false;
|
||||
|
||||
/** 窗口组件中触发移除事件与释放窗口对象 */
|
||||
private removed(uip: UIParams, isDestroy?: boolean) {
|
||||
uip.valid = false;
|
||||
|
||||
if (uip.callbacks && typeof uip.callbacks.onRemoved === "function") {
|
||||
uip.callbacks.onRemoved(this.node, uip.params);
|
||||
if (this.state.params && typeof this.state.params.onRemoved === "function") {
|
||||
this.state.params.onRemoved(this.node, this.state.params.data);
|
||||
}
|
||||
|
||||
// 界面移除舞台事件
|
||||
this.onCloseWindow && this.onCloseWindow(uip);
|
||||
// 关闭动画播放完后,界面移除舞台
|
||||
//@ts-ignore
|
||||
this.node.parent.uiClose(this.state);
|
||||
|
||||
// 关闭动画播放完后,界面移除舞台事件
|
||||
this.onClose && this.onClose();
|
||||
|
||||
if (isDestroy) {
|
||||
// 释放界面显示对象
|
||||
this.node.destroy();
|
||||
|
||||
// 释放界面相关资源
|
||||
oops.res.release(uip.config.prefab, uip.config.bundle);
|
||||
oops.res.release(this.state.config.prefab, this.state.config.bundle);
|
||||
|
||||
// oops.log.logView(`【界面管理】释放【${uip.config.prefab}】界面资源`);
|
||||
}
|
||||
@@ -98,7 +94,7 @@ export class LayerUIElement extends Component {
|
||||
}
|
||||
|
||||
// 触发窗口组件上窗口移除之后的事件
|
||||
this.applyComponentsFunction(this.node, EventOnRemoved, this.params.params);
|
||||
this.applyComponentsFunction(this.node, EventOnRemoved, this.state.params.data);
|
||||
}
|
||||
|
||||
private applyComponentsFunction(node: Node, funName: string, params: any) {
|
||||
@@ -112,38 +108,33 @@ export class LayerUIElement extends Component {
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
this.params = null!;
|
||||
this.onCloseWindowBefore = null!;
|
||||
this.onCloseWindow = null!;
|
||||
this.state = null!;
|
||||
this.onClose = null!;
|
||||
}
|
||||
}
|
||||
|
||||
/** 本类型仅供gui模块内部使用,请勿在功能逻辑中使用 */
|
||||
export class UIParams {
|
||||
export class UIState {
|
||||
/** 界面唯一编号 */
|
||||
uiid: string = null!;
|
||||
/** 界面配置 */
|
||||
config: UIConfig = null!;
|
||||
/** 传递给打开界面的参数 */
|
||||
params: any = null!;
|
||||
/** 窗口事件 */
|
||||
callbacks: UICallbacks = null!;
|
||||
params: UIParam = null!;
|
||||
/** 是否在使用状态 */
|
||||
valid: boolean = true;
|
||||
/** 界面根节点 */
|
||||
node: Node = null!;
|
||||
}
|
||||
|
||||
/** 界面关闭参数 */
|
||||
export interface UIRemove {
|
||||
/** 关闭是否释放资源内存 */
|
||||
isDestroy?: boolean;
|
||||
/** 界面动画播放完关闭事件 */
|
||||
onRemoved?: Function;
|
||||
}
|
||||
/*** 界面打开参数 */
|
||||
export interface UIParam {
|
||||
/** 自定义传递参数 */
|
||||
data?: any;
|
||||
|
||||
/** 是否开启预加载(默认不开启 - 开启后加载完不显示界面) */
|
||||
preload?: boolean;
|
||||
|
||||
/*** 界面回调参数对象定义 */
|
||||
export interface UICallbacks {
|
||||
/**
|
||||
* 节点添加到层级以后的回调
|
||||
* @param node 当前界面节点
|
||||
@@ -151,13 +142,6 @@ export interface UICallbacks {
|
||||
*/
|
||||
onAdded?: (node: Node, params: any) => void,
|
||||
|
||||
/**
|
||||
* 窗口节点 destroy 之后回调
|
||||
* @param node 当前界面节点
|
||||
* @param params 外部传递参数
|
||||
*/
|
||||
onRemoved?: (node: Node | null, params: any) => void,
|
||||
|
||||
/**
|
||||
* 如果指定onBeforeRemoved,则next必须调用,否则节点不会被正常删除。
|
||||
*
|
||||
@@ -167,6 +151,10 @@ export interface UICallbacks {
|
||||
*/
|
||||
onBeforeRemove?: (node: Node, next: Function) => void,
|
||||
|
||||
/** 网络异常时,窗口加载失败回调 */
|
||||
onLoadFailure?: () => void;
|
||||
/**
|
||||
* 窗口节点 destroy 之后回调
|
||||
* @param node 当前界面节点
|
||||
* @param params 外部传递参数
|
||||
*/
|
||||
onRemoved?: (node: Node, params: any) => void
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export interface UIConfig {
|
||||
vacancy?: boolean,
|
||||
/** 是否打开窗口后显示背景遮罩(默认关闭) */
|
||||
mask?: boolean;
|
||||
/** 是否启动真机安全区域显示 */
|
||||
/** 是否启动真机安全区域显示(默认关闭) */
|
||||
safeArea?: boolean;
|
||||
/** 界面弹出时的节点排序索引 */
|
||||
siblingIndex?: number;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* @LastEditTime: 2022-09-06 17:20:51
|
||||
*/
|
||||
|
||||
import { UIRemove } from '../../core/gui/layer/LayerUIElement';
|
||||
import { ecs } from '../../libs/ecs/ECS';
|
||||
import { ECSModel } from '../../libs/ecs/ECSModel';
|
||||
import { GameComponent } from './GameComponent';
|
||||
@@ -43,13 +42,13 @@ export abstract class CCComp extends GameComponent implements ecs.IComp {
|
||||
tid: number = -1;
|
||||
|
||||
/** 从父节点移除自己 */
|
||||
remove(params?: UIRemove) {
|
||||
remove() {
|
||||
const cct = ECSModel.compCtors[this.tid];
|
||||
if (this.ent) {
|
||||
ModuleUtil.removeGui(this.ent, cct, params);
|
||||
ModuleUtil.removeGui(this.ent, cct);
|
||||
}
|
||||
else {
|
||||
console.error(`组件 ${this.name} 移除失败,实体不存在`);
|
||||
console.error(`组件 ${this.name} 移除失败,组件未注册`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* @LastEditTime: 2022-09-06 17:22:05
|
||||
*/
|
||||
|
||||
import { UIRemove } from '../../core/gui/layer/LayerUIElement';
|
||||
import { ecs } from '../../libs/ecs/ECS';
|
||||
import { ECSModel } from '../../libs/ecs/ECSModel';
|
||||
import VMParent from '../../libs/model-view/VMParent';
|
||||
@@ -55,13 +54,13 @@ export abstract class CCVMParentComp extends VMParent implements ecs.IComp {
|
||||
tid: number = -1;
|
||||
|
||||
/** 从父节点移除自己 */
|
||||
remove(params?: UIRemove) {
|
||||
remove() {
|
||||
const cct = ECSModel.compCtors[this.tid];
|
||||
if (this.ent) {
|
||||
ModuleUtil.removeGui(this.ent, cct, params);
|
||||
ModuleUtil.removeGui(this.ent, cct);
|
||||
}
|
||||
else {
|
||||
console.error(`组件 ${this.name} 移除失败,实体不存在`);
|
||||
console.error(`组件 ${this.name} 移除失败,组件未注册`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IAudioParams } from "../../core/common/audio/IAudio";
|
||||
import { EventDispatcher } from "../../core/common/event/EventDispatcher";
|
||||
import { EventMessage, ListenerFunc } from "../../core/common/event/EventMessage";
|
||||
import { AssetType, CompleteCallback, Paths, ProgressCallback, resLoader } from "../../core/common/loader/ResLoader";
|
||||
import { LayerUIElement, UIRemove } from "../../core/gui/layer/LayerUIElement";
|
||||
import { LayerUIElement } from "../../core/gui/layer/LayerUIElement";
|
||||
import { ViewUtil } from "../../core/utils/ViewUtil";
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
@@ -483,18 +483,10 @@ export class GameComponent extends Component {
|
||||
//#endregion
|
||||
|
||||
/** 移除自己 */
|
||||
remove(params?: UIRemove) {
|
||||
if (params == null) {
|
||||
params = { isDestroy: true };
|
||||
}
|
||||
else {
|
||||
if (params.isDestroy == null) params.isDestroy = true;
|
||||
}
|
||||
|
||||
remove() {
|
||||
const comp = this.node.getComponent(LayerUIElement);
|
||||
if (comp) {
|
||||
if (params.onRemoved) comp.onCloseWindowBefore = params.onRemoved;
|
||||
oops.gui.removeByNode(this.node, params.isDestroy);
|
||||
oops.gui.removeByNode(this.node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@ import { Node, __private } from "cc";
|
||||
import { oops } from "../../core/Oops";
|
||||
import { resLoader } from "../../core/common/loader/ResLoader";
|
||||
import { gui } from "../../core/gui/Gui";
|
||||
import { Uiid } from "../../core/gui/layer/LayerEnum";
|
||||
import { LayerUIElement, UICallbacks, UIRemove } from "../../core/gui/layer/LayerUIElement";
|
||||
import { LayerUIElement, UIParam } from "../../core/gui/layer/LayerUIElement";
|
||||
import { ViewUtil } from "../../core/utils/ViewUtil";
|
||||
import { ecs } from "../../libs/ecs/ECS";
|
||||
import { CompType } from "../../libs/ecs/ECSModel";
|
||||
@@ -17,29 +16,26 @@ export class ModuleUtil {
|
||||
* 异步添加视图层组件
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param uiArgs 界面参数
|
||||
* @param anim 界面打开与关闭动画
|
||||
* @param params 界面参数
|
||||
* @returns 界面节点
|
||||
*/
|
||||
static addGui<T extends CCVMParentComp | CCComp>(ent: ecs.Entity, ctor: ECSCtor<T>, uiArgs?: any, anim?: UICallbacks): Promise<Node | null> {
|
||||
return new Promise<Node | null>((resolve, reject) => {
|
||||
const uic: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
const comp = node.getComponent(ctor) as ecs.Comp;
|
||||
ent.add(comp);
|
||||
if (anim && anim.onAdded) anim.onAdded(node, params);
|
||||
resolve(node);
|
||||
},
|
||||
onLoadFailure: () => {
|
||||
if (anim && anim.onLoadFailure) anim.onLoadFailure();
|
||||
resolve(null);
|
||||
}
|
||||
};
|
||||
|
||||
static addGui<T extends CCVMParentComp | CCComp>(ent: ecs.Entity, ctor: ECSCtor<T>, params?: UIParam): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
//@ts-ignore
|
||||
const key = ctor[gui.internal.GUI_KEY];
|
||||
if (key) {
|
||||
oops.gui.open(key, uiArgs, uic);
|
||||
if (params == null) {
|
||||
params = { preload: true };
|
||||
}
|
||||
else {
|
||||
params.preload = true;
|
||||
}
|
||||
|
||||
let node = await oops.gui.open(key, params);
|
||||
const comp = node.getComponent(ctor) as ecs.Comp;
|
||||
ent.add(comp);
|
||||
oops.gui.show(key);
|
||||
resolve(node);
|
||||
}
|
||||
else {
|
||||
console.error(`${key} 界面组件未使用 gui.register 注册`);
|
||||
@@ -49,18 +45,11 @@ export class ModuleUtil {
|
||||
|
||||
/**
|
||||
* 业务实体上移除界面组件
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param params 界面关闭参数
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param params 界面关闭参数
|
||||
*/
|
||||
static removeGui(ent: ecs.Entity, ctor: CompType<ecs.IComp>, params?: UIRemove) {
|
||||
if (params == null) {
|
||||
params = { isDestroy: true };
|
||||
}
|
||||
else {
|
||||
if (params.isDestroy == null) params.isDestroy = true;
|
||||
}
|
||||
|
||||
static removeGui(ent: ecs.Entity, ctor: CompType<ecs.IComp>) {
|
||||
//@ts-ignore
|
||||
const key = ctor[gui.internal.GUI_KEY];
|
||||
if (key) {
|
||||
@@ -72,16 +61,14 @@ export class ModuleUtil {
|
||||
|
||||
const comp = node.getComponent(LayerUIElement);
|
||||
if (comp) {
|
||||
comp.onCloseWindowBefore = () => {
|
||||
if (params.isDestroy) ent.remove(ctor);
|
||||
if (params.onRemoved) params.onRemoved();
|
||||
comp.onClose = () => {
|
||||
if (comp.state.config.destroy) ent.remove(ctor);
|
||||
};
|
||||
oops.gui.remove(key, params.isDestroy);
|
||||
oops.gui.remove(key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (params.isDestroy) ent.remove(ctor);
|
||||
if (params.onRemoved) params.onRemoved();
|
||||
ent.remove(ctor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,77 +86,4 @@ export class ModuleUtil {
|
||||
ent.add(comp);
|
||||
node.parent = parent;
|
||||
}
|
||||
|
||||
//#region deprecated
|
||||
/**
|
||||
* 添加界面组件
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param uiId 界面资源编号
|
||||
* @param uiArgs 界面参数
|
||||
* @deprecated 使用gui.register注册的界面组件,可使用add方法打开
|
||||
*/
|
||||
static addViewUi<T extends CCVMParentComp | CCComp>(ent: ecs.Entity, ctor: ECSCtor<T>, uiId: Uiid, uiArgs: any = null) {
|
||||
const uic: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
const comp = node.getComponent(ctor) as ecs.Comp;
|
||||
//@ts-ignore
|
||||
if (!ent.has(ctor)) ent.add(comp);
|
||||
}
|
||||
};
|
||||
oops.gui.open(uiId, uiArgs, uic);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步添加视图层组件
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param uiId 界面资源编号
|
||||
* @param uiArgs 界面参数
|
||||
* @returns 界面节点
|
||||
* @deprecated 使用gui.register注册的界面组件,可使用add方法打开
|
||||
*/
|
||||
static addViewUiAsync<T extends CCVMParentComp | CCComp>(ent: ecs.Entity, ctor: ECSCtor<T>, uiId: Uiid, uiArgs: any = null): Promise<Node | null> {
|
||||
return new Promise<Node | null>((resolve, reject) => {
|
||||
const uic: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
const comp = node.getComponent(ctor) as ecs.Comp;
|
||||
ent.add(comp);
|
||||
resolve(node);
|
||||
},
|
||||
onLoadFailure: () => {
|
||||
resolve(null);
|
||||
}
|
||||
};
|
||||
oops.gui.open(uiId, uiArgs, uic);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务实体上移除界面组件
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param uiId 界面资源编号
|
||||
* @param isDestroy 是否释放界面缓存(默认为释放界面缓存)
|
||||
* @param onRemoved 窗口关闭完成事件
|
||||
* @deprecated 使用gui.register注册的界面组件,可使用remove方法移除
|
||||
*/
|
||||
static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: Uiid, isDestroy: boolean = true, onRemoved?: Function) {
|
||||
const node = oops.gui.get(uiId);
|
||||
if (!node) {
|
||||
if (onRemoved) onRemoved();
|
||||
return;
|
||||
}
|
||||
|
||||
const comp = node.getComponent(LayerUIElement);
|
||||
if (comp) {
|
||||
comp.onCloseWindowBefore = () => {
|
||||
// 移除ECS显示组件
|
||||
if (isDestroy) ent.remove(ctor, isDestroy);
|
||||
if (onRemoved) onRemoved();
|
||||
};
|
||||
oops.gui.remove(uiId, isDestroy);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user