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 using RemovedElementsType = std::unordered_set<ElementIdType>;
42 
43 class ACE_EXPORT ElementRegister {
44 public:
45     static constexpr ElementIdType UndefinedElementId = static_cast<ElementIdType>(-1);
46 
47     ACE_FORCE_EXPORT static ElementRegister* GetInstance();
48     RefPtr<Element> GetElementById(ElementIdType elementId);
49     RefPtr<V2::ElementProxy> GetElementProxyById(ElementIdType elementId);
50 
51     ACE_FORCE_EXPORT RefPtr<AceType> GetNodeById(ElementIdType elementId);
52     /**
53      * version of GetNodeById(elmtId) function to return an Element of
54      * given class. returns nullptr if Element with this elmtId baddest found
55      * or class mismatch
56      */
57     template<class E>
GetSpecificItemById(ElementIdType elmtId)58     RefPtr<E> GetSpecificItemById(ElementIdType elmtId)
59     {
60         return AceType::DynamicCast<E>(GetNodeById(elmtId));
61     }
62 
63     bool AddElementProxy(const WeakPtr<V2::ElementProxy>& element);
64     bool AddElement(const RefPtr<Element>& element);
65 
66     RefPtr<NG::UINode> GetUINodeById(ElementIdType elementId);
67     NG::FrameNode* GetFrameNodePtrById(ElementIdType elementId);
68 
69     ACE_FORCE_EXPORT bool AddUINode(const RefPtr<NG::UINode>& node);
70 
71     bool Exists(ElementIdType elementId);
72 
73     /**
74      * When a custom node is created from recycle, update its element id.
75      */
76     void UpdateRecycleElmtId(int32_t oldElmtId, int32_t newElmtId);
77 
78     /**
79      * remove Element with given elmtId from the Map
80      * means GetElementById on this elmtId no longer returns an Element
81      * method adds the elmtId to the removed Element Set
82      */
83     bool RemoveItem(ElementIdType elementId);
84 
85     /**
86      * remove Element with given elmtId from the Map
87      * means GetElementById on this elmtId no longer returns an Element
88      * method does NOT add the elmtId to the removed Element Set
89      * Use with caution: e.g. only use when knowing the Element will
90      * be added with new ElementId shortly
91      */
92     ACE_FORCE_EXPORT bool RemoveItemSilently(ElementIdType elementId);
93 
94     void MoveRemovedItems(RemovedElementsType& removedItems);
95 
96     /**
97      * does a complete reset
98      * clears the Map of Elements and Set of removed Elements
99      */
100     void Clear();
101 
MakeUniqueId()102     ACE_FORCE_EXPORT ElementIdType MakeUniqueId()
103     {
104         return nextUniqueElementId_++;
105     }
106 
107     RefPtr<NG::GeometryTransition> GetOrCreateGeometryTransition(
108         const std::string& id, bool followWithoutTransition = false, bool doRegisterSharedTransition = true);
109     void DumpGeometryTransition();
110 
111     void ReSyncGeometryTransition(const WeakPtr<NG::FrameNode>& trigger = nullptr,
112                                   const AnimationOption& option = AnimationOption());
113 
114     void AddPendingRemoveNode(const RefPtr<NG::UINode>& node);
115     void ClearPendingRemoveNodes();
116 
RegisterJSCleanUpIdleTaskFunc(const std::function<void (void)> & jsCallback)117     void RegisterJSCleanUpIdleTaskFunc(const std::function<void(void)>& jsCallback) {
118         jsCleanUpIdleTaskCallback_ = std::move(jsCallback);
119     }
120 
CallJSCleanUpIdleTaskFunc()121     void CallJSCleanUpIdleTaskFunc() {
122         if (jsCleanUpIdleTaskCallback_) {
123             jsCleanUpIdleTaskCallback_();
124         }
125     }
126 
GetNodeNum()127     uint32_t GetNodeNum() const
128     {
129         return itemMap_.size();
130     }
131 
GetLastestElementId()132     ElementIdType GetLastestElementId() const
133     {
134         return lastestElementId_;
135     }
136 
137     RefPtr<NG::FrameNode> GetAttachedFrameNodeById(const std::string& key);
138 
139     void AddFrameNodeByInspectorId(const std::string& key, const WeakPtr<NG::FrameNode>& node);
140 
141     void RemoveFrameNodeByInspectorId(const std::string& key, int32_t nodeId);
142 
143 private:
144     // private constructor
145     ElementRegister() = default;
146 
147     bool AddReferenced(ElementIdType elmtId, const WeakPtr<AceType>& referenced);
148 
149     //  Singleton instance
150     static thread_local ElementRegister* instance_;
151     static std::mutex mutex_;
152 
153     // ElementID assigned during initial render
154     // first to Component, then synced to Element
155     ElementIdType nextUniqueElementId_ = 0;
156 
157     ElementIdType lastestElementId_ = 0;
158 
159     // Map for created elements
160     std::unordered_map<ElementIdType, WeakPtr<AceType>> itemMap_;
161 
162     // Map for inspectorId
163     std::unordered_map<std::string, std::list<WeakPtr<NG::FrameNode>>> inspectorIdMap_;
164 
165     RemovedElementsType removedItems_;
166 
167     std::unordered_map<std::string, RefPtr<NG::GeometryTransition>> geometryTransitionMap_;
168 
169     std::list<RefPtr<NG::UINode>> pendingRemoveNodes_;
170 
171     std::function<void(void)> jsCleanUpIdleTaskCallback_;
172 
173     ACE_DISALLOW_COPY_AND_MOVE(ElementRegister);
174 };
175 } // namespace OHOS::Ace
176 #endif
177