idlize

Форк
0
120 строк · 3.7 Кб
1
/*
2
 * Copyright (c) 2024 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

16
import { pointer, nullptr, isNullPtr } from "@koalaui/interop"
17
import { finalizerRegister, finalizerUnregister, Thunk } from "./Finalization";
18
import { nativeModule } from "@koalaui/arkoala";
19

20
export abstract class FinalizableBase {
21
    ptr: pointer
22
    finalizer: pointer
23
    managed: boolean
24
    cleaner?: NativeThunk = undefined
25

26
    constructor(ptr: pointer, finalizer: pointer, managed: boolean) {
27
        this.ptr = ptr
28
        this.finalizer = finalizer
29
        this.managed = managed
30

31
        if (this.managed) {
32
            if (isNullPtr(this.ptr)) throw new Error("Can't have nullptr ptr")
33
            if (isNullPtr(this.finalizer)) throw new Error("Can't have nullptr finalizer")
34

35
            const handle = this.createHandle()
36
            const thunk = this.makeNativeThunk(ptr, finalizer, handle)
37
            finalizerRegister(this, thunk)
38
            this.cleaner = thunk
39
        }
40
    }
41

42
    abstract makeNativeThunk(ptr: pointer, finalizer: pointer, handle: string|undefined): NativeThunk
43

44
    createHandle(): string | undefined {
45
        return undefined
46
    }
47

48
    close() {
49
        if (isNullPtr(this.ptr)) {
50
            throw new Error(`Closing a closed object: ${this}`)
51
        } else if (this.cleaner === undefined || isNullPtr(this.cleaner.ptr) || isNullPtr(this.cleaner.finalizer)) {
52
            throw new Error(`No thunk assigned to ${this}`)
53
        }
54

55
        finalizerUnregister(this)
56
        this.cleaner?.clean()
57
        this.cleaner = undefined
58
        this.ptr = nullptr
59
    }
60

61
    release(): pointer {
62
        finalizerUnregister(this)
63
        if (this.cleaner !== undefined)
64
            this.cleaner.ptr = nullptr
65
        const result = this.ptr
66
        this.ptr = nullptr
67
        return result
68
    }
69

70
    resetPeer(pointer: pointer) {
71
        if (this.managed) throw Error(`Can only reset peer for an unmanaged object`)
72
        this.ptr = pointer
73
    }
74

75
    use<R>(body: (value: FinalizableBase) => R): R {
76
        const result = body(this)
77
        this.close()
78
        return result
79
    }
80
}
81

82
export class Finalizable extends FinalizableBase {
83
    constructor(public ptr: pointer, finalizer: pointer, managed: boolean = true) {
84
        super(ptr, finalizer, managed)
85
    }
86

87
    makeNativeThunk(ptr: pointer, finalizer: pointer, handle: string | undefined): NativeThunk {
88
        return new NativeThunkImpl(ptr, finalizer, handle)
89
    }
90
}
91

92
export abstract class NativeThunk implements Thunk {
93
    ptr:pointer
94
    finalizer: pointer
95
    name?: string
96

97
    constructor(ptr: pointer, finalizer: pointer, name?: string) {
98
        this.ptr = ptr;
99
        this.finalizer = finalizer;
100
        this.name = name
101
    }
102

103
    clean() {
104
        if(!isNullPtr(this.ptr)) {
105
            this.destroyNative(this.ptr, this.finalizer)
106
        }
107
        this.ptr = nullptr;
108
    }
109

110
    abstract destroyNative(ptr: pointer, finalizer: pointer) : void
111
}
112

113
class NativeThunkImpl extends NativeThunk {
114
    constructor(ptr: pointer, finalizer: pointer, name?: string) {
115
        super(ptr, finalizer, name)
116
    }
117
    destroyNative(ptr: pointer, finalizer: pointer): void {
118
        nativeModule()._InvokeFinalizer(ptr, finalizer)
119
    }
120
}
121

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.