diff --git a/arkoala-arkts/arkui/src/generated/Finalizable.ts b/arkoala-arkts/arkui/src/generated/Finalizable.ts deleted file mode 100644 index 0b931ee06ad7cdf6c03c5a6092e177ca48bca322..0000000000000000000000000000000000000000 --- a/arkoala-arkts/arkui/src/generated/Finalizable.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { pointer, nullptr } from "@koalaui/interop" - -export class Finalizable { - public ptr: pointer - public finalizerPtr: pointer - - constructor(ptr: pointer, finalizerPtr: pointer) { - this.ptr = ptr - this.finalizerPtr = finalizerPtr - } - - release(): pointer { - let result = this.ptr - this.ptr = nullptr - return result - } -} \ No newline at end of file diff --git a/interop/src/arkts/Finalizable.sts b/interop/src/arkts/Finalizable.sts index 50b494929d333475a61fd80574f51639a6aee18c..6ae3ac2d8b4f612072e37bee9b64eae3d91a2b01 100644 --- a/interop/src/arkts/Finalizable.sts +++ b/interop/src/arkts/Finalizable.sts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,20 +13,88 @@ * limitations under the License. */ +import { finalizerRegister, finalizerUnregister, Thunk } from "@koalaui/common" +import { InteropNativeModule } from "./InteropNativeModule" import { pointer, nullptr } from "./InteropTypes" -export class Finalizable { - public ptr: pointer - public finalizerPtr: pointer +class NativeThunk implements Thunk { + finalizer: pointer + obj: pointer + name: string|undefined + + constructor(obj: pointer, finalizer: pointer, name?: string) { + this.finalizer = finalizer + this.obj = obj + this.name = name + } + + clean() { + if (this.obj != nullptr) { + this.destroyNative(this.obj, this.finalizer) + } + this.obj = nullptr + } - constructor(ptr: pointer, finalizerPtr: pointer) { + destroyNative(ptr: pointer, finalizer: pointer): void { + InteropNativeModule._InvokeFinalizer(ptr, finalizer) + } +} + +/** + * Class with the custom finalizer, usually used to release a native peer. + * Do not use directly, only via subclasses. + */ +export class Finalizable { + ptr: pointer + finalizer: pointer + cleaner: NativeThunk|undefined = undefined + managed: boolean + constructor(ptr: pointer, finalizer: pointer, managed: boolean = true) { this.ptr = ptr - this.finalizerPtr = finalizerPtr + this.finalizer = finalizer + this.managed = managed + const handle = undefined + + if (this.managed) { + if (this.ptr == nullptr) throw new Error("Can't have nullptr ptr ${}") + if (this.finalizer == nullptr) throw new Error("Managed finalizer is 0") + + const thunk = new NativeThunk(ptr, finalizer, handle) + finalizerRegister(this, thunk) + this.cleaner = thunk + } + } + + close() { + if (this.ptr == nullptr) { + throw new Error(`Closing a closed object: ` + this.toString()) + } else if (this.cleaner == undefined) { + throw new Error(`No thunk assigned to ` + this.toString()) + } else { + finalizerUnregister(this) + this.cleaner!.clean() + this.cleaner = undefined + this.ptr = nullptr + } } release(): pointer { + finalizerUnregister(this) + if (this.cleaner) + this.cleaner!.obj = nullptr let result = this.ptr this.ptr = nullptr return result } -} \ No newline at end of file + + resetPeer(pointer: pointer) { + if (this.managed) throw new Error("Can only reset peer for an unmanaged object") + this.ptr = pointer + } + + use(body: (value: Finalizable) => R): R { + let result = body(this) + this.close() + return result + } +} diff --git a/interop/src/interop/Finalizable.ts b/interop/src/interop/Finalizable.ts index 55af492917c4f9cef102f0629a7b90b64f4240c4..5f2bcbe20298436848653cf8f3a35e0f947eccc4 100644 --- a/interop/src/interop/Finalizable.ts +++ b/interop/src/interop/Finalizable.ts @@ -13,8 +13,7 @@ * limitations under the License. */ -import { Wrapper } from "./Wrapper" -import { nullptr, isNullPtr } from "./Wrapper" +import { Wrapper, nullptr, isNullPtr } from "./Wrapper" import { finalizerRegister, finalizerUnregister, Thunk } from "@koalaui/common" import { InteropNativeModule } from "./InteropNativeModule" import { pointer } from "./InteropTypes"