import { Component } from "cc"; /*** * 事件管理器 * 事件可一对一也可一对多 */ export class EventManager { //事件 private _events = new Map(); //事件ID缓存 private _targets = new Set(); //只触发一次事件 private _onceEvents = new Map(); //只触发一次事件ID缓存 private _onceTargets = new Set(); constructor() { this._events.clear(); this._targets.clear(); this._onceEvents.clear(); this._onceTargets.clear(); } /** * 添加事件 * @param name 事件名 * @param callback 回调函数 * @param target 回调目标 * @param uuid 事件唯一ID,如果在组件调用不需要该值 */ addEvent(name: string, callback: (...val: any[]) => void, target: any, uuid: string = null) { if (!name || !callback || !target) { console.error("添加事件失败name,callback或者target为空."); return false; } if (!this._events.has(name)) { this._events.set(name, []); } if (!uuid) { uuid = target.node.uuid; } this._events.get(name).push({ id: uuid, func: callback.bind(target), target: target }); if (!this._targets.has(uuid)) { this._targets.add(uuid); } return true; } /** * 只触发一次事件 * @param name 事件名 * @param callback 回调函数 * @param target 回调目标 * @param uuid 事件唯一ID,如果在组件调用不需要该值 */ onceEvent(name: string, callback: (...val: any[]) => void, target: any, uuid: string = null) { if (!name || !callback || !target) { console.error("添加事件失败name,callback或者target为空."); return false; } if (!this._onceEvents.has(name)) { this._onceEvents.set(name, []); } if (!uuid) { uuid = target.node.uuid; } this._onceEvents.get(name).push({ id: uuid, func: callback.bind(target), target: target }); if (!this._onceTargets.has(uuid)) { this._onceTargets.add(uuid); } return true; } /** * 发射事件 * @param name 事件名 * @param val 传递的数据 */ fireEvent(name: string, ...val: any[]) { let event = this._events.get(name); if (event) { for (let i = event.length - 1; i >= 0; --i) { if (event[i].target instanceof Component) { if (event[i].target.isValid) { event[i].func(...val); } else { event.splice(i, 1); } } else { event[i].func(...val); } } } let onceEvent = this._onceEvents.get(name); if (onceEvent) { for (let i = onceEvent.length - 1; i >= 0; --i) { if (onceEvent[i].target instanceof Component) { if (onceEvent[i].target.isValid) { onceEvent[i].func(...val); } } else { onceEvent[i].func(...val); } } this._onceEvents.delete(name); } } /** * 移除组件所有事件 * @param target 目标组件或事件的唯一标识 */ removeEvent(target: Component | string) { let uuid = (typeof target === "string") ? target : target?.node?.uuid; if (this._targets.has(uuid)) { this._targets.delete(uuid); this._events.forEach((events, name) => { for (let i = events.length - 1; i >= 0; --i) { if (events[i].id === uuid) { events.splice(i, 1); } } if (events.length === 0) { this._events.delete(name); } }); } if (this._onceTargets.has(uuid)) { this._onceTargets.delete(uuid); this._onceEvents.forEach((events, name) => { for (let i = events.length - 1; i >= 0; --i) { if (events[i].id === uuid) { events.splice(i, 1); } } if (events.length === 0) { this._onceEvents.delete(name); } }); } } removeAll() { this._events.clear(); this._targets.clear(); this._onceEvents.clear(); this._onceTargets.clear(); } } export let EventMgr = new EventManager; /** * 如果在组件上添加事件则所有的target为this * addEvent("Level_Up",callback,this) * 移除组件所有的事件,如果组件为UIMgr管理则会自动调用 * removeEvent(this) * * 如果在非组件上监听事件 * addEvent("Level_Up",callback,this,only_uuid) * 移除事件 * removeEvent(only_uuid) */