30bf0f32a6e3e61c55452e2650de219bd9e5d351
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / scene-graph-traveler.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/scene-graph-traveler.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/update/nodes/node.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 SceneGraphTraveler::SceneGraphTraveler(SceneGraph::Node& rootNode)
29 : mRootNode(rootNode),
30   mNodeStack{},
31   mInvalidated{false}
32 {
33   mRootNode.AddObserver(*this);
34   Clear();
35 }
36
37 SceneGraphTraveler::~SceneGraphTraveler()
38 {
39   if(!mInvalidated)
40   {
41     mRootNode.RemoveObserver(*this);
42   }
43 }
44
45 SceneGraph::Node* SceneGraphTraveler::FindNode(uint32_t id)
46 {
47   SceneGraph::Node* node = nullptr;
48
49   // Find node in cached map
50   auto iter = mTravledNodeMap.find(id);
51   if(iter != mTravledNodeMap.end())
52   {
53     node = iter->second;
54   }
55   else
56   {
57     while(!FullSearched())
58     {
59       SceneGraph::Node& currentNode = GetCurrentNode();
60       IterateNextNode();
61
62       // Cache traveled node and id pair.
63       mTravledNodeMap.insert({currentNode.mId, &currentNode});
64
65       if(currentNode.mId == id)
66       {
67         node = &currentNode;
68         break;
69       }
70     }
71   }
72
73   return node;
74 }
75
76 void SceneGraphTraveler::Clear()
77 {
78   mTravledNodeMap.clear();
79   mTravledNodeMap.rehash(0u); ///< Note : We have to reduce capacity of hash map. Without this line, clear() API will be slow downed.
80   mNodeStack.clear();
81   if(!mInvalidated)
82   {
83     mNodeStack.emplace_back(&mRootNode, 0u);
84   }
85 }
86
87 bool SceneGraphTraveler::FullSearched() const
88 {
89   return mNodeStack.empty();
90 }
91
92 SceneGraph::Node& SceneGraphTraveler::GetCurrentNode()
93 {
94   DALI_ASSERT_DEBUG(!FullSearched());
95
96   return *(mNodeStack.back().first);
97 }
98
99 void SceneGraphTraveler::IterateNextNode()
100 {
101   while(!mNodeStack.empty())
102   {
103     auto&    currentNode       = *(mNodeStack.back().first);
104     uint32_t currentChildIndex = mNodeStack.back().second;
105
106     if(currentNode.GetChildren().Count() <= currentChildIndex)
107     {
108       mNodeStack.pop_back();
109       continue;
110     }
111     else
112     {
113       // Stack current child, and increase index
114       ++mNodeStack.back().second;
115       mNodeStack.emplace_back(currentNode.GetChildren()[currentChildIndex], 0u);
116       break;
117     }
118   }
119 }
120
121 } // namespace Internal
122
123 } // namespace Dali