From e6a8791fc34472ed9c38e63f1696f8b015e07050 Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Wed, 24 Sep 2025 11:03:37 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E4=B8=AD=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E6=9B=B4=E5=AE=89=E5=85=A8=E7=9A=84=E4=BA=8B=E4=BB=B6=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E5=99=A8=E6=96=B9=E6=B3=95=EF=BC=88=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=B3=84=E9=9C=B2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/ECS/Systems/EntitySystem.ts | 106 +++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/packages/core/src/ECS/Systems/EntitySystem.ts b/packages/core/src/ECS/Systems/EntitySystem.ts index ad836a61..dab90b24 100644 --- a/packages/core/src/ECS/Systems/EntitySystem.ts +++ b/packages/core/src/ECS/Systems/EntitySystem.ts @@ -5,6 +5,17 @@ import type { Scene } from '../Scene'; import type { ISystemBase } from '../../Types'; import type { QuerySystem } from '../Core/QuerySystem'; import { getSystemInstanceTypeName } from '../Decorators'; +import type { EventListenerConfig, TypeSafeEventSystem, EventHandler } from '../Core/EventSystem'; + +/** + * 事件监听器记录 + */ +interface EventListenerRecord { + eventSystem: TypeSafeEventSystem; + eventType: string; + handler: EventHandler; + listenerRef: string; +} /** * 实体系统的基类 @@ -37,6 +48,7 @@ export abstract class EntitySystem implements ISystemBase { private _initialized: boolean = false; private _matcher: Matcher; private _trackedEntities: Set = new Set(); + private _eventListeners: EventListenerRecord[] = []; /** * 获取系统处理的实体列表(动态查询) @@ -146,12 +158,18 @@ export abstract class EntitySystem implements ISystemBase { /** * 重置系统状态 - * + * * 当系统从场景中移除时调用,重置初始化状态以便重新添加时能正确初始化。 */ public reset(): void { this._initialized = false; this._trackedEntities.clear(); + + // 清理所有事件监听器 + this.cleanupEventListeners(); + + // 调用用户可重写的销毁方法 + this.onDestroy(); } /** @@ -543,4 +561,90 @@ export abstract class EntitySystem implements ISystemBase { protected onRemoved(entity: Entity): void { // 子类可以重写此方法 } + + /** + * 添加事件监听器 + * + * 推荐使用此方法而不是直接调用eventSystem.on(), + * 这样可以确保系统移除时自动清理监听器,避免内存泄漏。 + * + * @param eventType 事件类型 + * @param handler 事件处理函数 + * @param config 监听器配置 + */ + protected addEventListener( + eventType: string, + handler: EventHandler, + config?: EventListenerConfig + ): void { + if (!this.scene?.eventSystem) { + console.warn(`[${this.systemName}] Cannot add event listener: scene.eventSystem not available`); + return; + } + + const listenerRef = this.scene.eventSystem.on(eventType, handler, config); + + // 跟踪监听器以便后续清理 + if (listenerRef) { + this._eventListeners.push({ + eventSystem: this.scene.eventSystem, + eventType, + handler, + listenerRef + }); + } + } + + /** + * 移除特定的事件监听器 + * + * @param eventType 事件类型 + * @param handler 事件处理函数 + */ + protected removeEventListener( + eventType: string, + handler: EventHandler + ): void { + const listenerIndex = this._eventListeners.findIndex( + listener => listener.eventType === eventType && listener.handler === handler + ); + + if (listenerIndex >= 0) { + const listener = this._eventListeners[listenerIndex]; + + // 从事件系统中移除 + listener.eventSystem.off(eventType, listener.listenerRef); + + // 从跟踪列表中移除 + this._eventListeners.splice(listenerIndex, 1); + } + } + + /** + * 清理所有事件监听器 + * + * 系统移除时自动调用,清理所有通过addEventListener添加的监听器。 + */ + private cleanupEventListeners(): void { + for (const listener of this._eventListeners) { + try { + listener.eventSystem.off(listener.eventType, listener.listenerRef); + } catch (error) { + console.warn(`[${this.systemName}] Failed to remove event listener for "${listener.eventType}":`, error); + } + } + + // 清空跟踪列表 + this._eventListeners.length = 0; + } + + /** + * 系统销毁时的回调 + * + * 当系统从场景中移除时调用,子类可以重写此方法进行清理操作。 + * 注意:事件监听器会被框架自动清理,无需手动处理。 + */ + protected onDestroy(): void { + // 子类可以重写此方法进行清理操作 + } } \ No newline at end of file