优化聚焦强类型事件方法命名规范调整,核心改动为:废弃原有基于重载区分事件方法的实现方式,统一采用语义化、独立化的方法命名规则。适配 AI 自动生成代码的理解与解析逻辑

This commit is contained in:
dgflash
2026-04-05 09:19:31 +08:00
parent da020de1ff
commit 421c7db39e
2 changed files with 332 additions and 335 deletions

View File

@@ -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();
}
}

View File

@@ -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();