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:
@@ -17,6 +17,12 @@ export namespace gui {
|
||||
export namespace internal {
|
||||
/** 界面唯一标记变量名 */
|
||||
export const GUI_KEY = "OOPS_GUI_KEY";
|
||||
|
||||
/** 获取界面唯一关键字 */
|
||||
export function getKey(ctor: any) {
|
||||
return ctor[GUI_KEY];
|
||||
}
|
||||
|
||||
/** 获取界面组件配置 */
|
||||
export function getConfig(key: string) {
|
||||
return configs[key];
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Camera, Node, ResolutionPolicy, SafeArea, screen, view, warn } from "cc";
|
||||
import { resLoader } from "../../common/loader/ResLoader";
|
||||
import { oops } from "../../Oops";
|
||||
import { gui } from "../Gui";
|
||||
import { LayerDialog } from "./LayerDialog";
|
||||
@@ -260,6 +259,23 @@ export class LayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理指定界面的缓存
|
||||
* @param uiid 窗口唯一标识
|
||||
* @example
|
||||
* oops.gui.removeCache(UIID.Loading);
|
||||
*/
|
||||
removeCache(uiid: Uiid) {
|
||||
let info = this.getInfo(uiid);
|
||||
let layer = this.uiLayers.get(info.config.layer);
|
||||
if (layer) {
|
||||
layer.removeCache(info.config.prefab);
|
||||
}
|
||||
else {
|
||||
console.error(`移除编号为【${uiid}】的界面失败,界面层不存在`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过界面节点移除
|
||||
* @param node 窗口节点
|
||||
|
||||
@@ -17,19 +17,13 @@ export class LayerPopUp extends LayerUI {
|
||||
/** 半透明遮罩资源 */
|
||||
protected mask!: Node;
|
||||
|
||||
constructor(name: string) {
|
||||
super(name);
|
||||
|
||||
this.on(Node.EventType.CHILD_ADDED, this.onChildAdded, this);
|
||||
this.on(Node.EventType.CHILD_REMOVED, this.onChildRemoved, this);
|
||||
}
|
||||
|
||||
private onChildAdded(child: Node) {
|
||||
protected onChildAdded(child: Node) {
|
||||
this.mask.setSiblingIndex(this.children.length - 2);
|
||||
}
|
||||
|
||||
private onChildRemoved(child: Node) {
|
||||
protected onChildRemoved(child: Node) {
|
||||
this.mask.setSiblingIndex(this.children.length - 2);
|
||||
super.onChildRemoved(child);
|
||||
}
|
||||
|
||||
protected uiInit(state: UIState): Promise<boolean> {
|
||||
|
||||
@@ -23,6 +23,20 @@ export class LayerUI extends Node {
|
||||
constructor(name: string) {
|
||||
super(name);
|
||||
LayerHelper.setFullScreen(this);
|
||||
|
||||
this.on(Node.EventType.CHILD_ADDED, this.onChildAdded, this);
|
||||
this.on(Node.EventType.CHILD_REMOVED, this.onChildRemoved, this);
|
||||
}
|
||||
|
||||
protected onChildAdded(child: Node) {
|
||||
|
||||
}
|
||||
|
||||
protected onChildRemoved(child: Node) {
|
||||
const comp = child.getComponent(LayerUIElement);
|
||||
if (comp) {
|
||||
this.closeUi(comp.state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,8 +88,9 @@ export class LayerUI extends Node {
|
||||
protected async load(state: UIState): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
// 加载界面资源超时提示
|
||||
let timerId = setTimeout(this.onLoadingTimeoutGui, oops.config.game.loadingTimeoutGui);
|
||||
if (state.node == null) {
|
||||
let timerId = setTimeout(this.onLoadingTimeoutGui, oops.config.game.loadingTimeoutGui);
|
||||
|
||||
// 优先加载配置的指定资源包中资源,如果没配置则加载默认资源包资源
|
||||
const res = await resLoader.loadAsync(state.config.bundle!, state.config.prefab, Prefab);
|
||||
if (res) {
|
||||
@@ -92,14 +107,13 @@ export class LayerUI extends Node {
|
||||
console.warn(`路径为【${state.config.prefab}】的预制加载失败`);
|
||||
this.failure(state);
|
||||
}
|
||||
|
||||
// 关闭界面资源超时提示
|
||||
oops.gui.waitClose();
|
||||
clearTimeout(timerId);
|
||||
}
|
||||
|
||||
// 关闭界面资源超时提示
|
||||
oops.gui.waitClose();
|
||||
clearTimeout(timerId);
|
||||
|
||||
await this.uiInit(state);
|
||||
|
||||
resolve(state.node);
|
||||
});
|
||||
}
|
||||
@@ -157,40 +171,30 @@ export class LayerUI extends Node {
|
||||
release = state.config.destroy !== undefined ? state.config.destroy : true;
|
||||
|
||||
// 不释放界面,缓存起来待下次使用
|
||||
if (release === false) {
|
||||
this.ui_cache.set(state.config.prefab, state);
|
||||
}
|
||||
if (release === false) this.ui_cache.set(state.config.prefab, state);
|
||||
|
||||
const node = state.node;
|
||||
const comp = node.getComponent(LayerUIElement)!;
|
||||
const comp = state.node.getComponent(LayerUIElement)!;
|
||||
comp.remove(release);
|
||||
}
|
||||
|
||||
// 清理界面缓存
|
||||
const cache = this.ui_cache.get(prefabPath);
|
||||
if (cache) {
|
||||
// 验证是否删除后台缓存界面
|
||||
if (release) this.removeCache(prefabPath);
|
||||
}
|
||||
// 验证是否删除后台缓存界面
|
||||
if (release) this.removeCache(prefabPath);
|
||||
}
|
||||
|
||||
/** 删除缓存的界面,当缓存界面被移除舞台时,可通过此方法删除缓存界面 */
|
||||
private removeCache(prefabPath: string) {
|
||||
let vp = this.ui_cache.get(prefabPath);
|
||||
if (vp) {
|
||||
this.closeUi(vp);
|
||||
removeCache(prefabPath: string) {
|
||||
const state = this.ui_cache.get(prefabPath);
|
||||
if (state) {
|
||||
this.ui_cache.delete(prefabPath);
|
||||
const node = vp.node;
|
||||
const comp = node.getComponent(LayerUIElement)!;
|
||||
const comp = state.node.getComponent(LayerUIElement)!;
|
||||
comp.remove(true);
|
||||
node.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/** 显示界面 */
|
||||
show(prefabPath: string) {
|
||||
const vp = this.ui_nodes.get(prefabPath);
|
||||
if (vp) vp.node.parent = this;
|
||||
const state = this.ui_nodes.get(prefabPath);
|
||||
if (state) state.node.parent = this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,8 +202,8 @@ export class LayerUI extends Node {
|
||||
* @param prefabPath 预制路径
|
||||
*/
|
||||
get(prefabPath: string): Node {
|
||||
const vp = this.ui_nodes.get(prefabPath);
|
||||
if (vp) return vp.node;
|
||||
const state = this.ui_nodes.get(prefabPath);
|
||||
if (state) return state.node;
|
||||
return null!;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,10 +73,6 @@ export class LayerUIElement extends Component {
|
||||
this.state.params.onRemoved(this.node, this.state.params.data);
|
||||
}
|
||||
|
||||
// 关闭动画播放完后,界面移除舞台
|
||||
//@ts-ignore
|
||||
this.node.parent.closeUi(this.state);
|
||||
|
||||
// 关闭动画播放完后,界面移除舞台事件
|
||||
this.onClose && this.onClose();
|
||||
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
import { Label, _decorator } from "cc";
|
||||
import { EDITOR } from "cc/env";
|
||||
import { oops } from "../../../core/Oops";
|
||||
import { EventMessage } from "../../../core/common/event/EventMessage";
|
||||
import { TimeUtil } from "../../../core/utils/TimeUtils";
|
||||
import { EDITOR } from "cc/env";
|
||||
|
||||
const { ccclass, property, menu } = _decorator;
|
||||
|
||||
/** 倒计时标签 */
|
||||
@ccclass("LabelTime")
|
||||
@menu('OopsFramework/Label/LabelTime (倒计时标签)')
|
||||
@menu("OopsFramework/Label/LabelTime (倒计时标签)")
|
||||
export default class LabelTime extends Label {
|
||||
@property({
|
||||
tooltip: "到计时间总时间(单位秒)"
|
||||
tooltip: "到计时间总时间(单位秒)",
|
||||
})
|
||||
countDown: number = 1000;
|
||||
|
||||
@property({
|
||||
tooltip: "天数数据格式化"
|
||||
tooltip: "天数数据格式化",
|
||||
})
|
||||
dayFormat: string = "{0} day";
|
||||
|
||||
@property({
|
||||
tooltip: "时间格式化"
|
||||
tooltip: "时间格式化",
|
||||
})
|
||||
timeFormat: string = "{0}:{1}:{2}";
|
||||
|
||||
@property({
|
||||
tooltip: "是否有00"
|
||||
tooltip: "是否有00",
|
||||
})
|
||||
zeroize: boolean = true;
|
||||
|
||||
@@ -35,9 +35,9 @@ export default class LabelTime extends Label {
|
||||
})
|
||||
paused: boolean = false;
|
||||
|
||||
private backStartTime: number = 0; // 进入后台开始时间
|
||||
private dateDisable!: boolean; // 时间能否由天数显示
|
||||
private result!: string; // 时间结果字符串
|
||||
private backStartTime: number = 0; // 进入后台开始时间
|
||||
private dateDisable!: boolean; // 时间能否由天数显示
|
||||
private result!: string; // 时间结果字符串
|
||||
|
||||
/** 每秒触发事件 */
|
||||
onSecond: Function = null!;
|
||||
@@ -45,10 +45,9 @@ export default class LabelTime extends Label {
|
||||
onComplete: Function = null!;
|
||||
|
||||
private replace(value: string, ...args: any): string {
|
||||
return value.replace(/\{(\d+)\}/g,
|
||||
function (m, i) {
|
||||
return args[i];
|
||||
});
|
||||
return value.replace(/\{(\d+)\}/g, function (m, i) {
|
||||
return args[i];
|
||||
});
|
||||
}
|
||||
|
||||
/** 格式化字符串 */
|
||||
@@ -84,23 +83,15 @@ export default class LabelTime extends Label {
|
||||
if (date < 2) {
|
||||
df = df.replace("days", "day");
|
||||
}
|
||||
this.result = this.replace(df, date, hours); // 如果天大于1,则显示 "1 Day..."
|
||||
this.result = this.replace(df, date, hours); // 如果天大于1,则显示 "1 Day..."
|
||||
}
|
||||
else {
|
||||
hours += date * 24;
|
||||
if (this.zeroize) {
|
||||
this.result = this.replace(
|
||||
this.timeFormat,
|
||||
this.coverString(hours),
|
||||
this.coverString(minutes),
|
||||
this.coverString(seconds)); // 否则显示 "01:12:24"
|
||||
this.result = this.replace(this.timeFormat, this.coverString(hours), this.coverString(minutes), this.coverString(seconds)); // 否则显示 "01:12:24"
|
||||
}
|
||||
else {
|
||||
this.result = this.replace(
|
||||
this.timeFormat,
|
||||
hours,
|
||||
minutes,
|
||||
seconds);
|
||||
this.result = this.replace(this.timeFormat, hours, minutes, seconds);
|
||||
}
|
||||
}
|
||||
this.string = this.result;
|
||||
@@ -108,8 +99,7 @@ export default class LabelTime extends Label {
|
||||
|
||||
/** 个位数的时间数据将字符串补位 */
|
||||
private coverString(value: number) {
|
||||
if (value < 10)
|
||||
return "0" + value;
|
||||
if (value < 10) return "0" + value;
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@@ -123,7 +113,7 @@ export default class LabelTime extends Label {
|
||||
* @param second 倒计时时间(单位秒)
|
||||
*/
|
||||
setTime(second: number) {
|
||||
this.countDown = second; // 倒计时,初始化显示字符串
|
||||
this.countDown = second; // 倒计时,初始化显示字符串
|
||||
this.timing_end();
|
||||
this.timing_start();
|
||||
this.format();
|
||||
@@ -140,15 +130,33 @@ export default class LabelTime extends Label {
|
||||
this.format();
|
||||
}
|
||||
|
||||
start() {
|
||||
onLoad() {
|
||||
if (!EDITOR) {
|
||||
oops.message.on(EventMessage.GAME_SHOW, this.onGameShow, this);
|
||||
oops.message.on(EventMessage.GAME_HIDE, this.onGameHide, this);
|
||||
}
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.countDown <= 0) return;
|
||||
this.timing_start();
|
||||
this.format();
|
||||
}
|
||||
|
||||
onEnable() {
|
||||
super.onEnable();
|
||||
if (!EDITOR) {
|
||||
this.onGameShow();
|
||||
}
|
||||
}
|
||||
|
||||
onDisable() {
|
||||
super.onDisable();
|
||||
if (!EDITOR) {
|
||||
this.onGameHide();
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
if (!EDITOR) {
|
||||
oops.message.off(EventMessage.GAME_SHOW, this.onGameShow, this);
|
||||
@@ -175,6 +183,12 @@ export default class LabelTime extends Label {
|
||||
}
|
||||
|
||||
private onScheduleSecond() {
|
||||
if (this.countDown == 0) {
|
||||
this.format();
|
||||
this.onScheduleComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
this.countDown--;
|
||||
this.format();
|
||||
if (this.onSecond) this.onSecond(this.node);
|
||||
@@ -187,15 +201,17 @@ export default class LabelTime extends Label {
|
||||
private onScheduleComplete() {
|
||||
this.timing_end();
|
||||
this.format();
|
||||
this.unschedule(this.onScheduleSecond);
|
||||
if (this.onComplete) this.onComplete(this.node);
|
||||
}
|
||||
|
||||
/** 开始计时 */
|
||||
private timing_start() {
|
||||
timing_start() {
|
||||
this.schedule(this.onScheduleSecond, 1);
|
||||
}
|
||||
|
||||
private timing_end() {
|
||||
/** 关闭计时 */
|
||||
timing_end() {
|
||||
this.unscheduleAllCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,7 @@ export class CCEntity extends ecs.Entity {
|
||||
*/
|
||||
addUi<T extends CCVMParentComp | CCComp>(ctor: ECSCtor<T>, params?: UIParam): Promise<Node> {
|
||||
return new Promise<Node>(async (resolve, reject) => {
|
||||
//@ts-ignore
|
||||
const key = ctor[gui.internal.GUI_KEY];
|
||||
const key = gui.internal.getKey(ctor);
|
||||
if (key) {
|
||||
if (params == null) {
|
||||
params = { preload: true };
|
||||
@@ -62,8 +61,7 @@ export class CCEntity extends ecs.Entity {
|
||||
* @param ctor 界面逻辑组件
|
||||
*/
|
||||
removeUi(ctor: CompType<ecs.IComp>) {
|
||||
//@ts-ignore
|
||||
const key = ctor[gui.internal.GUI_KEY];
|
||||
const key = gui.internal.getKey(ctor);
|
||||
if (key) {
|
||||
const node = oops.gui.get(key);
|
||||
if (node == null) {
|
||||
@@ -73,9 +71,8 @@ export class CCEntity extends ecs.Entity {
|
||||
|
||||
const comp = node.getComponent(LayerUIElement);
|
||||
if (comp) {
|
||||
comp.onClose = () => {
|
||||
if (comp.state.config.destroy) this.remove(ctor);
|
||||
};
|
||||
// 处理界面关闭动画播放完成后,移除ECS组件,避免使用到组件实体数据还在动画播放时在使用导致的空对象问题
|
||||
comp.onClose = this.remove.bind(this, ctor);
|
||||
oops.gui.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user