事件模块分这个文件管理代码

This commit is contained in:
dgflash
2026-02-20 15:22:53 +08:00
parent eaaa4afc28
commit 7318e824cb
8 changed files with 173 additions and 131 deletions

View File

@@ -0,0 +1,18 @@
import type { ListenerFunc } from './EventMessage';
/** 事件数据对象,用于存储事件监听器信息 */
export class EventData {
/** 事件名称 */
event!: string;
/** 事件监听器函数 */
listener!: ListenerFunc;
/** 监听器绑定的作用域对象 */
object!: object;
/** 重置数据,准备回收到对象池 */
reset() {
this.event = '';
this.listener = null!;
this.object = null!;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "74a2046d-feb9-4f28-b29c-b7be8f1f9022",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,32 @@
import { EventData } from './EventData';
/** EventData 对象池,减少频繁创建对象的 GC 压力 */
export class EventDataPool {
/** 对象池,存储可复用的 EventData 对象 */
private static pool: EventData[] = [];
/** 对象池最大容量,防止内存占用过大 */
private static readonly MAX_POOL_SIZE = 100;
/** 从对象池获取对象 */
static get(): EventData {
if (this.pool.length > 0) {
return this.pool.pop()!;
}
return new EventData();
}
/** 回收对象到对象池 */
static put(data: EventData) {
data.reset();
if (this.pool.length >= this.MAX_POOL_SIZE) {
// 删除最老的对象
this.pool.shift();
}
this.pool.push(data);
}
/** 清空对象池 */
static clear() {
this.pool.length = 0;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "2e4b5b79-a855-4adc-a158-94488dbc1ef6",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -5,7 +5,7 @@
* @LastEditTime: 2022-09-02 10:57:01
*/
import type { ListenerFunc } from './EventMessage';
import { MessageEventData } from './MessageManager';
import { MessageEventData } from './MessageEventData';
/**
* 事件对象基类,继承该类将拥有发送和接收事件的能力

View File

@@ -0,0 +1,93 @@
import type { ListenerFunc } from './EventMessage';
import { EventData } from './EventData';
import { EventDataPool } from './EventDataPool';
import { message } from './MessageManager';
/** 批量注册、移除全局事件对象(用于组件级事件管理) */
export class MessageEventData {
/** 本地事件列表,用于批量清理 */
private events: Map<string, Array<EventData>> = new Map();
/**
* 注册全局事件
* @param event 事件名
* @param listener 处理事件的侦听器函数
* @param object 侦听函数绑定的作用域对象
*/
on(event: string, listener: ListenerFunc, object: object) {
// 先注册到全局消息管理器
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 侦听函数绑定的作用域对象(可选)
*/
off(event: string, listener?: ListenerFunc, object?: object) {
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) {
message.dispatchEvent(event, ...args);
}
/** 清除所有的全局事件监听 */
clear() {
// 直接遍历 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

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "35a44c13-f854-4219-8210-ff706c9d5b07",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,135 +1,7 @@
import { log, warn } from 'cc';
import type { ListenerFunc } from './EventMessage';
class EventData {
event!: string;
listener!: ListenerFunc;
object: any;
/** 重置数据,准备回收到对象池 */
reset() {
this.event = '';
this.listener = null!;
this.object = null;
}
}
/** EventData 对象池,减少频繁创建对象的 GC 压力 */
class EventDataPool {
private static pool: EventData[] = [];
private static readonly MAX_POOL_SIZE = 100;
/** 从对象池获取对象 */
static get(): EventData {
if (this.pool.length > 0) {
return this.pool.pop()!;
}
return new EventData();
}
/** 回收对象到对象池 */
static put(data: EventData) {
data.reset();
if (this.pool.length >= this.MAX_POOL_SIZE) {
// 删除最老的对象
this.pool.shift();
}
this.pool.push(data);
}
/** 清空对象池 */
static clear() {
this.pool.length = 0;
}
}
/** 批量注册、移除全局事件对象(用于组件级事件管理) */
export class MessageEventData {
private events: Map<string, Array<EventData>> = new Map();
/**
* 注册全局事件
* @param event 事件名
* @param listener 处理事件的侦听器函数
* @param object 侦听函数绑定的作用域对象
*/
on(event: string, listener: ListenerFunc, object: object) {
// 先注册到全局消息管理器
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 侦听函数绑定的作用域对象(可选)
*/
off(event: string, listener?: ListenerFunc, object?: object) {
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) {
message.dispatchEvent(event, ...args);
}
/** 清除所有的全局事件监听 */
clear() {
// 直接遍历 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 { EventData } from './EventData';
import { EventDataPool } from './EventDataPool';
/**
* 全局消息管理