界面支持直接传窗口配置的方式开关

1、省去UIID枚举配置
2、每个模块的窗口配置可代码分离管理
This commit is contained in:
dgflash
2025-07-26 12:45:37 +08:00
parent 501b20ee1d
commit 91786493f7
7 changed files with 133 additions and 159 deletions

View File

@@ -5,6 +5,7 @@
* @LastEditTime: 2023-01-09 11:52:38
*/
import { Node } from "cc";
import { Uiid } from "./LayerEnum";
import { UIConfig } from "./UIConfig";
/*** 界面回调参数对象定义 */
@@ -39,7 +40,7 @@ export interface UICallbacks {
/** 本类型仅供gui模块内部使用请勿在功能逻辑中使用 */
export class ViewParams {
/** 界面唯一编号 */
uiid: number = -1;
uiid: string = null!;
/** 界面配置 */
config: UIConfig = null!;
/** 传递给打开界面的参数 */

View File

@@ -96,11 +96,6 @@ export class DelegateComponent extends Component {
// 释放界面相关资源
oops.res.release(vp.config.prefab, vp.config.bundle);
// 释放自动递增编号的界面配置
if (vp.config.auto) {
oops.gui.setConfig(vp.uiid, null!);
}
oops.log.logView(`【界面管理】释放【${vp.config.prefab}】界面资源`);
}
else {

View File

@@ -1,3 +1,10 @@
import { UIConfig } from "./UIConfig";
/** 界面编号 */
export type Uiid = number | string | UIConfig;
/** 界面配置集合 */
export type UIConfigMap = { [key: string]: UIConfig }
/** 屏幕适配类型 */
export enum ScreenAdapterType {
/** 自动适配 */

View File

@@ -1,27 +1,15 @@
import { Camera, Layers, Node, ResolutionPolicy, SafeArea, Widget, screen, view, warn } from "cc";
import { resLoader } from "../../common/loader/ResLoader";
import { oops } from "../../Oops";
import { UICallbacks } from "./Defines";
import { DelegateComponent } from "./DelegateComponent";
import { LayerDialog } from "./LayerDialog";
import { LayerType, LayerTypeCls } from "./LayerEnum";
import { LayerType, LayerTypeCls, UIConfigMap, Uiid } from "./LayerEnum";
import { LayerNotify } from "./LayerNotify";
import { LayerPopUp } from "./LayerPopup";
import { LayerUI } from "./LayerUI";
import { UIConfig } from "./UIConfig";
/** 自动生成界面编号最小值 */
const uiidMin = 1000000;
/** 自动生成界面编号最大值 */
const uiidMax = 9999999;
var uiid: number = uiidMin; // 当前自动递增界面编号
/** 自动获取界面唯一编号 */
function getUiid(): number {
if (uiid == uiidMax) uiid = uiidMin;
uiid++;
return uiid;
}
/** 界面层级管理器 */
export class LayerManager {
/** 界面根节点 */
@@ -43,7 +31,7 @@ export class LayerManager {
/** 消息提示控制器请使用show方法来显示 */
private notify!: LayerNotify;
/** UI配置 */
private configs: { [key: number]: UIConfig } = {};
private configs: UIConfigMap = {};
/** 界面层集合 - 无自定义类型 */
private uiLayers: Map<string, LayerUI> = new Map();
/** 界面层组件集合 */
@@ -148,7 +136,7 @@ export class LayerManager {
* 初始化所有UI的配置对象
* @param configs 配置对象
*/
init(configs: { [key: number]: UIConfig }): void {
init(configs: UIConfigMap): void {
this.configs = configs;
}
@@ -183,16 +171,28 @@ export class LayerManager {
this.notify.waitClose();
}
/**
* 设置界面配置
* @param uiid 要设置的界面id
* @param config 要设置的配置
*/
setConfig(uiid: number, config: UIConfig): void {
if (config)
this.configs[uiid] = config;
else
delete this.configs[uiid];
private getInfo(uiid: Uiid): { key: string; config: UIConfig } {
let key = "";
let config: UIConfig = null!;
// 确定 key 和 config
if (typeof uiid === 'object') {
if (uiid.bundle == null) uiid.bundle = resLoader.defaultBundleName;
key = uiid.bundle + "_" + uiid.prefab;
config = this.configs[key];
if (config == null) {
config = uiid;
this.configs[key] = uiid;
}
}
else {
key = uiid.toString();
config = this.configs[uiid];
if (config == null) {
console.error(`打开编号为【${uiid}】的界面失败,配置信息不存在`);
}
}
return { key, config };
}
/**
@@ -211,16 +211,11 @@ export class LayerManager {
};
oops.gui.open(UIID.Loading, null, uic);
*/
open(uiid: number, uiArgs: any = null, callbacks?: UICallbacks): void {
const config = this.configs[uiid];
if (config == null) {
warn(`打开编号为【${uiid}】的界面失败,配置信息不存在`);
return;
}
let layer = this.uiLayers.get(config.layer);
open(uiid: Uiid, uiArgs: any = null, callbacks?: UICallbacks): void {
let info = this.getInfo(uiid);
let layer = this.uiLayers.get(info.config.layer);
if (layer) {
layer.add(uiid, config, uiArgs, callbacks);
layer.add(info.key, info.config, uiArgs, callbacks);
}
else {
console.error(`打开编号为【${uiid}】的界面失败,界面层不存在`);
@@ -234,7 +229,7 @@ export class LayerManager {
* @example
* var node = await oops.gui.openAsync(UIID.Loading);
*/
async openAsync(uiid: number, uiArgs: any = null): Promise<Node | null> {
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) => {
@@ -248,105 +243,6 @@ export class LayerManager {
});
}
/**
* 通过界面配置打开一个界面
* @param config 界面配置数据
* @returns
*/
openAsyncConfig(config: UIConfig): Promise<number> {
return new Promise(async (resolve, reject) => {
let uiid = getUiid();
config.auto = true;
this.setConfig(uiid, config);
await oops.gui.openAsync(uiid, { uiid: uiid });
resolve(uiid);
});
}
/**
* 场景替换
* @param removeUiId 移除场景编号
* @param openUiId 新打开场景编号
* @param uiArgs 新打开场景参数
*/
replace(removeUiId: number, openUiId: number, 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: number, openUiId: number, 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);
}
});
}
/**
* 缓存中是否存在指定标识的窗口
* @param uiid 窗口唯一标识
* @example
* oops.gui.has(UIID.Loading);
*/
has(uiid: number): boolean {
const config = this.configs[uiid];
if (config == null) {
warn(`编号为【${uiid}】的界面配置不存在,配置信息不存在`);
return false;
}
var result = false;
let layer = this.uiLayers.get(config.layer);
if (layer) {
result = layer.has(config.prefab);
}
else {
console.error(`验证编号为【${uiid}】的界面失败,界面层不存在`);
}
return result;
}
/**
* 缓存中是否存在指定标识的窗口
* @param uiid 窗口唯一标识
* @example
* oops.gui.has(UIID.Loading);
*/
get(uiid: number): Node {
const config = this.configs[uiid];
if (config == null) {
warn(`编号为【${uiid}】的界面配置不存在,配置信息不存在`);
return null!;
}
let result: Node = null!;
let layer = this.uiLayers.get(config.layer);
if (layer) {
result = layer.get(config.prefab);
}
else {
console.error(`获取编号为【${uiid}】的界面失败,界面层不存在`);
}
return result;
}
/**
* 移除指定标识的窗口
* @param uiid 窗口唯一标识
@@ -354,16 +250,11 @@ export class LayerManager {
* @example
* oops.gui.remove(UIID.Loading);
*/
remove(uiid: number, isDestroy: boolean = true) {
const config = this.configs[uiid];
if (config == null) {
warn(`删除编号为【${uiid}】的界面失败,配置信息不存在`);
return;
}
let layer = this.uiLayers.get(config.layer);
remove(uiid: Uiid, isDestroy: boolean = true) {
let info = this.getInfo(uiid);
let layer = this.uiLayers.get(info.config.layer);
if (layer) {
layer.remove(config.prefab, isDestroy);
layer.remove(info.config.prefab, isDestroy);
}
else {
console.error(`移除编号为【${uiid}】的界面失败,界面层不存在`);
@@ -383,7 +274,8 @@ export class LayerManager {
if (comp && comp.vp) {
// 释放显示的界面
if (node.parent) {
this.remove(comp.vp.uiid, isDestroy);
let uiid = this.configs[comp.vp.uiid];
this.remove(uiid, isDestroy);
}
// 释放缓存中的界面
else if (isDestroy) {
@@ -395,12 +287,85 @@ export class LayerManager {
}
}
else {
warn(`当前删除的 Node 不是通过界面管理器添加`);
warn(`当前删除的 Node 不是通过界面管理器添加`);
node.destroy();
}
}
}
/**
* 场景替换
* @param removeUiId 移除场景编号
* @param openUiId 新打开场景编号
* @param uiArgs 新打开场景参数
*/
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);
}
});
}
/**
* 缓存中是否存在指定标识的窗口
* @param uiid 窗口唯一标识
* @example
* oops.gui.has(UIID.Loading);
*/
has(uiid: Uiid): boolean {
let info = this.getInfo(uiid);
let result = false;
let layer = this.uiLayers.get(info.config.layer);
if (layer) {
result = layer.has(info.config.prefab);
}
else {
console.error(`验证编号为【${uiid}】的界面失败,界面层不存在`);
}
return result;
}
/**
* 缓存中是否存在指定标识的窗口
* @param uiid 窗口唯一标识
* @example
* oops.gui.has(UIID.Loading);
*/
get(uiid: Uiid): Node {
let info = this.getInfo(uiid);
let result: Node = null!;
let layer = this.uiLayers.get(info.config.layer);
if (layer) {
result = layer.get(info.config.prefab);
}
else {
console.error(`获取编号为【${uiid}】的界面失败,界面层不存在`);
}
return result;
}
/**
* 清除所有窗口
* @param isDestroy 移除后是否释放

View File

@@ -3,6 +3,7 @@ import { Collection } from "db://oops-framework/libs/collection/Collection";
import { oops } from "../../Oops";
import { UICallbacks, ViewParams } from "./Defines";
import { DelegateComponent } from "./DelegateComponent";
import { Uiid } from "./LayerEnum";
import { UIConfig } from "./UIConfig";
/** 界面层对象 */
@@ -35,7 +36,7 @@ export class LayerUI extends Node {
* @param callbacks 回调函数对象,可选
* @returns ture为成功,false为失败
*/
add(uiid: number, config: UIConfig, params?: any, callbacks?: UICallbacks) {
add(uiid: Uiid, config: UIConfig, params?: any, callbacks?: UICallbacks) {
if (this.ui_nodes.has(config.prefab)) {
console.warn(`路径为【${config.prefab}】的预制重复加载`);
return;
@@ -45,7 +46,7 @@ export class LayerUI extends Node {
let vp = this.ui_cache.get(config.prefab);
if (vp == null) {
vp = new ViewParams();
vp.uiid = uiid;
vp.uiid = uiid.toString();
vp.config = config;
}
this.ui_nodes.set(config.prefab, vp);

View File

@@ -10,16 +10,19 @@ export enum UIID {
Netinstable
}
// 打开界面方式的配置数据
// 打开界面方式1
export var UIConfigData: { [key: number]: UIConfig } = {
[UIID.Loading]: { layer: LayerType.UI, prefab: "loading/prefab/loading", bundle: "resources" },
[UIID.Netinstable]: { layer: LayerType.PopUp, prefab: "common/prefab/netinstable" },
[UIID.Window]: { layer: LayerType.Dialog, prefab: "common/prefab/window" }
}
// 打开界面方式2
export class InitializeUIConfig {
static Loading = { layer: LayerType.UI, prefab: "gui/loading/loading" }
}
*/
export interface UIConfig {
/** 是否为自动生成的界面编号 */
auto?: boolean,
/** -----公共属性----- */
/** 远程包名 */
bundle?: string;

View File

@@ -3,6 +3,8 @@ import { oops } from "../../core/Oops";
import { resLoader } from "../../core/common/loader/ResLoader";
import { UICallbacks } from "../../core/gui/layer/Defines";
import { DelegateComponent } from "../../core/gui/layer/DelegateComponent";
import { Uiid } from "../../core/gui/layer/LayerEnum";
import { UIConfig } from "../../core/gui/layer/UIConfig";
import { ViewUtil } from "../../core/utils/ViewUtil";
import { ecs } from "../../libs/ecs/ECS";
import { CompType } from "../../libs/ecs/ECSModel";
@@ -43,7 +45,7 @@ export class ModuleUtil {
static addViewUiAsync<T extends CCVMParentComp | CCComp>(
ent: ecs.Entity,
ctor: __private.__types_globals__Constructor<T> | __private.__types_globals__AbstractedConstructor<T>,
uiId: number,
uiId: number | UIConfig,
uiArgs: any = null): Promise<Node | null> {
return new Promise<Node | null>((resolve, reject) => {
const uic: UICallbacks = {
@@ -88,7 +90,7 @@ export class ModuleUtil {
* @param isDestroy 是否释放界面缓存(默认为释放界面缓存)
* @param onRemoved 窗口关闭完成事件
*/
static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: number, isDestroy: boolean = true, onRemoved?: Function) {
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();