f5a387e9b9f928868720512845773033d24c5f1e
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-proxy-impl.cpp
1 /*
2  * Copyright (c) 2021 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/update-proxy-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/update/manager/update-proxy-property-modifier.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace
29 {
30 SceneGraph::Node* FindNodeInSceneGraph(uint32_t id, SceneGraph::Node& node)
31 {
32   SceneGraph::Node* matchingNode = nullptr;
33
34   if(node.mId == id)
35   {
36     matchingNode = &node;
37   }
38   else
39   {
40     for(auto&& i : node.GetChildren())
41     {
42       matchingNode = FindNodeInSceneGraph(id, *i);
43       if(matchingNode)
44       {
45         break;
46       }
47     }
48   }
49
50   return matchingNode;
51 }
52
53 } // unnamed namespace
54
55 UpdateProxy::UpdateProxy(SceneGraph::UpdateManager& updateManager, SceneGraph::TransformManager& transformManager, SceneGraph::Node& rootNode)
56 : mNodeContainer(),
57   mLastCachedIdNodePair({0u, nullptr}),
58   mDirtyNodes(),
59   mCurrentBufferIndex(0u),
60   mUpdateManager(updateManager),
61   mTransformManager(transformManager),
62   mRootNode(rootNode),
63   mPropertyModifier(nullptr)
64 {
65 }
66
67 UpdateProxy::~UpdateProxy() = default;
68
69 bool UpdateProxy::GetPosition(uint32_t id, Vector3& position) const
70 {
71   bool                    success = false;
72   const SceneGraph::Node* node    = GetNodeWithId(id);
73   if(node)
74   {
75     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
76     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
77     success                                              = true;
78   }
79   return success;
80 }
81
82 bool UpdateProxy::SetPosition(uint32_t id, const Vector3& position)
83 {
84   bool              success = false;
85   SceneGraph::Node* node    = GetNodeWithId(id);
86   if(node)
87   {
88     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
89     success = true;
90   }
91   return success;
92 }
93
94 bool UpdateProxy::BakePosition(uint32_t id, const Vector3& position)
95 {
96   bool              success = false;
97   SceneGraph::Node* node    = GetNodeWithId(id);
98   if(node)
99   {
100     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
101     success = true;
102   }
103   return success;
104 }
105
106 bool UpdateProxy::GetSize(uint32_t id, Vector3& size) const
107 {
108   bool                    success = false;
109   const SceneGraph::Node* node    = GetNodeWithId(id);
110   if(node)
111   {
112     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
113     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
114     success                                              = true;
115   }
116   return success;
117 }
118
119 bool UpdateProxy::SetSize(uint32_t id, const Vector3& size)
120 {
121   bool              success = false;
122   SceneGraph::Node* node    = GetNodeWithId(id);
123   if(node)
124   {
125     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
126     success = true;
127   }
128   return success;
129 }
130
131 bool UpdateProxy::BakeSize(uint32_t id, const Vector3& size)
132 {
133   bool              success = false;
134   SceneGraph::Node* node    = GetNodeWithId(id);
135   if(node)
136   {
137     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
138     success = true;
139   }
140   return success;
141 }
142
143 bool UpdateProxy::GetPositionAndSize(uint32_t id, Vector3& position, Vector3& size) const
144 {
145   bool                    success = false;
146   const SceneGraph::Node* node    = GetNodeWithId(id);
147   if(node)
148   {
149     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
150     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
151     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
152     success                                              = true;
153   }
154   return success;
155 }
156
157 bool UpdateProxy::GetScale(uint32_t id, Vector3& scale) const
158 {
159   bool                    success = false;
160   const SceneGraph::Node* node    = GetNodeWithId(id);
161   if(node)
162   {
163     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
164     scale                                                = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE);
165     success                                              = true;
166   }
167
168   return success;
169 }
170
171 bool UpdateProxy::SetScale(uint32_t id, const Vector3& scale)
172 {
173   bool              success = false;
174   SceneGraph::Node* node    = GetNodeWithId(id);
175   if(node)
176   {
177     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
178     success = true;
179   }
180   return success;
181 }
182
183 bool UpdateProxy::BakeScale(uint32_t id, const Vector3& scale)
184 {
185   bool              success = false;
186   SceneGraph::Node* node    = GetNodeWithId(id);
187   if(node)
188   {
189     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
190     success = true;
191   }
192   return success;
193 }
194
195 bool UpdateProxy::GetColor(uint32_t id, Vector4& color) const
196 {
197   bool                    success = false;
198   const SceneGraph::Node* node    = GetNodeWithId(id);
199   if(node)
200   {
201     color   = node->mColor.Get(mCurrentBufferIndex);
202     success = true;
203   }
204
205   return success;
206 }
207
208 bool UpdateProxy::SetColor(uint32_t id, const Vector4& color)
209 {
210   bool              success = false;
211   SceneGraph::Node* node    = GetNodeWithId(id);
212   if(node)
213   {
214     node->mColor.Set(mCurrentBufferIndex, color);
215     node->SetDirtyFlag(SceneGraph::NodePropertyFlags::COLOR);
216     mDirtyNodes.push_back(id);
217     AddResetter(*node, node->mColor);
218     success = true;
219   }
220   return success;
221 }
222
223 bool UpdateProxy::BakeColor(uint32_t id, const Vector4& color)
224 {
225   bool              success = false;
226   SceneGraph::Node* node    = GetNodeWithId(id);
227   if(node)
228   {
229     node->mColor.Bake(mCurrentBufferIndex, color);
230     success = true;
231   }
232   return success;
233 }
234
235 void UpdateProxy::NodeHierarchyChanged()
236 {
237   mLastCachedIdNodePair = {0u, nullptr};
238   mNodeContainer.clear();
239   mPropertyModifier.reset();
240 }
241
242 SceneGraph::Node* UpdateProxy::GetNodeWithId(uint32_t id) const
243 {
244   SceneGraph::Node* node = nullptr;
245
246   // Cache the last accessed node so we don't have to traverse
247   if(mLastCachedIdNodePair.node && mLastCachedIdNodePair.id == id)
248   {
249     node = mLastCachedIdNodePair.node;
250   }
251   else
252   {
253     // Find node in vector
254     for(auto&& pair : mNodeContainer)
255     {
256       if(pair.id == id)
257       {
258         node                  = pair.node;
259         mLastCachedIdNodePair = pair;
260         break;
261       }
262     }
263
264     if(!node)
265     {
266       // Node not in vector, find in scene-graph
267       node = FindNodeInSceneGraph(id, mRootNode);
268       if(node)
269       {
270         mNodeContainer.push_back({id, node});
271         mLastCachedIdNodePair = *mNodeContainer.rbegin();
272       }
273     }
274   }
275
276   return node;
277 }
278
279 void UpdateProxy::AddResetter(SceneGraph::Node& node, SceneGraph::PropertyBase& propertyBase)
280 {
281   if(!mPropertyModifier)
282   {
283     mPropertyModifier = PropertyModifierPtr(new PropertyModifier(mUpdateManager));
284   }
285   mPropertyModifier->AddResetter(node, propertyBase);
286 }
287
288 void UpdateProxy::AddNodeResetters()
289 {
290   for(auto&& id : mDirtyNodes)
291   {
292     SceneGraph::Node* node = FindNodeInSceneGraph(id, mRootNode);
293     if(node)
294     {
295       mUpdateManager.AddNodeResetter(*node);
296     }
297   }
298 }
299
300 } // namespace Internal
301
302 } // namespace Dali