diff --git a/arkoala-arkts/arkui/src/Application.ts b/arkoala-arkts/arkui/src/Application.ts index df0f3e77354200f04518068900dffaae8561aff6..a60c065a043bdfbab3baf7906dae109210191f56 100644 --- a/arkoala-arkts/arkui/src/Application.ts +++ b/arkoala-arkts/arkui/src/Application.ts @@ -28,8 +28,6 @@ import { enterForeignContext, leaveForeignContext } from "./handwritten" setCustomEventsChecker(checkArkoalaCallbacks) -let rootPointer: pointer = nullptr - enum EventType { Click, Text, @@ -70,6 +68,7 @@ export function currentPartialUpdateContext(): T | undefined { return _currentPartialUpdateContext as (T | undefined) } +// TODO: move to Application class. let detachedRoots: Map> = new Map>() export function createUiDetachedRoot( @@ -97,27 +96,6 @@ export function destroyUiDetachedRoot(node: PeerNode): void { root.dispose() } -function createMemoRoot(manager: StateManager, - /** @memo */ - builder: UserViewBuilder -): ComputableState { - const peer = PeerNode.generateRootPeer() - rootPointer = peer.peer.ptr - - const node = manager.updatableNode(peer, (context: StateContext) => { - const frozen = manager.frozen - manager.frozen = true - memoEntry(context, 0, builder) - manager.frozen = frozen - }) - node.value - return node -} - -function measureLayoutAndDraw(peerNode: PeerNode) { - ArkUINativeModule._MeasureLayoutAndDraw(peerNode.peer.ptr) -} - function dumpTree(node: IncrementalNode, indent: int32 = 0) { const indentToString = (indent: number) => { let str = "" @@ -154,7 +132,7 @@ function drawCurrentCrash(crash: Object) { export class Application { private manager: StateManager | undefined = undefined - private root: ComputableState | undefined = undefined + private rootState: ComputableState | undefined = undefined private timer: MutableState | undefined = undefined private currentCrash: Object | undefined = undefined private enableDumpTree = false @@ -169,22 +147,47 @@ export class Application { this.useNativeLog = useNativeLog } + static createMemoRootState(manager: StateManager, + /** @memo */ + builder: UserViewBuilder + ): ComputableState { + const peer = PeerNode.generateRootPeer() + return manager.updatableNode(peer, (context: StateContext) => { + const frozen = manager.frozen + manager.frozen = true + memoEntry(context, 0, builder) + manager.frozen = frozen + }) + } + + private computeRoot(): PeerNode { + // let handle = ArkUINativeModule._SystemAPI_StartFrame() + let result: PeerNode + try { + result = this.rootState!.value + } finally { + // ArkUINativeModule._SystemAPI_EndFrame(handle) + } + return result + } + start(): pointer { if (this.withLog) UserView.startNativeLog(1) + let root: PeerNode| undefined = undefined try { this.manager = GlobalStateManager.instance this.timer = createAnimationTimer(this.manager!) - let /** @memo */ - builder = this.userView!.getBuilder() - this.root = createMemoRoot(this.manager!, builder) + let builder = this.userView!.getBuilder() + this.rootState = Application.createMemoRootState(this.manager!, builder) + root = this.computeRoot() } catch (e) { if (e instanceof Error) { const stack = e.stack if (stack) { InteropNativeModule._NativeLog("ArkTS Application.start stack trace: " + stack) - return nullptr } + return nullptr } } if (this.withLog) { @@ -198,7 +201,7 @@ export class Application { } } } - return rootPointer! + return root!.peer.ptr } private checkEvents(what: int32) { @@ -209,9 +212,10 @@ export class Application { private updateState() { // NativeModule._NativeLog("ARKTS: updateState") - this.updateStates(this.manager!, this.root!) + this.updateStates(this.manager!, this.rootState!) // Here we request to draw a frame and call custom components JS callbacks. - measureLayoutAndDraw(this.root!.value as PeerNode) + let root = this.rootState!.value + ArkUINativeModule._MeasureLayoutAndDraw(root.peer.ptr) // Call callbacks and sync callScheduledCallbacks() } @@ -220,7 +224,7 @@ export class Application { // Ensure all current state updates took effect. manager.syncChanges() manager.updateSnapshot() - root.value + this.computeRoot() for (const detachedRoot of detachedRoots.values()) detachedRoot.value if (partialUpdates.length > 0) { @@ -267,7 +271,7 @@ export class Application { try { this.timer!.value = Date.now() as int64 this.loopIteration(arg0, arg1) - if (this.enableDumpTree) dumpTree(this.root!.value) + if (this.enableDumpTree) dumpTree(this.rootState!.value) } catch (error) { if (error instanceof Error) { if (error.stack) {