diff --git a/.gitee/CODEOWNERS b/.gitee/CODEOWNERS index cbd29239ec07c28a7885931d0e0de46abb1764a0..4babdd92f5cc8d30c58f56090d38ecccf401acf7 100644 --- a/.gitee/CODEOWNERS +++ b/.gitee/CODEOWNERS @@ -3172,6 +3172,11 @@ frameworks/core/interfaces/native/implementation/level_order_peer.h @arkuipopupw frameworks/core/interfaces/native/implementation/mouse_event_accessor.cpp @arkuievent frameworks/core/interfaces/native/implementation/mouse_event_peer.h @arkuievent +frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkComponentRoot.ts @arkuistatemgmt +frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkStructBase.ts @arkuistatemgmt +frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/PeerNode.ts @arkuiframework +frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/customComponent.ts @arkuistatemgmt + frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/BuilderNode.ts @arkuiframework frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts @arkuiframework frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/RenderNode.ts @arkuiframework diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkComponentRoot.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkComponentRoot.ts index ce11d6fdf881c0e3e144ed311cdc5cd1fe344dc5..0b2ff082fb58089428a3748e8a60254df39dc96d 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkComponentRoot.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkComponentRoot.ts @@ -39,7 +39,7 @@ export function setNeedCreate(isNeedCreate: boolean): boolean export function ArkComponentRoot( component: ArkCustomComponent, /** @memo */ - content: () => void + content: (node: PeerNode) => void ) { InteropNativeModule._NativeLog(`ArkTS ArkComponentRoot enter`) NodeAttach( @@ -55,7 +55,7 @@ export function ArkComponentRoot( component.aboutToDisappear() }) ) - content(); + content(node); } ) } \ No newline at end of file diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkStructBase.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkStructBase.ts index f6c4992a5680c73c1c263647d2f3994a90bee21e..1ad56c4d739038cfe78cad29c7392524213ece47 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkStructBase.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ArkStructBase.ts @@ -20,6 +20,7 @@ import { SyntaxItemPeer } from "./handwritten/RepeatImpl"; import { ObserveSingleton } from "./stateManagement/base/observeSingleton"; import { OBSERVE } from "./stateManagement"; import { PeerNode } from "./PeerNode" +import { RecordData } from "@ohos.base" /** base class for user's structs */ export abstract class ArkStructBase implements ArkCustomComponent { @@ -39,8 +40,8 @@ export abstract class ArkStructBase implements ArkCustomComponent throw new Error("Not supported yet"); } - aboutToReuse(initializers?: T_Options): void {} - aboutToRecycle(): void {} + aboutToReuse(param: RecordData, initializers?: T_Options): void { } + aboutToRecycle(): void { } // Can be overridden as an effect of @Prop, @Watch etc protected __updateStruct(initializers?: T_Options): void { } @@ -79,7 +80,7 @@ export abstract class ArkStructBase implements ArkCustomComponent content?: () => void, initializers?: T_Options ): void { - ArkComponentRoot(this, () => { + ArkComponentRoot(this, (node: PeerNode) => { this.__updateStruct(initializers); const savedRenderingComponent = OBSERVE.renderingComponent OBSERVE.renderingComponent = this.isV2() ? @@ -91,6 +92,12 @@ export abstract class ArkStructBase implements ArkCustomComponent this.onDidBuild(); }) }); + node.setOnRecycle(() => + this.aboutToRecycle() + ) + node.setOnReuse((params?: RecordData) => { + this.aboutToReuse(params, params ? undefined : initializers); + }) }) } @@ -114,8 +121,8 @@ export abstract class ArkStructBase implements ArkCustomComponent return instance }); node.setOnReuse( - () => { - component.aboutToReuse(initializers) + (params?: RecordData) => { + component.aboutToReuse(params, params ? undefined : initializers) } ) component._buildWrapper(content, initializers); diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/BuilderNode.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/BuilderNode.ts index 8a452a2031bc8ee061b3d93c1de13b3c7cc723dc..3ec776074682531ae1f554c3cb2d9314220c068e 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/BuilderNode.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/BuilderNode.ts @@ -30,6 +30,7 @@ import { ArkUIAniModule } from 'arkui.ani' import { UIContextImpl, ContextRecord } from "./handwritten/UIContextImpl" import { ParallelizeUI } from "../@ohos.arkui.Parallelize" import { memorizeUpdatedState } from "./stateManagement/remember" +import { RecordData } from "@ohos.base" export enum NodeRenderType { RENDER_TYPE_DISPLAY = 0, @@ -191,7 +192,7 @@ export class BuilderNode { this._JSBuilderNode.disposeNode(); this.nodePtr_ = undefined; } - public reuse(param?: Record): void { + public reuse(param?: RecordData): void { this._JSBuilderNode.reuse(param); } public recycle(): void { @@ -395,10 +396,18 @@ export class JSBuilderNode extends BuilderNodeOps { return null; } - public reuse(param?: Record): void { + public reuse(param?: RecordData): void { + if (this.__root) { + let node = findPeerNode(this.__root!); + node?.onReuse(true, param); + } } public recycle(): void { + if (this.__root) { + let node = findPeerNode(this.__root!); + node?.onRecycle(true); + } } public getFrameNodeWithoutCheck(): FrameNode | null | undefined { diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ComponentContent.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ComponentContent.ts index 10afc1aa7a6a4eb0ba99a30712684791d349203e..df52ed6b0e8f6f9ca9e78d3107cbd18428b43a7c 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ComponentContent.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ComponentContent.ts @@ -21,6 +21,7 @@ import { BuilderNode, BuildOptions, voidBuilderFunc, TBuilderFunc } from "./Buil import { Content } from "./Content" import { KPointer, pointer } from "@koalaui/interop" +import { RecordData } from "@ohos.base" export interface ComponentContentBase extends Content { @@ -56,7 +57,7 @@ export class ComponentContent implements ComponentContentBase { // point to struct FrameNodePeer or undefined return this.builderNode_.getNodePtr(); } - reuse(param?: Record): void { + reuse(param?: RecordData): void { this.builderNode_.reuse(param); } recycle(): void { diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/PeerNode.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/PeerNode.ts index 9561fda5962fa32d5b4dabc64169d77a31cb3a67..1d5a538d0bee3f07d6df038af17e9e99446cf7ad 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/PeerNode.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/PeerNode.ts @@ -22,6 +22,7 @@ import { ReusablePool } from "./ReusablePool" import { StateStylesOps } from './component/arkui-custom' import { ArkUIAniModule } from "arkui.ani" import { StateUpdateLoop } from "./stateManagement" +import { RecordData } from "@ohos.base" export const PeerNodeType = 11 export const RootPeerType = 33 @@ -50,7 +51,7 @@ export class PeerNode extends IncrementalNode { ArkUIAniModule._UINode_OnUpdateDone(this.peer.ptr) } private id: int32 - private _reuseCb?: () => void + private _reuseCb?: (param?: RecordData) => void private _recycleCb?: () => void // Pool to store recycled child scopes, grouped by type private _reusePool?: Map @@ -71,17 +72,36 @@ export class PeerNode extends IncrementalNode { return this.id } - onReuse(): void { - if (!this.reusable) { - return + onReuse(sync: boolean, param?: RecordData): void { + if (this._reuseCb) { + if (sync) { + this._reuseCb?.(param); + } else { + scheduleCallback(() => { this._reuseCb?.(param) }) // could change states + } + } + if (sync) { + + for (let child = this.firstChild; child; child = child!.nextSibling) { + if (child?.isKind(PeerNodeType)) { + (child as PeerNode)!.onReuse(sync, param); + } + } } - scheduleCallback(this._reuseCb) // could change states } - onRecycle(): void { + onRecycle(needRecurs?: boolean): void { this._recycleCb?.() + if (needRecurs) { + for (let child = this.firstChild; child; child = child!.nextSibling) { + if (child?.isKind(PeerNodeType)) { + (child as PeerNode)!.onRecycle(needRecurs); + } + } + } } + updateReusePoolSize(size: number, reuseKey: string) { this._reusePool?.get(reuseKey)?.setMaxSize(size) } @@ -140,7 +160,7 @@ export class PeerNode extends IncrementalNode { setOnRecycle(cb: () => void): void { this._recycleCb = cb } - setOnReuse(cb: () => void): void { + setOnReuse(cb: (param?: RecordData) => void): void { this._reuseCb = cb } @@ -167,7 +187,11 @@ export class PeerNode extends IncrementalNode { // TODO: rework to avoid search let peer = findPeerNode(child) if (peer) { - peer.reusable ? peer!.onReuse() : peer.reusable = true // becomes reusable after initial mount + if (peer.reusable) { + peer!.onReuse(false) + } else { + peer.reusable = true // becomes reusable after initial mount + } let peerPtr = peer.peer.ptr if (this.insertMark != nullptr) { if (this.insertDirection == 0) { diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/LazyItemNode.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/LazyItemNode.ts index aff0cc30862272ea50c3b98c993877d83332addb..e74d470978e314a3f45f428d6d638470eb68a944 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/LazyItemNode.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/LazyItemNode.ts @@ -31,7 +31,7 @@ export class LazyItemNode extends IncrementalNode { return } const peer = node as PeerNode - peer.reusable ? peer.onReuse() : peer.reusable = true + peer.reusable ? peer.onReuse(false) : peer.reusable = true } this.onChildRemoved = (node: IncrementalNode) => { if (!node.isKind(PeerNodeType)) { @@ -39,7 +39,7 @@ export class LazyItemNode extends IncrementalNode { } const peer = node as PeerNode if (!peer.disposed) { - peer.onRecycle() + peer.onRecycle(false) } } } diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/customComponent.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/customComponent.ts index f8a92f82a4d1a2cc809b21ffc8dcbbd317d3b005..b4806bb73994d937a5f2517f6f4b0cc4b248b291 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/customComponent.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/customComponent.ts @@ -29,6 +29,61 @@ import promptAction from '@ohos/promptAction'; import { Theme } from '@ohos/arkui/theme'; import { ArkThemeScopeManager } from "arkui/handwritten/theme/ArkThemeScopeManager"; import { CustomDialogController } from './customDialogController'; +import { RecordData } from "@ohos.base" + +export class ReuseObject { + readonly _raw: RecordData; + private _recordValue: Record = {} + private _isRecord: boolean = false; + constructor(value: RecordData) { + this._raw = value; + if (this._raw instanceof Record) { + this._recordValue = value as Record; + this._isRecord = true; + } + } + + get raw(): RecordData { + return this._raw; + } + + $_get(key: string): RecordData { + if (this._raw === undefined || this._raw === null) { + return undefined; + } + if (this._isRecord) { + return this._recordValue[key]; + } else { + return ((reflect.Value.of(this._raw) as ClassValue).getFieldByName(key).getData() as RecordData); + } + } + + has(key: string): boolean { + if (this._raw === undefined || this._raw === null) { + return false; + } + if (this._isRecord) { + return this._recordValue.has(key); + } else { + return (Type.of(this._raw) as ClassType).hasField(key); + } + } + + keys(): string[] { + if (this._raw === undefined || this._raw === null) { + return []; + } + if (this._isRecord) { + let key: string[] = []; + for (let value of this._recordValue.keys()) { + key.push(value); + } + return key; + } else { + return Object.getOwnPropertyNames(this._raw!); + } + } +} export interface PageLifeCycle { onPageShow(): void {} @@ -145,16 +200,20 @@ export class CustomDelegate extends } } - aboutToReuse(initializers?: T_Options): void { + aboutToReuse(param: RecordData, initializers?: T_Options): void { if (this.instance instanceof ReusableLifeCycle) { const reusable = this.instance as ReusableLifeCycle; + if (param) { + reusable.aboutToReuse(new ReuseObject(param)) + return; + } if (initializers === undefined) { - reusable.aboutToReuse({}); - } else { + reusable.aboutToReuse(new ReuseObject({} as Record as RecordData)); + } else if (initializers instanceof T_Options) { const component = this.instance as BaseCustomComponent; const data: T_Options = initializers as T_Options; - const params: Record = component.__toRecord(data! as object); - reusable.aboutToReuse(params); + const params: Record | undefined = component.__toRecord(data! as object); + reusable.aboutToReuse(new ReuseObject(params === undefined ? initializers as RecordData : params)); } } else if (this.instance instanceof ReusableV2LifeCycle) { const reusable = this.instance as ReusableV2LifeCycle; @@ -299,11 +358,11 @@ export abstract class BaseCustomComponent extends ExtendableComponent } aboutToRecycle(): void {} - __toRecord(param: object): Record { return {} } + __toRecord(param: object): Record | undefined { return undefined; } } interface ReusableLifeCycle { - aboutToReuse(params: Record): void; + aboutToReuse(params: ReuseObject): void; } export abstract class CustomComponent, T_Options> extends BaseCustomComponent implements ReusableLifeCycle { @@ -327,7 +386,7 @@ export abstract class CustomComponent, T () => createInstance(uiContext, factory, initializers), content, initializers, reuseKey); } - aboutToReuse(params: Record): void {} + aboutToReuse(params: ReuseObject): void { } } interface ReusableV2LifeCycle {