1 /* 2 * Copyright (c) 2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_ELEMENT_REGISTER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_ELEMENT_REGISTER_H 18 19 #include <mutex> 20 #include <unordered_map> 21 #include <unordered_set> 22 #include <list> 23 #include <functional> 24 #include "base/memory/referenced.h" 25 #include "frameworks/base/memory/ace_type.h" 26 #include "frameworks/core/components_ng/animation/geometry_transition.h" 27 28 namespace OHOS::Ace::V2 { 29 class ElementProxy; 30 } // namespace OHOS::Ace::V2 31 32 namespace OHOS::Ace::NG { 33 class UINode; 34 class FrameNode; 35 } // namespace OHOS::Ace::NG 36 37 namespace OHOS::Ace { 38 using ElementIdType = int32_t; 39 class Element; 40 41 // removed_items is a Set of elmtId and UINode TAG 42 // The TAG aims easier analysis for DFX and debug 43 // This std::pair needs a custom has function 44 struct deleted_element_hash { operatordeleted_element_hash45 inline std::size_t operator()(const std::pair<ElementIdType, std::string>& v) const 46 { 47 return v.first; 48 } 49 }; 50 51 using RemovedElementsType = std::unordered_set<std::pair<ElementIdType, std::string>, deleted_element_hash>; 52 53 class ACE_EXPORT ElementRegister { 54 public: 55 static constexpr ElementIdType UndefinedElementId = static_cast<ElementIdType>(-1); 56 57 static ElementRegister* GetInstance(); 58 RefPtr<Element> GetElementById(ElementIdType elementId); 59 RefPtr<V2::ElementProxy> GetElementProxyById(ElementIdType elementId); 60 61 RefPtr<AceType> GetNodeById(ElementIdType elementId); 62 /** 63 * version of GetNodeById(elmtId) function to return an Element of 64 * given class. returns nullptr if Element with this elmtId baddest found 65 * or class mismatch 66 */ 67 template<class E> GetSpecificItemById(ElementIdType elmtId)68 RefPtr<E> GetSpecificItemById(ElementIdType elmtId) 69 { 70 return AceType::DynamicCast<E>(GetNodeById(elmtId)); 71 } 72 73 bool AddElementProxy(const WeakPtr<V2::ElementProxy>& element); 74 bool AddElement(const RefPtr<Element>& element); 75 76 RefPtr<NG::UINode> GetUINodeById(ElementIdType elementId); 77 bool AddUINode(const RefPtr<NG::UINode>& node); 78 79 bool Exists(ElementIdType elementId); 80 81 /** 82 * When a custom node is created from recycle, update its element id. 83 */ 84 void UpdateRecycleElmtId(int32_t oldElmtId, int32_t newElmtId); 85 86 /** 87 * remove Element with given elmtId from the Map 88 * means GetElementById on this elmtId no longer returns an Element 89 * method adds the elmtId to the removed Element Set 90 */ 91 bool RemoveItem(ElementIdType elementId, const std::string& tag = std::string("undefined TAG")); 92 93 /** 94 * remove Element with given elmtId from the Map 95 * means GetElementById on this elmtId no longer returns an Element 96 * method does NOT add the elmtId to the removed Element Set 97 * Use with caution: e.g. only use when knowing the Element will 98 * be added with new ElementId shortly 99 */ 100 bool RemoveItemSilently(ElementIdType elementId); 101 102 void MoveRemovedItems(RemovedElementsType& removedItems); 103 104 /** 105 * does a complete reset 106 * clears the Map of Elements and Set of removed Elements 107 */ 108 void Clear(); 109 MakeUniqueId()110 ElementIdType MakeUniqueId() 111 { 112 return nextUniqueElementId_++; 113 } 114 115 RefPtr<NG::GeometryTransition> GetOrCreateGeometryTransition(const std::string& id, 116 const WeakPtr<NG::FrameNode>& frameNode, 117 bool followWithoutTransition = false); 118 void DumpGeometryTransition(); 119 120 void ReSyncGeometryTransition(); 121 122 void AddPendingRemoveNode(const RefPtr<NG::UINode>& node); 123 void ClearPendingRemoveNodes(); 124 RegisterJSCleanUpIdleTaskFunc(const std::function<void (void)> & jsCallback)125 void RegisterJSCleanUpIdleTaskFunc(const std::function<void(void)>& jsCallback) { 126 LOGD("RegisterJSCleanUpIdleTaskFunc registered"); 127 jsCleanUpIdleTaskCallback_ = std::move(jsCallback); 128 } 129 CallJSCleanUpIdleTaskFunc()130 void CallJSCleanUpIdleTaskFunc() { 131 if (jsCleanUpIdleTaskCallback_) { 132 jsCleanUpIdleTaskCallback_(); 133 } 134 } 135 136 private: 137 // private constructor 138 ElementRegister() = default; 139 140 bool AddReferenced(ElementIdType elmtId, const WeakPtr<AceType>& referenced); 141 142 // Singleton instance 143 static thread_local ElementRegister* instance_; 144 static std::mutex mutex_; 145 146 // ElementID assigned during initial render 147 // first to Component, then synced to Element 148 ElementIdType nextUniqueElementId_ = 0; 149 150 // Map for created elements 151 std::unordered_map<ElementIdType, WeakPtr<AceType>> itemMap_; 152 153 // Set of removed Elements (not in itemMap_ anymore) 154 RemovedElementsType removedItems_; 155 156 std::unordered_map<std::string, RefPtr<NG::GeometryTransition>> geometryTransitionMap_; 157 158 std::list<RefPtr<NG::UINode>> pendingRemoveNodes_; 159 160 std::function<void(void)> jsCleanUpIdleTaskCallback_; 161 162 ACE_DISALLOW_COPY_AND_MOVE(ElementRegister); 163 }; 164 } // namespace OHOS::Ace 165 #endif 166