Add API to UpdateProxy
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-proxy-impl.cpp
1 /*
2  * Copyright (c) 2022 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::GetWorldPositionScaleAndSize(uint32_t id, Vector3& position, Vector3& scale, Vector3& size) 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     const Matrix&                       worldMatrix      = transformManager.GetWorldMatrix(node->GetTransformId());
165
166     Quaternion orientation;
167     worldMatrix.GetTransformComponents(position, orientation, scale);
168
169     size    = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
170     success = true;
171   }
172   return success;
173 }
174
175 bool UpdateProxy::GetScale(uint32_t id, Vector3& scale) const
176 {
177   bool                    success = false;
178   const SceneGraph::Node* node    = GetNodeWithId(id);
179   if(node)
180   {
181     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
182     scale                                                = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE);
183     success                                              = true;
184   }
185
186   return success;
187 }
188
189 bool UpdateProxy::SetScale(uint32_t id, const Vector3& scale)
190 {
191   bool              success = false;
192   SceneGraph::Node* node    = GetNodeWithId(id);
193   if(node)
194   {
195     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
196     success = true;
197   }
198   return success;
199 }
200
201 bool UpdateProxy::BakeScale(uint32_t id, const Vector3& scale)
202 {
203   bool              success = false;
204   SceneGraph::Node* node    = GetNodeWithId(id);
205   if(node)
206   {
207     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
208     success = true;
209   }
210   return success;
211 }
212
213 bool UpdateProxy::GetColor(uint32_t id, Vector4& color) const
214 {
215   bool                    success = false;
216   const SceneGraph::Node* node    = GetNodeWithId(id);
217   if(node)
218   {
219     color   = node->mColor.Get(mCurrentBufferIndex);
220     success = true;
221   }
222
223   return success;
224 }
225
226 bool UpdateProxy::SetColor(uint32_t id, const Vector4& color)
227 {
228   bool              success = false;
229   SceneGraph::Node* node    = GetNodeWithId(id);
230   if(node)
231   {
232     node->mColor.Set(mCurrentBufferIndex, color);
233     node->SetDirtyFlag(SceneGraph::NodePropertyFlags::COLOR);
234     mDirtyNodes.push_back(id);
235     AddResetter(*node, node->mColor);
236     success = true;
237   }
238   return success;
239 }
240
241 bool UpdateProxy::BakeColor(uint32_t id, const Vector4& color)
242 {
243   bool              success = false;
244   SceneGraph::Node* node    = GetNodeWithId(id);
245   if(node)
246   {
247     node->mColor.Bake(mCurrentBufferIndex, color);
248     success = true;
249   }
250   return success;
251 }
252
253 void UpdateProxy::NodeHierarchyChanged()
254 {
255   mLastCachedIdNodePair = {0u, nullptr};
256   mNodeContainer.clear();
257   mPropertyModifier.reset();
258 }
259
260 SceneGraph::Node* UpdateProxy::GetNodeWithId(uint32_t id) const
261 {
262   SceneGraph::Node* node = nullptr;
263
264   // Cache the last accessed node so we don't have to traverse
265   if(mLastCachedIdNodePair.node && mLastCachedIdNodePair.id == id)
266   {
267     node = mLastCachedIdNodePair.node;
268   }
269   else
270   {
271     // Find node in vector
272     for(auto&& pair : mNodeContainer)
273     {
274       if(pair.id == id)
275       {
276         node                  = pair.node;
277         mLastCachedIdNodePair = pair;
278         break;
279       }
280     }
281
282     if(!node)
283     {
284       // Node not in vector, find in scene-graph
285       node = FindNodeInSceneGraph(id, mRootNode);
286       if(node)
287       {
288         mNodeContainer.push_back({id, node});
289         mLastCachedIdNodePair = *mNodeContainer.rbegin();
290       }
291     }
292   }
293
294   return node;
295 }
296
297 void UpdateProxy::AddResetter(SceneGraph::Node& node, SceneGraph::PropertyBase& propertyBase)
298 {
299   if(!mPropertyModifier)
300   {
301     mPropertyModifier = PropertyModifierPtr(new PropertyModifier(mUpdateManager));
302   }
303   mPropertyModifier->AddResetter(node, propertyBase);
304 }
305
306 void UpdateProxy::AddNodeResetters()
307 {
308   for(auto&& id : mDirtyNodes)
309   {
310     SceneGraph::Node* node = FindNodeInSceneGraph(id, mRootNode);
311     if(node)
312     {
313       mUpdateManager.AddNodeResetter(*node);
314     }
315   }
316 }
317
318 } // namespace Internal
319
320 } // namespace Dali