import { NodeIKernelMsgListener } from '@/core'; import { NodeIQQNTWrapperSession } from '@/core/wrapper'; import { randomUUID } from 'crypto'; interface Internal_MapKey { timeout: number, createtime: number, func: (...arg: any[]) => any, } export class ListenerClassBase { [key: string]: string; } export interface ListenerIBase { // eslint-disable-next-line @typescript-eslint/no-misused-new new(listener: any): ListenerClassBase; } export class NTEventWrapper { private ListenerMap: { [key: string]: ListenerIBase } | undefined;//ListenerName-Unique -> Listener构造函数 private WrapperSession: NodeIQQNTWrapperSession | undefined;//WrapperSession private ListenerManger: Map = new Map(); //ListenerName-Unique -> Listener实例 private EventTask = new Map>>();//tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func} constructor() { } createProxyDispatch(ListenerMainName: string) { // eslint-disable-next-line @typescript-eslint/no-this-alias const current = this; return new Proxy({}, { get(target: any, prop: any, receiver: any) { // console.log('get', prop, typeof target[prop]); if (typeof target[prop] === 'undefined') { // 如果方法不存在,返回一个函数,这个函数调用existentMethod return (...args: any[]) => { current.DispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then(); }; } // 如果方法存在,正常返回 return Reflect.get(target, prop, receiver); } }); } init({ ListenerMap, WrapperSession }: { ListenerMap: { [key: string]: typeof ListenerClassBase }, WrapperSession: NodeIQQNTWrapperSession }) { this.ListenerMap = ListenerMap; this.WrapperSession = WrapperSession; } CreatEventFunction any>(eventName: string): T | undefined { const eventNameArr = eventName.split('/'); type eventType = { [key: string]: () => { [key: string]: (...params: Parameters) => Promise> } } if (eventNameArr.length > 1) { const serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', ''); const eventName = eventNameArr[1]; //getNodeIKernelGroupListener,GroupService //console.log('2', eventName); const services = (this.WrapperSession as unknown as eventType)[serviceName](); let event = services[eventName]; //重新绑定this event = event.bind(services); if (event) { return event as T; } return undefined; } } CreatListenerFunction(listenerMainName: string, uniqueCode: string = ''): T { const ListenerType = this.ListenerMap![listenerMainName]; let Listener = this.ListenerManger.get(listenerMainName + uniqueCode); if (!Listener && ListenerType) { Listener = new ListenerType(this.createProxyDispatch(listenerMainName)); const ServiceSubName = listenerMainName.match(/^NodeIKernel(.*?)Listener$/)![1]; const Service = 'NodeIKernel' + ServiceSubName + 'Service/addKernel' + ServiceSubName + 'Listener'; const addfunc = this.CreatEventFunction<(listener: T) => number>(Service); addfunc!(Listener as T); //console.log(addfunc!(Listener as T)); this.ListenerManger.set(listenerMainName + uniqueCode, Listener); } return Listener as T; } //统一回调清理事件 async DispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) { //console.log(ListenerMainName, this.EventTask.get(ListenerMainName), ListenerSubName, this.EventTask.get(ListenerMainName)?.get(ListenerSubName)); this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.forEach((task, uuid) => { //console.log(task.func, uuid, task.createtime, task.timeout); if (task.createtime + task.timeout < Date.now()) { this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid); return; } task.func(...args); }); } async CallNoListenerEvent Promise,>(EventName = '', timeout: number = 3000, ...args: Parameters) { return new Promise>(async (resolve, reject) => { const EventFunc = this.CreatEventFunction(EventName); let complete = false; const Timeouter = setTimeout(() => { if (!complete) { reject(new Error('NTEvent EventName:' + EventName + ' timeout')); } }, timeout); const retData = await EventFunc!(...args); complete = true; resolve(retData); }); } async CallNormalEvent Promise, ListenerType extends (...args: any[]) => void>(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, ...args: Parameters) { return new Promise<[EventRet: Awaited>, ...Parameters]>(async (resolve, reject) => { const id = randomUUID(); let complete = 0; let retData: ArrayLike> | undefined = undefined; let retEvent: any = {}; const databack = () => { if (complete < waitTimes) { reject(new Error('NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' timeout')); } else { resolve([retEvent as Awaited>, ...(retData as Parameters)]); } }; const Timeouter = setTimeout(databack, timeout); const ListenerNameList = ListenerName.split('/'); const ListenerMainName = ListenerNameList[0]; const ListenerSubName = ListenerNameList[1]; const eventCallbak = { timeout: timeout, createtime: Date.now(), func: (...args: any[]) => { complete++; //console.log('func', ...args); retData = args as ArrayLike>; if (complete >= waitTimes) { clearTimeout(Timeouter); databack(); } } }; if (!this.EventTask.get(ListenerMainName)) { this.EventTask.set(ListenerMainName, new Map()); } if (!(this.EventTask.get(ListenerMainName)?.get(ListenerSubName))) { this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map()); } this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak); this.CreatListenerFunction(ListenerMainName); const EventFunc = this.CreatEventFunction(EventName); retEvent = await EventFunc!(...args); }); } } export const NTEventDispatch = new NTEventWrapper(); // 示例代码 快速创建事件 // let NTEvent = new NTEventWrapper(); // let TestEvent = NTEvent.CreatEventFunction<(force: boolean) => Promise>('NodeIKernelProfileLikeService/GetTest'); // if (TestEvent) { // TestEvent(true); // } // 示例代码 快速创建监听Listener类 // let NTEvent = new NTEventWrapper(); // NTEvent.CreatListenerFunction('NodeIKernelMsgListener', 'core') // 调用接口 //let NTEvent = new NTEventWrapper(); //let ret = await NTEvent.CallNormalEvent<(force: boolean) => Promise, (data1: string, data2: number) => void>('NodeIKernelProfileLikeService/GetTest', 'NodeIKernelMsgListener/onAddSendMsg', 1, 3000, true); // 注册监听 解除监听 // NTEventDispatch.RigisterListener('NodeIKernelMsgListener/onAddSendMsg','core',cb); // NTEventDispatch.UnRigisterListener('NodeIKernelMsgListener/onAddSendMsg','core'); // let GetTest = NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode); // GetTest('test'); // always模式 // NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode,(...args:any[])=>{ console.log(args) });