• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2025 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 */
15
16import { KPointer } from "../../interop/InteropTypes"
17import { CallbackRegistry } from "../../interop/Platform"
18
19class CallbackInfo {
20    cb: any
21    recv: any
22    constructor(callback: any, obj: any = null) {
23        this.cb = callback
24        this.recv = obj
25    }
26}
27
28const GLOBAL_SCOPE = new class CallbackScope {
29    static readonly CB_NULL = new CallbackInfo(
30        () => { throw new Error("attempted to call a callback at NULL") },
31        null
32    )
33    static readonly CB_UNDEFINED = new CallbackInfo(
34        () => { throw new Error("attempted to call an uninitialized callback") },
35        null
36    )
37    static readonly CB_NULL_ID = 0
38    nextId: number
39    callbackMap: Map<number, CallbackInfo> | null
40
41    constructor() {
42        this.nextId = 1
43        this.callbackMap = new Map()
44        this.callbackMap.set(CallbackScope.CB_NULL_ID, CallbackScope.CB_NULL)
45    }
46
47    addCallback(cb: any, obj: any): number {
48        let id = this.nextId++
49        this.callbackMap?.set(id, new CallbackInfo(cb, obj))
50        return id
51    }
52
53    getCallback(id: number): CallbackInfo {
54        return this.callbackMap?.get(id) || CallbackScope.CB_UNDEFINED
55    }
56
57    deleteCallback(id: number): void {
58        if (id > CallbackScope.CB_NULL_ID) {
59            this.callbackMap?.delete(id)
60        }
61    }
62
63    release(): void {
64        this.callbackMap = null
65    }
66}
67
68function callCallback(callbackId: number): any {
69    let CallbackInfo = GLOBAL_SCOPE.getCallback(callbackId)
70    try {
71        let cb = CallbackInfo.cb
72        if (CallbackInfo.recv !== null) {
73            cb = cb.bind(CallbackInfo.recv)
74        }
75        return cb()
76    } catch (e) {
77        console.error(e)
78    }
79}
80
81export function registerCallback(callback: any, obj: any = null): KPointer {
82    return GLOBAL_SCOPE.addCallback(callback, obj)
83}
84
85function releaseCallback(callbackId: number): void {
86    return GLOBAL_SCOPE.deleteCallback(callbackId)
87}
88
89declare namespace globalThis {
90    function callCallback(callbackId: number): any
91    function releaseCallback(callbackId: number): any
92}
93
94globalThis.callCallback = callCallback
95globalThis.releaseCallback = releaseCallback
96
97export function setCallbackRegistry(_ignoredRegistry: CallbackRegistry) {
98    // On WASM we don't need registry in current implementation.
99}
100