• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/interfaces/native/node/node_adapter_impl.h"
17 
18 #include "core/components_ng/syntax/lazy_for_each_node.h"
19 
20 struct _ArkUINodeAdapter {
21     OHOS::Ace::RefPtr<OHOS::Ace::NG::NativeLazyForEachBuilder> builder;
22     OHOS::Ace::RefPtr<OHOS::Ace::NG::LazyForEachNode> node;
23 };
24 
25 namespace OHOS::Ace::NG {
26 
RegisterDataChangeListener(const RefPtr<V2::DataChangeListener> & listener)27 void NativeLazyForEachBuilder::RegisterDataChangeListener(const RefPtr<V2::DataChangeListener>& listener)
28 {
29     listener_ = RawPtr(listener);
30     if (!receiver_) {
31         return;
32     }
33     ArkUINodeAdapterEvent event { .type = ON_ATTACH_TO_NODE };
34     event.extraParam = reinterpret_cast<intptr_t>(userData_);
35     auto lazyForEachNode = DynamicCast<LazyForEachNode>(listener);
36     if (lazyForEachNode) {
37         auto parent = lazyForEachNode->GetParent();
38         if (parent) {
39             event.handle = reinterpret_cast<ArkUINodeHandle>(RawPtr(parent));
40         }
41     }
42     receiver_(&event);
43 }
44 
UnregisterDataChangeListener(V2::DataChangeListener * listener)45 void NativeLazyForEachBuilder::UnregisterDataChangeListener(V2::DataChangeListener* listener)
46 {
47     listener_ = nullptr;
48     if (!receiver_) {
49         return;
50     }
51     ArkUINodeAdapterEvent event { .type = ON_DETACH_FROM_NODE };
52     event.extraParam = reinterpret_cast<intptr_t>(userData_);
53     receiver_(&event);
54 }
55 
OnGetTotalCount()56 int32_t NativeLazyForEachBuilder::OnGetTotalCount()
57 {
58     return totalCount_;
59 }
60 
OnGetChildByIndex(int32_t index,std::unordered_map<std::string,LazyForEachCacheChild> & cachedItems)61 LazyForEachChild NativeLazyForEachBuilder::OnGetChildByIndex(
62     int32_t index, std::unordered_map<std::string, LazyForEachCacheChild>& cachedItems)
63 {
64     LazyForEachChild child;
65     if (!receiver_) {
66         return child;
67     }
68     ArkUINodeAdapterEvent getIdevent { .index = index, .idSet = false, .type = ON_GET_NODE_ID, .nodeSet = false };
69     getIdevent.extraParam = reinterpret_cast<intptr_t>(userData_);
70     receiver_(&getIdevent);
71     std::string idStr;
72     if (getIdevent.idSet) {
73         idStr = std::to_string(getIdevent.id);
74     } else {
75         idStr = std::to_string(index);
76     }
77     child.first = idStr;
78     const auto& itemIter = cachedItems.find(idStr);
79     if (itemIter != cachedItems.end()) {
80         child.second = itemIter->second.second;
81         cachedItems.erase(itemIter);
82         // For not change C-API receiver
83         if (needUpdateEvent_) {
84             getIdevent.type = ON_UPDATE_NODE;
85             getIdevent.handle = reinterpret_cast<ArkUINodeHandle>(AceType::RawPtr(child.second));
86             if (!getIdevent.idSet) {
87                 getIdevent.id = index;
88             }
89             receiver_(&getIdevent);
90         }
91         FlushDirtyPropertyNodes(child.second);
92         return child;
93     }
94     ArkUINodeAdapterEvent getChildEvent {
95         .index = index, .id = getIdevent.id, .idSet = false, .type = ON_ADD_NODE_TO_ADAPTER, .nodeSet = false
96     };
97     getChildEvent.extraParam = reinterpret_cast<intptr_t>(userData_);
98     receiver_(&getChildEvent);
99     if (getChildEvent.nodeSet) {
100         child.second = Claim(reinterpret_cast<UINode*>(getChildEvent.handle));
101     }
102     FlushDirtyPropertyNodes(child.second);
103     return child;
104 }
105 
FlushDirtyPropertyNodes(const RefPtr<UINode> & node)106 void NativeLazyForEachBuilder::FlushDirtyPropertyNodes(const RefPtr<UINode>& node)
107 {
108     CHECK_NULL_VOID(node);
109     auto context = node->GetContext();
110     CHECK_NULL_VOID(context);
111     context->FlushDirtyPropertyNodes();
112 }
113 
OnItemDeleted(UINode * node,const std::string & key)114 void NativeLazyForEachBuilder::OnItemDeleted(UINode* node, const std::string& key)
115 {
116     if (!receiver_) {
117         return;
118     }
119     ArkUINodeAdapterEvent event {
120         .id = StringUtils::StringToInt(key), .idSet = false, .type = ON_REMOVE_NODE_FROM_ADAPTER, .nodeSet = false
121     };
122     event.extraParam = reinterpret_cast<intptr_t>(userData_);
123     event.handle = reinterpret_cast<ArkUINodeHandle>(node);
124     receiver_(&event);
125 }
126 
GetAllItem(ArkUINodeHandle ** items,ArkUI_Uint32 * size)127 ArkUI_Int32 NativeLazyForEachBuilder::GetAllItem(ArkUINodeHandle** items, ArkUI_Uint32* size)
128 {
129     std::vector<UINode*> childList;
130     GetAllItems(childList);
131     *size = childList.size();
132     *items = new ArkUINodeHandle[*size];
133     for (uint32_t i = 0; i < *size; i++) {
134         (*items)[i] = reinterpret_cast<ArkUINodeHandle>(childList[i]);
135     }
136     return ERROR_CODE_NO_ERROR;
137 }
138 
UINodeAdapter(ArkUINodeAdapterHandle handle)139 UINodeAdapter::UINodeAdapter(ArkUINodeAdapterHandle handle) : handle_(handle)
140 {
141     CHECK_NULL_VOID(handle_);
142     CHECK_NULL_VOID(handle_->builder);
143     handle_->builder->SetUserData(this);
144     handle_->builder->SetReceiver([](ArkUINodeAdapterEvent* event) {
145         CHECK_NULL_VOID(event);
146         auto adapter = reinterpret_cast<UINodeAdapter*>(event->extraParam);
147         if (adapter != nullptr) {
148             adapter->OnEventReceived(event);
149         }
150     });
151     handle_->builder->SetNeedUpdateEvent(true);
152 }
153 
~UINodeAdapter()154 UINodeAdapter::~UINodeAdapter()
155 {
156     if (handle_ != nullptr) {
157         delete handle_;
158         handle_ = nullptr;
159     }
160 }
161 
OnEventReceived(ArkUINodeAdapterEvent * event)162 void UINodeAdapter::OnEventReceived(ArkUINodeAdapterEvent* event)
163 {
164     switch (event->type) {
165         case ON_ATTACH_TO_NODE:
166             if (attachToNodeFunc_) {
167                 attachToNodeFunc_(event->handle);
168             }
169             break;
170         case ON_DETACH_FROM_NODE:
171             if (detachFromNodeFunc_) {
172                 detachFromNodeFunc_();
173             }
174             break;
175         case ON_GET_NODE_ID:
176             if (getChildIdFunc_) {
177                 auto id = getChildIdFunc_(event->index);
178                 event->idSet = true;
179                 event->id = id;
180             }
181             break;
182         case ON_ADD_NODE_TO_ADAPTER:
183             if (createNewChildFunc_) {
184                 auto handle = createNewChildFunc_(event->index);
185                 event->nodeSet = true;
186                 event->handle = handle;
187             }
188             break;
189         case ON_REMOVE_NODE_FROM_ADAPTER:
190             if (disposeChildFunc_) {
191                 disposeChildFunc_(event->handle, event->id);
192             }
193             break;
194         case ON_UPDATE_NODE:
195             if (updateChildFunc_) {
196                 updateChildFunc_(event->handle, event->id);
197             }
198             break;
199         default:
200             break;
201     }
202 }
203 
SetTotalNodeCount(uint32_t count)204 void UINodeAdapter::SetTotalNodeCount(uint32_t count)
205 {
206     CHECK_NULL_VOID(handle_);
207     CHECK_NULL_VOID(handle_->builder);
208     handle_->builder->SetNodeTotalCount(count);
209 }
210 
GetTotalNodeCount() const211 uint32_t UINodeAdapter::GetTotalNodeCount() const
212 {
213     CHECK_NULL_RETURN(handle_, 0);
214     CHECK_NULL_RETURN(handle_->builder, 0);
215     return handle_->builder->GetNodeTotalCount();
216 }
217 
NotifyItemReloaded()218 void UINodeAdapter::NotifyItemReloaded()
219 {
220     CHECK_NULL_VOID(handle_);
221     CHECK_NULL_VOID(handle_->builder);
222     handle_->builder->NotifyItemReloaded();
223 }
224 
NotifyItemChanged(uint32_t start,uint32_t count)225 void UINodeAdapter::NotifyItemChanged(uint32_t start, uint32_t count)
226 {
227     CHECK_NULL_VOID(handle_);
228     CHECK_NULL_VOID(handle_->builder);
229     handle_->builder->NotifyItemChanged(start, count);
230 }
231 
NotifyItemInserted(uint32_t start,uint32_t count)232 void UINodeAdapter::NotifyItemInserted(uint32_t start, uint32_t count)
233 {
234     CHECK_NULL_VOID(handle_);
235     CHECK_NULL_VOID(handle_->builder);
236     handle_->builder->NotifyItemInserted(start, count);
237 }
238 
NotifyItemMoved(uint32_t from,uint32_t to)239 void UINodeAdapter::NotifyItemMoved(uint32_t from, uint32_t to)
240 {
241     CHECK_NULL_VOID(handle_);
242     CHECK_NULL_VOID(handle_->builder);
243     handle_->builder->NotifyItemMoved(from, to);
244 }
245 
NotifyItemRemoved(uint32_t start,uint32_t count)246 void UINodeAdapter::NotifyItemRemoved(uint32_t start, uint32_t count)
247 {
248     CHECK_NULL_VOID(handle_);
249     CHECK_NULL_VOID(handle_->builder);
250     handle_->builder->NotifyItemRemoved(start, count);
251 }
252 
GetAllItems()253 std::vector<ArkUINodeHandle> UINodeAdapter::GetAllItems()
254 {
255     std::vector<ArkUINodeHandle> items;
256     CHECK_NULL_RETURN(handle_, items);
257     CHECK_NULL_RETURN(handle_->builder, items);
258 
259     ArkUINodeHandle* itemArray = nullptr;
260     uint32_t size = 0;
261     handle_->builder->GetAllItem(&itemArray, &size);
262     for (uint32_t i = 0; i < size; i++) {
263         items.push_back(itemArray[i]);
264     }
265     if (itemArray != nullptr) {
266         delete[] itemArray;
267     }
268     return items;
269 }
270 
271 } // namespace OHOS::Ace::NG
272 
273 namespace OHOS::Ace::NodeAdapter {
274 namespace {
275 
Create()276 ArkUINodeAdapterHandle Create()
277 {
278     auto* adapter = new _ArkUINodeAdapter { .builder = AceType::MakeRefPtr<NG::NativeLazyForEachBuilder>() };
279     adapter->builder->SetHostHandle(adapter);
280     return adapter;
281 }
282 
Dispose(ArkUINodeAdapterHandle handle)283 void Dispose(ArkUINodeAdapterHandle handle)
284 {
285     if (!handle) {
286         return;
287     }
288     if (handle->node) {
289         const auto& parent = handle->node->GetParent();
290         if (parent) {
291             parent->RemoveChild(handle->node);
292         }
293     }
294     if (handle->builder) {
295         handle->builder->SetHostHandle(nullptr);
296     }
297     delete handle;
298 }
299 
SetTotalNodeCount(ArkUINodeAdapterHandle handle,ArkUI_Uint32 size)300 ArkUI_Int32 SetTotalNodeCount(ArkUINodeAdapterHandle handle, ArkUI_Uint32 size)
301 {
302     if (handle) {
303         handle->builder->SetNodeTotalCount(size);
304         return ERROR_CODE_NO_ERROR;
305     }
306     return ERROR_CODE_PARAM_INVALID;
307 }
308 
GetTotalNodeCount(ArkUINodeAdapterHandle handle)309 ArkUI_Uint32 GetTotalNodeCount(ArkUINodeAdapterHandle handle)
310 {
311     if (handle) {
312         return handle->builder->GetNodeTotalCount();
313     }
314     return 0;
315 }
316 
RegisterEventReceiver(ArkUINodeAdapterHandle handle,void * userData,void (* receiver)(ArkUINodeAdapterEvent * event))317 ArkUI_Int32 RegisterEventReceiver(
318     ArkUINodeAdapterHandle handle, void* userData, void (*receiver)(ArkUINodeAdapterEvent* event))
319 {
320     if (!handle) {
321         return ERROR_CODE_PARAM_INVALID;
322     }
323     handle->builder->SetUserData(userData);
324     handle->builder->SetReceiver(receiver);
325     return ERROR_CODE_NO_ERROR;
326 }
327 
UnregisterEventReceiver(ArkUINodeAdapterHandle handle)328 void UnregisterEventReceiver(ArkUINodeAdapterHandle handle)
329 {
330     if (!handle) {
331         return;
332     }
333     handle->builder->SetUserData(nullptr);
334     handle->builder->SetReceiver(nullptr);
335 }
336 
NotifyItemReloaded(ArkUINodeAdapterHandle handle)337 ArkUI_Int32 NotifyItemReloaded(ArkUINodeAdapterHandle handle)
338 {
339     if (!handle) {
340         return ERROR_CODE_PARAM_INVALID;
341     }
342     return handle->builder->NotifyItemReloaded();
343 }
344 
NotifyItemChanged(ArkUINodeAdapterHandle handle,ArkUI_Uint32 startPosition,ArkUI_Uint32 itemCount)345 ArkUI_Int32 NotifyItemChanged(ArkUINodeAdapterHandle handle, ArkUI_Uint32 startPosition, ArkUI_Uint32 itemCount)
346 {
347     if (!handle) {
348         return ERROR_CODE_PARAM_INVALID;
349     }
350     return handle->builder->NotifyItemChanged(startPosition, itemCount);
351 }
352 
NotifyItemRemoved(ArkUINodeAdapterHandle handle,ArkUI_Uint32 startPosition,ArkUI_Uint32 itemCount)353 ArkUI_Int32 NotifyItemRemoved(ArkUINodeAdapterHandle handle, ArkUI_Uint32 startPosition, ArkUI_Uint32 itemCount)
354 {
355     if (!handle) {
356         return ERROR_CODE_PARAM_INVALID;
357     }
358     return handle->builder->NotifyItemRemoved(startPosition, itemCount);
359 }
360 
NotifyItemInserted(ArkUINodeAdapterHandle handle,ArkUI_Uint32 startPosition,ArkUI_Uint32 itemCount)361 ArkUI_Int32 NotifyItemInserted(ArkUINodeAdapterHandle handle, ArkUI_Uint32 startPosition, ArkUI_Uint32 itemCount)
362 {
363     if (!handle) {
364         return ERROR_CODE_PARAM_INVALID;
365     }
366     return handle->builder->NotifyItemInserted(startPosition, itemCount);
367 }
368 
NotifyItemMoved(ArkUINodeAdapterHandle handle,ArkUI_Uint32 from,ArkUI_Uint32 to)369 ArkUI_Int32 NotifyItemMoved(ArkUINodeAdapterHandle handle, ArkUI_Uint32 from, ArkUI_Uint32 to)
370 {
371     if (!handle) {
372         return ERROR_CODE_PARAM_INVALID;
373     }
374     return handle->builder->NotifyItemMoved(from, to);
375 }
376 
GetAllItem(ArkUINodeAdapterHandle handle,ArkUINodeHandle ** items,ArkUI_Uint32 * size)377 ArkUI_Int32 GetAllItem(ArkUINodeAdapterHandle handle, ArkUINodeHandle** items, ArkUI_Uint32* size)
378 {
379     if (!handle) {
380         return ERROR_CODE_PARAM_INVALID;
381     }
382     return handle->builder->GetAllItem(items, size);
383 }
384 
GetLazyForEachChildIndex(const RefPtr<NG::UINode> & node)385 int32_t GetLazyForEachChildIndex(const RefPtr<NG::UINode>& node)
386 {
387     int32_t index = 0;
388     for (const auto& iter : node->GetChildren()) {
389         if (AceType::InstanceOf<NG::LazyForEachNode>(iter)) {
390             return index;
391         }
392         index++;
393     }
394     return -1;
395 }
396 
AttachHostNode(ArkUINodeAdapterHandle handle,ArkUINodeHandle host)397 ArkUI_Bool AttachHostNode(ArkUINodeAdapterHandle handle, ArkUINodeHandle host)
398 {
399     CHECK_NULL_RETURN(handle, true);
400     CHECK_NULL_RETURN(host, true);
401     auto* uiNode = reinterpret_cast<NG::UINode*>(host);
402     // A NodeAdapter only allows binding to one LazyForEach
403     if (GetLazyForEachChildIndex(Referenced::Claim(uiNode)) != -1) {
404         return false;
405     }
406     if (!handle->node) {
407         handle->node =
408             NG::LazyForEachNode::CreateLazyForEachNode(ElementRegister::GetInstance()->MakeUniqueId(), handle->builder);
409     }
410     if (AceType::InstanceOf<NG::FrameNode>(uiNode)) {
411         auto* frameNode = reinterpret_cast<NG::FrameNode*>(uiNode);
412         if (frameNode->GetPattern()->OnAttachAdapter(Referenced::Claim(frameNode), handle->node)) {
413             return true;
414         } else if (frameNode->GetFirstChild() == nullptr) {
415             uiNode->AddChild(handle->node);
416             return true;
417         }
418     }
419     return false;
420 }
421 
DetachHostNode(ArkUINodeHandle host)422 void DetachHostNode(ArkUINodeHandle host)
423 {
424     CHECK_NULL_VOID(host);
425     auto* uiNode = reinterpret_cast<NG::UINode*>(host);
426     if (!AceType::InstanceOf<NG::FrameNode>(uiNode)) {
427         return;
428     }
429     auto* frameNode = reinterpret_cast<NG::FrameNode*>(uiNode);
430     // Component overload unbinding method, unbind LazyForEach according to your own specifications
431     if (frameNode->GetPattern()->DetachHostNodeAdapter(Referenced::Claim(frameNode))) {
432         return;
433     }
434     int32_t index = 0;
435     // The default first node is LazyForEach. If the LazyForEach node is not unbound
436     if (!AceType::InstanceOf<NG::LazyForEachNode>(uiNode->GetChildAtIndex(0))) {
437         index = GetLazyForEachChildIndex(Referenced::Claim(uiNode));
438     }
439     if (index == -1) {
440         return;
441     }
442     const auto& child = AceType::DynamicCast<NG::LazyForEachNode>(uiNode->GetChildAtIndex(index));
443     CHECK_NULL_VOID(child);
444     uiNode->RemoveChild(child);
445     const auto& builder = AceType::DynamicCast<NG::NativeLazyForEachBuilder>(child->GetBuilder());
446     CHECK_NULL_VOID(builder);
447     auto handle = builder->GetHostHandle();
448     CHECK_NULL_VOID(handle);
449     handle->node = nullptr;
450 }
451 
GetNodeAdapter(ArkUINodeHandle host)452 ArkUINodeAdapterHandle GetNodeAdapter(ArkUINodeHandle host)
453 {
454     CHECK_NULL_RETURN(host, nullptr);
455     auto* uiNode = reinterpret_cast<NG::UINode*>(host);
456     if (!AceType::InstanceOf<NG::FrameNode>(uiNode)) {
457         return nullptr;
458     }
459     ArkUINodeAdapterHandle handle = nullptr;
460     auto* frameNode = reinterpret_cast<NG::FrameNode*>(uiNode);
461     if (frameNode->GetPattern()->GetNodeAdapterComponent(handle, Referenced::Claim(frameNode))) {
462         return handle;
463     }
464     int32_t index = 0;
465     // The default first node is LazyForEach. If the LazyForEach node is not unbound
466     if (!AceType::InstanceOf<NG::LazyForEachNode>(uiNode->GetChildAtIndex(0))) {
467         index = GetLazyForEachChildIndex(Referenced::Claim(uiNode));
468     }
469     if (index == -1) {
470         return nullptr;
471     }
472     const auto& child = AceType::DynamicCast<NG::LazyForEachNode>(uiNode->GetChildAtIndex(index));
473     CHECK_NULL_RETURN(child, nullptr);
474     const auto& builder = AceType::DynamicCast<NG::NativeLazyForEachBuilder>(child->GetBuilder());
475     CHECK_NULL_RETURN(builder, nullptr);
476     return builder->GetHostHandle();
477 }
478 
GetNodeTypeInNodeAdapter(ArkUINodeAdapterHandle handle)479 ArkUI_CharPtr GetNodeTypeInNodeAdapter(ArkUINodeAdapterHandle handle)
480 {
481     CHECK_NULL_RETURN(handle, "");
482     CHECK_NULL_RETURN(handle->node, "");
483     static std::string nodeType = handle->node->GetTag();
484     return nodeType.c_str();
485 }
486 
FireArkUIObjectLifecycleCallback(void * data,ArkUINodeAdapterHandle handle)487 void FireArkUIObjectLifecycleCallback(void* data, ArkUINodeAdapterHandle handle)
488 {
489     CHECK_NULL_VOID(data);
490     CHECK_NULL_VOID(handle);
491     CHECK_NULL_VOID(handle->node);
492     auto context = handle->node->GetContext();
493     CHECK_NULL_VOID(context);
494     context->FireArkUIObjectLifecycleCallback(data);
495 }
496 } // namespace
497 
GetNodeAdapterAPI()498 const ArkUINodeAdapterAPI* GetNodeAdapterAPI()
499 {
500     CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
501     static const ArkUINodeAdapterAPI impl {
502         .create = Create,
503         .dispose = Dispose,
504         .setTotalNodeCount = SetTotalNodeCount,
505         .getTotalNodeCount = GetTotalNodeCount,
506         .registerEventReceiver = RegisterEventReceiver,
507         .unregisterEventReceiver = UnregisterEventReceiver,
508         .notifyItemReloaded = NotifyItemReloaded,
509         .notifyItemChanged = NotifyItemChanged,
510         .notifyItemRemoved = NotifyItemRemoved,
511         .notifyItemInserted = NotifyItemInserted,
512         .notifyItemMoved = NotifyItemMoved,
513         .getAllItem = GetAllItem,
514         .attachHostNode = AttachHostNode,
515         .detachHostNode = DetachHostNode,
516         .getNodeAdapter = GetNodeAdapter,
517         .getNodeType = GetNodeTypeInNodeAdapter,
518         .fireArkUIObjectLifecycleCallback = FireArkUIObjectLifecycleCallback
519     };
520     CHECK_INITIALIZED_FIELDS_END(impl, 0, 0, 0); // don't move this line
521     return &impl;
522 }
523 
GetCJUINodeAdapterAPI()524 const CJUINodeAdapterAPI* GetCJUINodeAdapterAPI()
525 {
526     CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
527     static const CJUINodeAdapterAPI impl {
528         .create = Create,
529         .dispose = Dispose,
530         .setTotalNodeCount = SetTotalNodeCount,
531         .getTotalNodeCount = GetTotalNodeCount,
532         .registerEventReceiver = RegisterEventReceiver,
533         .unregisterEventReceiver = UnregisterEventReceiver,
534         .notifyItemReloaded = NotifyItemReloaded,
535         .notifyItemChanged = NotifyItemChanged,
536         .notifyItemRemoved = NotifyItemRemoved,
537         .notifyItemInserted = NotifyItemInserted,
538         .notifyItemMoved = NotifyItemMoved,
539         .getAllItem = GetAllItem,
540         .attachHostNode = AttachHostNode,
541         .detachHostNode = DetachHostNode,
542         .getNodeAdapter = GetNodeAdapter
543     };
544     CHECK_INITIALIZED_FIELDS_END(impl, 0, 0, 0); // don't move this line
545     return &impl;
546 }
547 
548 } // namespace OHOS::Ace::NodeAdapter
549