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 42 // removed_items is a Set of elmtId and UINode TAG 43 // The TAG aims easier analysis for DFX and debug 44 // This std::pair needs a custom has function 45 struct deleted_element_hash { operatordeleted_element_hash46 inline std::size_t operator()(const std::pair<ElementIdType, std::string>& v) const 47 { 48 return v.first; 49 } 50 }; 51 52 using RemovedElementsType = std::unordered_set<std::pair<ElementIdType, std::string>, deleted_element_hash>; 53 54 class ACE_EXPORT ElementRegister { 55 public: 56 static constexpr ElementIdType UndefinedElementId = static_cast<ElementIdType>(-1); 57 58 static ElementRegister* GetInstance(); 59 RefPtr<Element> GetElementById(ElementIdType elementId); 60 RefPtr<V2::ElementProxy> GetElementProxyById(ElementIdType elementId); 61 62 RefPtr<AceType> GetNodeById(ElementIdType elementId); 63 /** 64 * version of GetNodeById(elmtId) function to return an Element of 65 * given class. returns nullptr if Element with this elmtId baddest found 66 * or class mismatch 67 */ 68 template<class E> GetSpecificItemById(ElementIdType elmtId)69 RefPtr<E> GetSpecificItemById(ElementIdType elmtId) 70 { 71 return AceType::DynamicCast<E>(GetNodeById(elmtId)); 72 } 73 74 bool AddElementProxy(const WeakPtr<V2::ElementProxy>& element); 75 bool AddElement(const RefPtr<Element>& element); 76 77 RefPtr<NG::UINode> GetUINodeById(ElementIdType elementId); 78 bool AddUINode(const RefPtr<NG::UINode>& node); 79 80 bool Exists(ElementIdType elementId); 81 82 /** 83 * When a custom node is created from recycle, update its element id. 84 */ 85 void UpdateRecycleElmtId(int32_t oldElmtId, int32_t newElmtId); 86 87 /** 88 * remove Element with given elmtId from the Map 89 * means GetElementById on this elmtId no longer returns an Element 90 * method adds the elmtId to the removed Element Set 91 */ 92 bool RemoveItem(ElementIdType elementId, const std::string& tag = std::string("undefined TAG")); 93 94 /** 95 * remove Element with given elmtId from the Map 96 * means GetElementById on this elmtId no longer returns an Element 97 * method does NOT add the elmtId to the removed Element Set 98 * Use with caution: e.g. only use when knowing the Element will 99 * be added with new ElementId shortly 100 */ 101 bool RemoveItemSilently(ElementIdType elementId); 102 103 void MoveRemovedItems(RemovedElementsType& removedItems); 104 105 /** 106 * does a complete reset 107 * clears the Map of Elements and Set of removed Elements 108 */ 109 void Clear(); 110 MakeUniqueId()111 ElementIdType MakeUniqueId() 112 { 113 return nextUniqueElementId_++; 114 } 115 116 RefPtr<NG::GeometryTransition> GetOrCreateGeometryTransition( 117 const std::string& id, bool followWithoutTransition = false); 118 void DumpGeometryTransition(); 119 120 void ReSyncGeometryTransition(const WeakPtr<NG::FrameNode>& trigger = nullptr, 121 const AnimationOption& option = AnimationOption()); 122 123 void AddPendingRemoveNode(const RefPtr<NG::UINode>& node); 124 void ClearPendingRemoveNodes(); 125 RegisterJSCleanUpIdleTaskFunc(const std::function<void (void)> & jsCallback)126 void RegisterJSCleanUpIdleTaskFunc(const std::function<void(void)>& jsCallback) { 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 RemovedElementsType removedItems_; 154 155 std::unordered_map<std::string, RefPtr<NG::GeometryTransition>> geometryTransitionMap_; 156 157 std::list<RefPtr<NG::UINode>> pendingRemoveNodes_; 158 159 std::function<void(void)> jsCleanUpIdleTaskCallback_; 160 161 ACE_DISALLOW_COPY_AND_MOVE(ElementRegister); 162 }; 163 } // namespace OHOS::Ace 164 #endif 165