mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-05-30 18:39:18 +08:00
优化聚焦强类型事件方法命名规范调整,核心改动为:废弃原有基于重载区分事件方法的实现方式,统一采用语义化、独立化的方法命名规则。适配 AI 自动生成代码的理解与解析逻辑
This commit is contained in:
@@ -1,185 +1,182 @@
|
||||
import type { ListenerFunc, ListenerFuncTyped } from './EventMessage';
|
||||
import type { TypedEventMap } from './MessageManager';
|
||||
import { EventData } from './EventData';
|
||||
import { EventDataPool } from './EventDataPool';
|
||||
import { message } from './MessageManager';
|
||||
|
||||
/** 批量注册、移除全局事件对象(用于组件级事件管理) */
|
||||
export class EventDispatcher {
|
||||
/** 本地事件列表,用于批量清理 */
|
||||
private events: Map<string, Array<EventData>> = new Map();
|
||||
|
||||
/**
|
||||
* 注册全局事件(强类型)
|
||||
* @param event 事件名(枚举)
|
||||
* @param listener 处理事件的侦听器函数
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
on<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void;
|
||||
|
||||
/**
|
||||
* 注册全局事件(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
on(event: string, listener: ListenerFunc, object: object): void;
|
||||
|
||||
/**
|
||||
* 注册全局事件(实现)
|
||||
*/
|
||||
on(event: string, listener: ListenerFunc, object: object): void {
|
||||
// 先注册到全局消息管理器
|
||||
message.on(event, listener, object);
|
||||
|
||||
// 记录到本地事件列表,用于批量清理
|
||||
let eds = this.events.get(event);
|
||||
if (eds == null) {
|
||||
eds = [];
|
||||
this.events.set(event, eds);
|
||||
}
|
||||
|
||||
const ed: EventData = EventDataPool.get();
|
||||
ed.event = event;
|
||||
ed.listener = listener;
|
||||
ed.object = object;
|
||||
eds.push(ed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除(强类型)
|
||||
* @param event 事件名(枚举)
|
||||
* @param listener 事件触发回调方法
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
once<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void;
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param listener 事件触发回调方法
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
once(event: string, listener: ListenerFunc, object: object): void;
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除(实现)
|
||||
*/
|
||||
once(event: string, listener: ListenerFunc, object: object): void {
|
||||
message.once(event, listener, object);
|
||||
|
||||
// 记录到本地事件列表
|
||||
let eds = this.events.get(event);
|
||||
if (eds == null) {
|
||||
eds = [];
|
||||
this.events.set(event, eds);
|
||||
}
|
||||
|
||||
const ed: EventData = EventDataPool.get();
|
||||
ed.event = event;
|
||||
ed.listener = listener;
|
||||
ed.object = object;
|
||||
eds.push(ed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除全局事件(强类型)
|
||||
* @param event 事件名(枚举)
|
||||
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
|
||||
* @param object 侦听函数绑定的作用域对象(可选)
|
||||
*/
|
||||
off<K extends keyof TypedEventMap>(event: K, listener?: ListenerFuncTyped<K, TypedEventMap[K]>, object?: object): void;
|
||||
|
||||
/**
|
||||
* 移除全局事件(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
|
||||
* @param object 侦听函数绑定的作用域对象(可选)
|
||||
*/
|
||||
off(event: string, listener?: ListenerFunc, object?: object): void;
|
||||
|
||||
/**
|
||||
* 移除全局事件(实现)
|
||||
*/
|
||||
off(event: string, listener?: ListenerFunc, object?: object): void {
|
||||
const eds = this.events.get(event);
|
||||
if (!eds) return;
|
||||
|
||||
// 如果没有指定 listener,移除该事件的所有监听器
|
||||
if (!listener) {
|
||||
for (const eb of eds) {
|
||||
message.off(event, eb.listener, eb.object);
|
||||
EventDataPool.put(eb);
|
||||
}
|
||||
this.events.delete(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除指定的监听器
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const eb = eds[i];
|
||||
if (eb.listener == listener && eb.object == object) {
|
||||
message.off(event, eb.listener, eb.object);
|
||||
EventDataPool.put(eb);
|
||||
eds.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果该事件已无监听器,删除事件
|
||||
if (eds.length == 0) {
|
||||
this.events.delete(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
*/
|
||||
|
||||
dispatchEvent(event: string, ...args: any[]): void {
|
||||
message.dispatchEvent(event, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件,支持同步与异步处理(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
*/
|
||||
|
||||
dispatchEventAsync(event: string, ...args: any[]): Promise<void> {
|
||||
return message.dispatchEventAsync(event, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发强类型事件(严格类型检查)
|
||||
* @param event 事件名(枚举)
|
||||
* @param data 事件数据(必须完全匹配类型定义)
|
||||
*/
|
||||
emit<K extends keyof TypedEventMap>(event: K, data: TypedEventMap[K]): void {
|
||||
message.emit(event, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发强类型异步事件(严格类型检查)
|
||||
* @param event 事件名(枚举)
|
||||
* @param data 事件数据(必须完全匹配类型定义)
|
||||
*/
|
||||
emitAsync<K extends keyof TypedEventMap>(event: K, data: TypedEventMap[K]): Promise<void> {
|
||||
return message.emitAsync(event, data);
|
||||
}
|
||||
|
||||
/** 清除所有的全局事件监听 */
|
||||
clear(): void {
|
||||
// 直接遍历 Map,避免创建临时数组
|
||||
for (const [event, eds] of this.events) {
|
||||
for (const eb of eds) {
|
||||
message.off(event, eb.listener, eb.object);
|
||||
EventDataPool.put(eb);
|
||||
}
|
||||
}
|
||||
this.events.clear();
|
||||
}
|
||||
}
|
||||
import type { ListenerFunc, ListenerFuncTyped } from './EventMessage';
|
||||
import type { TypedEventMap } from './MessageManager';
|
||||
import { EventData } from './EventData';
|
||||
import { EventDataPool } from './EventDataPool';
|
||||
import { message } from './MessageManager';
|
||||
|
||||
/** 批量注册、移除全局事件对象(用于组件级事件管理) */
|
||||
export class EventDispatcher {
|
||||
/** 本地事件列表,用于批量清理 */
|
||||
private events: Map<string, Array<EventData>> = new Map();
|
||||
|
||||
//#region 强类型事件方法
|
||||
|
||||
/**
|
||||
* 注册全局事件(强类型)
|
||||
* @param event 事件名(枚举)
|
||||
* @param listener 处理事件的侦听器函数
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
watch<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void {
|
||||
this.on(event as string, listener as ListenerFunc, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除(强类型)
|
||||
* @param event 事件名(枚举)
|
||||
* @param listener 事件触发回调方法
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
watchOnce<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void {
|
||||
this.once(event as string, listener as ListenerFunc, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除全局事件(强类型)
|
||||
* @param event 事件名(枚举)
|
||||
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
|
||||
* @param object 侦听函数绑定的作用域对象(可选)
|
||||
*/
|
||||
unwatch<K extends keyof TypedEventMap>(event: K, listener?: ListenerFuncTyped<K, TypedEventMap[K]>, object?: object): void {
|
||||
this.off(event as string, listener as ListenerFunc, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发强类型事件(严格类型检查)
|
||||
* @param event 事件名(枚举)
|
||||
* @param data 事件数据(必须完全匹配类型定义)
|
||||
*/
|
||||
emit<K extends keyof TypedEventMap>(event: K, data: TypedEventMap[K]): void {
|
||||
message.emit(event, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发强类型异步事件(严格类型检查)
|
||||
* @param event 事件名(枚举)
|
||||
* @param data 事件数据(必须完全匹配类型定义)
|
||||
*/
|
||||
emitAsync<K extends keyof TypedEventMap>(event: K, data: TypedEventMap[K]): Promise<void> {
|
||||
return message.emitAsync(event, data);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 弱类型事件方法
|
||||
|
||||
/**
|
||||
* 注册全局事件
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
on(event: string, listener: ListenerFunc, object: object): void {
|
||||
// 先注册到全局消息管理器
|
||||
message.on(event, listener, object);
|
||||
|
||||
// 记录到本地事件列表,用于批量清理
|
||||
let eds = this.events.get(event);
|
||||
if (eds == null) {
|
||||
eds = [];
|
||||
this.events.set(event, eds);
|
||||
}
|
||||
|
||||
const ed: EventData = EventDataPool.get();
|
||||
ed.event = event;
|
||||
ed.listener = listener;
|
||||
ed.object = object;
|
||||
eds.push(ed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除
|
||||
* @param event 事件名
|
||||
* @param listener 事件触发回调方法
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
once(event: string, listener: ListenerFunc, object: object): void {
|
||||
message.once(event, listener, object);
|
||||
|
||||
// 记录到本地事件列表
|
||||
let eds = this.events.get(event);
|
||||
if (eds == null) {
|
||||
eds = [];
|
||||
this.events.set(event, eds);
|
||||
}
|
||||
|
||||
const ed: EventData = EventDataPool.get();
|
||||
ed.event = event;
|
||||
ed.listener = listener;
|
||||
ed.object = object;
|
||||
eds.push(ed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除全局事件
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
|
||||
* @param object 侦听函数绑定的作用域对象(可选)
|
||||
*/
|
||||
off(event: string, listener?: ListenerFunc, object?: object): void {
|
||||
const eds = this.events.get(event);
|
||||
if (!eds) return;
|
||||
|
||||
// 如果没有指定 listener,移除该事件的所有监听器
|
||||
if (!listener) {
|
||||
for (const eb of eds) {
|
||||
message.off(event, eb.listener, eb.object);
|
||||
EventDataPool.put(eb);
|
||||
}
|
||||
this.events.delete(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除指定的监听器
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const eb = eds[i];
|
||||
if (eb.listener == listener && eb.object == object) {
|
||||
message.off(event, eb.listener, eb.object);
|
||||
EventDataPool.put(eb);
|
||||
eds.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果该事件已无监听器,删除事件
|
||||
if (eds.length == 0) {
|
||||
this.events.delete(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
*/
|
||||
dispatchEvent(event: string, ...args: any[]): void {
|
||||
message.dispatchEvent(event, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件,支持同步与异步处理
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
*/
|
||||
dispatchEventAsync(event: string, ...args: any[]): Promise<void> {
|
||||
return message.dispatchEventAsync(event, ...args);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
/** 清除所有的全局事件监听 */
|
||||
clear(): void {
|
||||
// 直接遍历 Map,避免创建临时数组
|
||||
for (const [event, eds] of this.events) {
|
||||
for (const eb of eds) {
|
||||
message.off(event, eb.listener, eb.object);
|
||||
EventDataPool.put(eb);
|
||||
}
|
||||
}
|
||||
this.events.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ export interface TypedEventMap {
|
||||
// 业务层通过 declare module 扩展此接口
|
||||
}
|
||||
|
||||
/** 获取 TypedEventMap 中所有事件 key 的联合类型 */
|
||||
export type EventMapKeys = keyof TypedEventMap;
|
||||
|
||||
/**
|
||||
* 全局消息管理
|
||||
*
|
||||
@@ -42,53 +45,16 @@ export interface TypedEventMap {
|
||||
export class MessageManager {
|
||||
private events: Map<string, Array<EventData>> = new Map();
|
||||
|
||||
//#region 强类型事件方法(提供给 Agent 自动生成用)
|
||||
|
||||
/**
|
||||
* 注册全局事件(强类型)
|
||||
* @param event 事件名(枚举)
|
||||
* @param listener 处理事件的侦听器函数
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
on<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void;
|
||||
|
||||
/**
|
||||
* 注册全局事件(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
on(event: string, listener: ListenerFunc, object: object): void;
|
||||
|
||||
/**
|
||||
* 注册全局事件(实现)
|
||||
*/
|
||||
on(event: string, listener: ListenerFunc, object: object): void {
|
||||
if (!event || !listener) {
|
||||
warn(`注册【${event}】事件的侦听器函数为空`);
|
||||
return;
|
||||
}
|
||||
|
||||
let eds = this.events.get(event);
|
||||
if (eds == null) {
|
||||
eds = [];
|
||||
this.events.set(event, eds);
|
||||
}
|
||||
|
||||
// 检查重复注册,如果已存在则直接返回,避免重复添加
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const bin = eds[i];
|
||||
if (bin.listener == listener && bin.object == object) {
|
||||
warn(`名为【${event}】的事件重复注册侦听器`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 从对象池获取 EventData 对象
|
||||
const data: EventData = EventDataPool.get();
|
||||
data.event = event;
|
||||
data.listener = listener;
|
||||
data.object = object;
|
||||
eds.push(data);
|
||||
watch<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void {
|
||||
this.on(event as string, listener as ListenerFunc, object);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,25 +63,8 @@ export class MessageManager {
|
||||
* @param listener 事件触发回调方法
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
once<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void;
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param listener 事件触发回调方法
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
once(event: string, listener: ListenerFunc, object: object): void;
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除(实现)
|
||||
*/
|
||||
once(event: string, listener: ListenerFunc, object: object): void {
|
||||
const _listener: any = ($event: string, ...$args: any[]) => {
|
||||
this.off(event, _listener, object);
|
||||
listener.call(object, $event, ...$args);
|
||||
};
|
||||
this.on(event, _listener, object);
|
||||
watchOnce<K extends keyof TypedEventMap>(event: K, listener: ListenerFuncTyped<K, TypedEventMap[K]>, object: object): void {
|
||||
this.once(event as string, listener as ListenerFunc, object);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,96 +73,8 @@ export class MessageManager {
|
||||
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
|
||||
* @param object 侦听函数绑定的作用域对象(可选)
|
||||
*/
|
||||
off<K extends keyof TypedEventMap>(event: K, listener?: ListenerFuncTyped<K, TypedEventMap[K]>, object?: object): void;
|
||||
|
||||
/**
|
||||
* 移除全局事件(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
|
||||
* @param object 侦听函数绑定的作用域对象(可选)
|
||||
*/
|
||||
off(event: string, listener?: Function, object?: object): void;
|
||||
|
||||
/**
|
||||
* 移除全局事件(实现)
|
||||
*/
|
||||
off(event: string, listener?: Function, object?: object): void {
|
||||
const eds = this.events.get(event);
|
||||
|
||||
if (!eds) {
|
||||
log(`名为【${event}】的事件不存在`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果没有指定 listener,移除该事件的所有监听器
|
||||
if (!listener) {
|
||||
for (const bin of eds) {
|
||||
EventDataPool.put(bin);
|
||||
}
|
||||
this.events.delete(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除指定的监听器
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const bin: EventData = eds[i];
|
||||
if (bin.listener == listener && bin.object == object) {
|
||||
EventDataPool.put(bin);
|
||||
eds.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (eds.length == 0) {
|
||||
this.events.delete(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
* @note 使用 concat() 创建数组副本,防止在事件回调中添加/删除监听器时影响遍历
|
||||
*/
|
||||
|
||||
dispatchEvent(event: string, ...args: any[]): void {
|
||||
const list = this.events.get(event);
|
||||
if (list != null) {
|
||||
const eds: Array<EventData> = list.concat();
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const ed = eds[i];
|
||||
ed.listener.call(ed.object, event, ...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件,支持同步与异步处理(兼容旧用法)
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
* @note 使用 concat() 创建数组副本,防止在事件回调中添加/删除监听器时影响遍历
|
||||
*/
|
||||
|
||||
dispatchEventAsync(event: string, ...args: any[]): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
const list = this.events.get(event);
|
||||
if (list != null) {
|
||||
const eds: Array<EventData> = list.concat();
|
||||
const length = eds.length;
|
||||
(async () => {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const ed = eds[i];
|
||||
await Promise.resolve(ed.listener.call(ed.object, event, ...args));
|
||||
}
|
||||
resolve();
|
||||
})();
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
unwatch<K extends keyof TypedEventMap>(event: K, listener?: ListenerFuncTyped<K, TypedEventMap[K]>, object?: object): void {
|
||||
this.off(event as string, listener as ListenerFunc, object);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,6 +120,145 @@ export class MessageManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 弱类型事件方法
|
||||
|
||||
/**
|
||||
* 注册全局事件
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
on(event: string, listener: ListenerFunc, object: object): void {
|
||||
if (!event || !listener) {
|
||||
warn(`注册【${event}】事件的侦听器函数为空`);
|
||||
return;
|
||||
}
|
||||
|
||||
let eds = this.events.get(event);
|
||||
if (eds == null) {
|
||||
eds = [];
|
||||
this.events.set(event, eds);
|
||||
}
|
||||
|
||||
// 检查重复注册,如果已存在则直接返回,避免重复添加
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const bin = eds[i];
|
||||
if (bin.listener == listener && bin.object == object) {
|
||||
warn(`名为【${event}】的事件重复注册侦听器`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 从对象池获取 EventData 对象
|
||||
const data: EventData = EventDataPool.get();
|
||||
data.event = event;
|
||||
data.listener = listener;
|
||||
data.object = object;
|
||||
eds.push(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听一次事件,事件响应后,该监听自动移除
|
||||
* @param event 事件名
|
||||
* @param listener 事件触发回调方法
|
||||
* @param object 侦听函数绑定的作用域对象
|
||||
*/
|
||||
once(event: string, listener: ListenerFunc, object: object): void {
|
||||
const _listener: any = ($event: string, ...$args: any[]) => {
|
||||
this.off(event, _listener, object);
|
||||
listener.call(object, $event, ...$args);
|
||||
};
|
||||
this.on(event, _listener, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除全局事件
|
||||
* @param event 事件名
|
||||
* @param listener 处理事件的侦听器函数(可选,不传则移除该事件的所有监听器)
|
||||
* @param object 侦听函数绑定的作用域对象(可选)
|
||||
*/
|
||||
off(event: string, listener?: Function, object?: object): void {
|
||||
const eds = this.events.get(event);
|
||||
|
||||
if (!eds) {
|
||||
log(`名为【${event}】的事件不存在`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果没有指定 listener,移除该事件的所有监听器
|
||||
if (!listener) {
|
||||
for (const bin of eds) {
|
||||
EventDataPool.put(bin);
|
||||
}
|
||||
this.events.delete(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除指定的监听器
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const bin: EventData = eds[i];
|
||||
if (bin.listener == listener && bin.object == object) {
|
||||
EventDataPool.put(bin);
|
||||
eds.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (eds.length == 0) {
|
||||
this.events.delete(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
* @note 使用 concat() 创建数组副本,防止在事件回调中添加/删除监听器时影响遍历
|
||||
*/
|
||||
dispatchEvent(event: string, ...args: any[]): void {
|
||||
const list = this.events.get(event);
|
||||
if (list != null) {
|
||||
const eds: Array<EventData> = list.concat();
|
||||
const length = eds.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const ed = eds[i];
|
||||
ed.listener.call(ed.object, event, ...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发全局事件,支持同步与异步处理
|
||||
* @param event 事件名
|
||||
* @param args 事件参数
|
||||
* @note 使用 concat() 创建数组副本,防止在事件回调中添加/删除监听器时影响遍历
|
||||
*/
|
||||
dispatchEventAsync(event: string, ...args: any[]): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
const list = this.events.get(event);
|
||||
if (list != null) {
|
||||
const eds: Array<EventData> = list.concat();
|
||||
const length = eds.length;
|
||||
(async () => {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const ed = eds[i];
|
||||
await Promise.resolve(ed.listener.call(ed.object, event, ...args));
|
||||
}
|
||||
resolve();
|
||||
})();
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
export const message = new MessageManager();
|
||||
|
||||
Reference in New Issue
Block a user