1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15import {Log} from "../Log"; 16 17export type Callback = (args: any) => void; 18const TAG = "EventBus"; 19 20export interface EventBus<T> { 21 on(event: T | T[], cb: Callback): () => void; 22 once(event: T, cb: Callback): () => void; 23 off(event: T | T[] | undefined, cb: Callback): void; 24 emit(event: T, args: any): void; 25} 26 27export function createEventBus<T extends string>(): EventBus<T> { 28 let _cbs: { [key: string]: Set<Callback> } = {}; 29 30 function on(events: T | T[], cb: Callback): () => void { 31 if (Array.isArray(events)) { 32 events.forEach((e) => on(e, cb)); 33 } else { 34 (_cbs[events] || (_cbs[events] = new Set())).add(cb); 35 Log.showInfo(TAG, `add event[${events}] callback, size: ${_cbs[events]?.size}`); 36 } 37 return () => off(events, cb); 38 } 39 40 function once(event: T, cb: Callback): () => void { 41 let newCallback = (args: any) => { 42 cb(args); 43 removeSelf(); 44 }; 45 function removeSelf() { 46 off(event, newCallback); 47 } 48 return on(event, newCallback); 49 } 50 51 function off(event: T | T[] | undefined, cb: Callback) { 52 if (!event) { 53 _cbs = {}; 54 Log.showInfo(TAG, `remove event[${event}] all callback`); 55 return; 56 } 57 if (Array.isArray(event)) { 58 event.forEach((e) => off(e, cb)); 59 return; 60 } 61 _cbs[event]?.delete(cb); 62 Log.showInfo(TAG, `remove event[${event}] callback, size: ${_cbs[event]?.size}`); 63 } 64 65 function emit(event: T, args: any) { 66 _cbs[event]?.forEach((cb) => cb(args)); 67 } 68 69 function stickyEmit(event: T, argument: any[]) {} 70 return { 71 on, 72 once, 73 off, 74 emit, 75 }; 76}