From 3e57fecba3b9ce16e2c00bf687572bf9c7b18e17 Mon Sep 17 00:00:00 2001 From: Denis Pikalov Date: Fri, 22 Aug 2025 16:31:37 +0300 Subject: [PATCH] Add recycle/reuse to Repeat non-virtualScroll Signed-off-by: Denis Pikalov Change-Id: Ic96bf44c0b97510440271cedae1ad9c46fb614ed --- .../declarative_frontend/jsview/js_repeat.cpp | 22 +++++++++++++++++++ .../declarative_frontend/jsview/js_repeat.h | 2 ++ .../src/lib/partial_update/pu_foreach.d.ts | 2 ++ .../src/lib/partial_update/pu_repeat_impl.ts | 8 +++++-- .../core/components_ng/syntax/repeat_model.h | 3 +++ .../components_ng/syntax/repeat_model_ng.cpp | 16 ++++++++++++++ .../components_ng/syntax/repeat_model_ng.h | 2 ++ .../core/components_ng/syntax/repeat_node.cpp | 16 ++++++++++++++ .../core/components_ng/syntax/repeat_node.h | 3 +++ 9 files changed, 72 insertions(+), 2 deletions(-) diff --git a/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp b/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp index 721410261c0..c3a31e8b581 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_repeat.cpp @@ -125,6 +125,26 @@ void JSRepeat::AfterAddChild() RepeatModel::GetInstance()->AfterAddChild(); } +void JSRepeat::RecycleChild(const JSCallbackInfo& info) +{ + if ((info.Length() < 1) || !info[0]->IsNumber()) { + TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.RecycleChild"); + return; + } + const auto index = info[0]->ToNumber(); + RepeatModel::GetInstance()->RecycleChild(index); +} + +void JSRepeat::ReuseChild(const JSCallbackInfo& info) +{ + if ((info.Length() < 1) || !info[0]->IsNumber()) { + TAG_LOGW(AceLogTag::ACE_REPEAT, "Invalid arguments for Repeat.ReuseChild"); + return; + } + const auto index = info[0]->ToNumber(); + RepeatModel::GetInstance()->ReuseChild(index); +} + void JSRepeat::JsParseItemDragEventHandler( const JsiExecutionContext& context, const JSRef& itemDragEventObj) { @@ -178,6 +198,8 @@ void JSRepeat::JSBind(BindingTarget globalObj) JSClass::StaticMethod("createNewChildFinish", &JSRepeat::CreateNewChildFinish); JSClass::StaticMethod("afterAddChild", &JSRepeat::AfterAddChild); JSClass::StaticMethod("onMove", &JSRepeat::OnMove); + JSClass::StaticMethod("recycle", &JSRepeat::RecycleChild); + JSClass::StaticMethod("reuse", &JSRepeat::ReuseChild); JSClass::Bind<>(globalObj); } diff --git a/frameworks/bridge/declarative_frontend/jsview/js_repeat.h b/frameworks/bridge/declarative_frontend/jsview/js_repeat.h index dc095000647..ffec7b61650 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_repeat.h +++ b/frameworks/bridge/declarative_frontend/jsview/js_repeat.h @@ -38,6 +38,8 @@ public: // key: string // parentView?: JSView static void CreateNewChildFinish(const JSCallbackInfo& info); + static void RecycleChild(const JSCallbackInfo& info); + static void ReuseChild(const JSCallbackInfo& info); static void AfterAddChild(); static void OnMove(const JSCallbackInfo& info); static void JsParseItemDragEventHandler(const JsiExecutionContext& context, const JSRef& itemDragEventObj); diff --git a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts index 01515f7903b..4de1e47ba46 100644 --- a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts +++ b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_foreach.d.ts @@ -43,6 +43,8 @@ declare class RepeatNative { static createNewChildFinish(id: string): void; static afterAddChild(): void; static onMove(handler: (from: number, to: number) => void, eventHandler?: ItemDragEventHandler); + static reuse(index: number): void; + static recycle(index: number): void; } // Repeat.virtualScroll maps to C++ RepeatVirtualScrollNode diff --git a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts index 6a399a0c630..9990ea60362 100644 --- a/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts +++ b/frameworks/bridge/declarative_frontend/state_mgmt/src/lib/partial_update/pu_repeat_impl.ts @@ -33,14 +33,16 @@ class __RepeatImpl { /**/ public render(config: __RepeatConfig, isInitialRender: boolean): void { - this.arr_ = config.arr; + if (this.arr_ !== config.arr) { + this.arr_ = config.arr; + isInitialRender = true; + } this.itemGenFuncs_ = config.itemGenFuncs; this.ttypeGenFunc_ = config.ttypeGenFunc; this.keyGenFunction_ = config.keyGenFunc; this.mkRepeatItem_ = config.mkRepeatItem; this.onMoveHandler_ = config.onMoveHandler; this.itemDragEventHandler = config.itemDragEventHandler; - isInitialRender ? this.initialRender() : this.reRender(); } @@ -126,6 +128,7 @@ class __RepeatImpl { itemInfo.repeatItem = oldRepeatItem; stateMgmtConsole.debug(`__RepeatImpl: new: key ${key} reuse key ${reuseKey} ${oldKeyIndex}->${index}`); + RepeatNative.recycle(oldKeyIndex); itemInfo.repeatItem.updateItem(item); itemInfo.repeatItem.updateIndex(index); @@ -135,6 +138,7 @@ class __RepeatImpl { // TBD moveChild() only when item types are same // C++ mv from tempChildren[oldIndex] to end of children_ RepeatNative.moveChild(oldKeyIndex); + RepeatNative.reuse(oldKeyIndex); } else { // case #3: // new array item, there are no deleted array items diff --git a/frameworks/core/components_ng/syntax/repeat_model.h b/frameworks/core/components_ng/syntax/repeat_model.h index 40057fae425..c3a69b38891 100644 --- a/frameworks/core/components_ng/syntax/repeat_model.h +++ b/frameworks/core/components_ng/syntax/repeat_model.h @@ -39,7 +39,10 @@ public: virtual void MoveChild(uint32_t fromIndex) = 0; virtual void CreateNewChildStart(const std::string& key) = 0; virtual void CreateNewChildFinish(const std::string& key) = 0; + virtual void RecycleChild(uint32_t index) = 0; + virtual void ReuseChild(uint32_t index) = 0; virtual void AfterAddChild() = 0; + virtual void OnMove(std::function&& onMove) = 0; virtual void SetItemDragHandler(std::function&& onLongPress, std::function&& onDragStart, std::function&& onMoveThrough, diff --git a/frameworks/core/components_ng/syntax/repeat_model_ng.cpp b/frameworks/core/components_ng/syntax/repeat_model_ng.cpp index 8a4becb94c4..4656f6b9c05 100644 --- a/frameworks/core/components_ng/syntax/repeat_model_ng.cpp +++ b/frameworks/core/components_ng/syntax/repeat_model_ng.cpp @@ -71,6 +71,22 @@ void RepeatModelNG::CreateNewChildFinish(const std::string& key) stack->PopContainer(); } +void RepeatModelNG::RecycleChild(uint32_t index) +{ + auto* stack = ViewStackProcessor::GetInstance(); + auto node = AceType::DynamicCast(stack->GetMainElementNode()); + CHECK_NULL_VOID(node); + node->RecycleChild(index); +} + +void RepeatModelNG::ReuseChild(uint32_t index) +{ + auto* stack = ViewStackProcessor::GetInstance(); + auto node = AceType::DynamicCast(stack->GetMainElementNode()); + CHECK_NULL_VOID(node); + node->ReuseChild(index); +} + void RepeatModelNG::AfterAddChild() { auto* stack = ViewStackProcessor::GetInstance(); diff --git a/frameworks/core/components_ng/syntax/repeat_model_ng.h b/frameworks/core/components_ng/syntax/repeat_model_ng.h index 8c09bfe6891..f8a5c4a4fc3 100644 --- a/frameworks/core/components_ng/syntax/repeat_model_ng.h +++ b/frameworks/core/components_ng/syntax/repeat_model_ng.h @@ -38,6 +38,8 @@ public: void MoveChild(uint32_t fromIndex) override; void CreateNewChildStart(const std::string& key) override; void CreateNewChildFinish(const std::string& key) override; + void RecycleChild(uint32_t index) override; + void ReuseChild(uint32_t index) override; void AfterAddChild() override; void OnMove(std::function&& onMove) override; diff --git a/frameworks/core/components_ng/syntax/repeat_node.cpp b/frameworks/core/components_ng/syntax/repeat_node.cpp index 6cb155b0092..17cb051f6ac 100644 --- a/frameworks/core/components_ng/syntax/repeat_node.cpp +++ b/frameworks/core/components_ng/syntax/repeat_node.cpp @@ -84,6 +84,22 @@ void RepeatNode::FinishRepeatRender(std::list& removedElmtId) } } +void RepeatNode::RecycleChild(uint32_t index) +{ + if (index < tempChildrenOfRepeat_.size()) { + auto& node = tempChildrenOfRepeat_.at(index); + node->OnRecycle(); + } +} + +void RepeatNode::ReuseChild(uint32_t index) +{ + if (index < tempChildrenOfRepeat_.size()) { + auto& node = tempChildrenOfRepeat_.at(index); + node->OnReuse(); + } +} + void RepeatNode::AfterAddChild() { if (!ModifyChildren().empty()) { diff --git a/frameworks/core/components_ng/syntax/repeat_node.h b/frameworks/core/components_ng/syntax/repeat_node.h index 947f9943934..e80450b6390 100644 --- a/frameworks/core/components_ng/syntax/repeat_node.h +++ b/frameworks/core/components_ng/syntax/repeat_node.h @@ -63,6 +63,9 @@ public: ids_ = std::move(ids); } + void ReuseChild(uint32_t index); + void RecycleChild(uint32_t index); + void AfterAddChild(); void SetOnMove(std::function&& onMove); void SetItemDragHandler(std::function&& onLongPress, std::function&& onDragStart, -- Gitee