修复提示系统加载与 RichText 兼容问题

1. 统一提示预制路径为 UI_Notify/UI_Wait/UI_Mask
2. LayerNotify 统一异步加载并支持模板克隆
3. LanguageLabel 兼容 RichText 模块未启用场景
This commit is contained in:
dgflash
2026-06-19 13:26:40 +08:00
parent 6cdce6eeee
commit 2acc9bd7e8
7 changed files with 72 additions and 46 deletions

View File

@@ -16,7 +16,11 @@ export class EventDispatcher {
* @param listener 处理事件的侦听器函数
* @param object 侦听函数绑定的作用域对象
*/
watch<K extends keyof OopsFramework.TypedEventMap>(event: K, listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>, object: object): void {
watch<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object: object
): void {
this.on(event as string, listener as ListenerFunc, object);
}
@@ -26,7 +30,11 @@ export class EventDispatcher {
* @param listener 事件触发回调方法
* @param object 侦听函数绑定的作用域对象
*/
watchOnce<K extends keyof OopsFramework.TypedEventMap>(event: K, listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>, object: object): void {
watchOnce<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object: object
): void {
this.once(event as string, listener as ListenerFunc, object);
}
@@ -36,7 +44,11 @@ export class EventDispatcher {
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
* @param object 侦听函数绑定的作用域对象(可选)
*/
unwatch<K extends keyof OopsFramework.TypedEventMap>(event: K, listener?: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>, object?: object): void {
unwatch<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener?: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object?: object
): void {
this.off(event as string, listener as ListenerFunc, object);
}
@@ -54,7 +66,10 @@ export class EventDispatcher {
* @param event 事件名(枚举)
* @param data 事件数据(必须完全匹配类型定义)
*/
emitAsync<K extends keyof OopsFramework.TypedEventMap>(event: K, data: OopsFramework.TypedEventMap[K]): Promise<void> {
emitAsync<K extends keyof OopsFramework.TypedEventMap>(
event: K,
data?: OopsFramework.TypedEventMap[K]
): Promise<void> {
return message.emitAsync(event, data);
}

View File

@@ -33,7 +33,11 @@ export class MessageManager {
* @param listener 处理事件的侦听器函数
* @param object 侦听函数绑定的作用域对象
*/
watch<K extends keyof OopsFramework.TypedEventMap>(event: K, listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>, object: object): void {
watch<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object: object
): void {
this.on(event as string, listener as ListenerFunc, object);
}
@@ -43,7 +47,11 @@ export class MessageManager {
* @param listener 事件触发回调方法
* @param object 侦听函数绑定的作用域对象
*/
watchOnce<K extends keyof OopsFramework.TypedEventMap>(event: K, listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>, object: object): void {
watchOnce<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object: object
): void {
this.once(event as string, listener as ListenerFunc, object);
}
@@ -53,7 +61,11 @@ export class MessageManager {
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
* @param object 侦听函数绑定的作用域对象(可选)
*/
unwatch<K extends keyof OopsFramework.TypedEventMap>(event: K, listener?: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>, object?: object): void {
unwatch<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener?: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object?: object
): void {
this.off(event as string, listener as ListenerFunc, object);
}
@@ -81,8 +93,11 @@ export class MessageManager {
* @param data 事件数据(必须完全匹配类型定义)
* @note 使用此方法可获得编译时的强类型约束,参数不匹配会编译报错
*/
emitAsync<K extends keyof OopsFramework.TypedEventMap>(event: K, data: OopsFramework.TypedEventMap[K]): Promise<void> {
return new Promise((resolve) => {
emitAsync<K extends keyof OopsFramework.TypedEventMap>(
event: K,
data?: OopsFramework.TypedEventMap[K]
): Promise<void> {
return new Promise(resolve => {
const list = this.events.get(event as string);
if (list != null) {
const eds: Array<EventData> = list.concat();
@@ -94,8 +109,7 @@ export class MessageManager {
}
resolve();
})();
}
else {
} else {
resolve();
}
});
@@ -219,7 +233,7 @@ export class MessageManager {
* @note 使用 concat() 创建数组副本,防止在事件回调中添加/删除监听器时影响遍历
*/
dispatchEventAsync(event: string, ...args: any[]): Promise<void> {
return new Promise((resolve) => {
return new Promise(resolve => {
const list = this.events.get(event);
if (list != null) {
const eds: Array<EventData> = list.concat();
@@ -231,8 +245,7 @@ export class MessageManager {
}
resolve();
})();
}
else {
} else {
resolve();
}
});

View File

@@ -8,9 +8,9 @@ export const GuiPromptConfig: {
Mask: { bundle: string; path: string };
} = {
/** 飘动提示 */
Notify: { bundle: 'game_common', path: 'gui/window/prefab/notify' },
Notify: { bundle: 'game_common', path: 'gui/window/prefab/UI_Notify' },
/** 延迟等待提示 */
Wait: { bundle: 'game_common', path: 'gui/window/prefab/wait' },
Wait: { bundle: 'game_common', path: 'gui/window/prefab/UI_Wait' },
/** 遮罩层 */
Mask: { bundle: 'game_common', path: 'gui/window/prefab/mask' },
Mask: { bundle: 'game_common', path: 'gui/window/prefab/UI_Mask' },
};

View File

@@ -33,15 +33,10 @@ export class LayerNotify extends Node {
try {
if (this.wait == null) {
// 兼容编辑器预览模式
if (EDITOR) {
this.wait = await ViewUtil.createPrefabNodeAsync(
GuiPromptConfig.Wait.path,
GuiPromptConfig.Wait.bundle
);
} else {
this.wait = ViewUtil.createPrefabNode(GuiPromptConfig.Wait.path, GuiPromptConfig.Wait.bundle);
}
this.wait = await ViewUtil.createPrefabNodeAsync(
GuiPromptConfig.Wait.path,
GuiPromptConfig.Wait.bundle
);
}
// 异步操作完成后,检查是否已被请求关闭
@@ -87,23 +82,26 @@ export class LayerNotify extends Node {
*/
async toast(content: string, useI18n: boolean) {
if (this.notify == null) {
this.notify = await ViewUtil.createPrefabNodeAsync(GuiPromptConfig.Notify.path, GuiPromptConfig.Notify.bundle);
this.notify = await ViewUtil.createPrefabNodeAsync(
GuiPromptConfig.Notify.path,
GuiPromptConfig.Notify.bundle
);
this.notifyItem = this.notify.children[0];
this.notifyItem.parent = null;
}
this.notify.parent = this;
const childNode = instantiate(this.notifyItem);
const prompt = childNode.getChildByName('prompt')!;
const toastCom = prompt.getComponent(Notify)!;
childNode.parent = this.notify;
const item = instantiate(this.notifyItem);
const prompt = item.getChildByName('prompt')!;
const notify = prompt.getComponent(Notify)!;
item.parent = this.notify;
toastCom.onComplete = () => {
if (this.notify.children.length == 0) {
notify.onComplete = () => {
if (this.notify.children.length <= 1) {
this.notify.parent = null;
}
};
toastCom.toast(content, useI18n);
notify.toast(content, useI18n);
// 超过3个提示就释放第一个提示
if (this.notify.children.length > 3) {

View File

@@ -16,8 +16,7 @@ export class Notify extends Component {
onComplete: Function = null!;
onLoad() {
if (this.animation)
this.animation.on(Animation.EventType.FINISHED, this.onFinished, this);
this.animation.on(Animation.EventType.FINISHED, this.onFinished, this);
}
private onFinished() {
@@ -36,8 +35,7 @@ export class Notify extends Component {
if (useI18n) {
label.enabled = true;
label.dataID = msg;
}
else {
} else {
label.enabled = false;
this.lab_content.string = msg;
}

View File

@@ -89,9 +89,9 @@ export class LanguageLabel extends Component {
/** 初始化并缓存组件引用 */
private _initComponents() {
if (this._componentInitialized) return;
this._labelCache = this.getComponent(Label);
this._richTextCache = this.getComponent(RichText);
this._richTextCache = RichText ? this.getComponent(RichText) : null;
this._componentInitialized = true;
if (!this._labelCache && !this._richTextCache) {

View File

@@ -22,7 +22,7 @@ export class GamePartEvent extends GamePartBase {
watch<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object: object,
object: object
): void {
this.event.on(event as string, listener as ListenerFunc, object);
}
@@ -35,7 +35,7 @@ export class GamePartEvent extends GamePartBase {
watchOnce<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object: object,
object: object
): void {
this.event.once(event as string, listener as ListenerFunc, object);
}
@@ -48,7 +48,7 @@ export class GamePartEvent extends GamePartBase {
unwatch<K extends keyof OopsFramework.TypedEventMap>(
event: K,
listener?: ListenerFuncTyped<K, OopsFramework.TypedEventMap[K]>,
object?: object,
object?: object
): void {
this.event.off(event as string, listener as ListenerFunc, object);
}
@@ -65,7 +65,10 @@ export class GamePartEvent extends GamePartBase {
* @param event 事件类型
* @param data 事件数据
*/
emitAsync<K extends keyof OopsFramework.TypedEventMap>(event: K, data: OopsFramework.TypedEventMap[K]): Promise<void> {
emitAsync<K extends keyof OopsFramework.TypedEventMap>(
event: K,
data?: OopsFramework.TypedEventMap[K]
): Promise<void> {
return this.event.emitAsync(event, data);
}
@@ -124,8 +127,7 @@ export class GamePartEvent extends GamePartBase {
const func = self[name];
if (func) {
this.on(name, func, this.comp);
}
else {
} else {
console.error(`名为【${name}】的全局事方法不存在`);
}
}