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