Keep node by id + Make SceneGraphTraveler don't travel anymore
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-proxy-impl.cpp
1 /*
2  * Copyright (c) 2024 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-manager.h>
23 #include <dali/internal/update/manager/update-proxy-property-modifier.h>
24
25 namespace Dali
26 {
27 namespace Internal
28 {
29 UpdateProxy::UpdateProxy(SceneGraph::UpdateManager& updateManager, SceneGraph::TransformManager& transformManager, SceneGraphTravelerInterfacePtr traveler)
30 : mLastCachedIdNodePair({0u, nullptr}),
31   mDirtyNodes(),
32   mCurrentBufferIndex(0u),
33   mUpdateManager(updateManager),
34   mTransformManager(transformManager),
35   mSceneGraphTraveler(traveler),
36   mPropertyModifier(nullptr)
37 {
38 }
39
40 UpdateProxy::~UpdateProxy() = default;
41
42 bool UpdateProxy::GetPosition(uint32_t id, Vector3& position) const
43 {
44   bool                    success = false;
45   const SceneGraph::Node* node    = GetNodeWithId(id);
46   if(node)
47   {
48     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
49     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
50     success                                              = true;
51   }
52   return success;
53 }
54
55 bool UpdateProxy::SetPosition(uint32_t id, const Vector3& position)
56 {
57   bool              success = false;
58   SceneGraph::Node* node    = GetNodeWithId(id);
59   if(node)
60   {
61     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
62     success = true;
63   }
64   return success;
65 }
66
67 bool UpdateProxy::BakePosition(uint32_t id, const Vector3& position)
68 {
69   bool              success = false;
70   SceneGraph::Node* node    = GetNodeWithId(id);
71   if(node)
72   {
73     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
74     success = true;
75   }
76   return success;
77 }
78
79 bool UpdateProxy::GetOrientation(uint32_t id, Quaternion& orientation) const
80 {
81   bool                    success = false;
82   const SceneGraph::Node* node    = GetNodeWithId(id);
83   if(node)
84   {
85     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
86
87     orientation = transformManager.GetQuaternionPropertyValue(node->GetTransformId());
88     success     = true;
89   }
90   return success;
91 }
92
93 bool UpdateProxy::SetOrientation(uint32_t id, const Quaternion& orientation)
94 {
95   bool              success = false;
96   SceneGraph::Node* node    = GetNodeWithId(id);
97   if(node)
98   {
99     mTransformManager.SetQuaternionPropertyValue(node->GetTransformId(), orientation);
100     success = true;
101   }
102   return success;
103 }
104
105 bool UpdateProxy::BakeOrientation(uint32_t id, const Quaternion& orientation)
106 {
107   bool              success = false;
108   SceneGraph::Node* node    = GetNodeWithId(id);
109   if(node)
110   {
111     mTransformManager.BakeQuaternionPropertyValue(node->GetTransformId(), orientation);
112     success = true;
113   }
114   return success;
115 }
116
117 bool UpdateProxy::GetSize(uint32_t id, Vector3& size) const
118 {
119   bool                    success = false;
120   const SceneGraph::Node* node    = GetNodeWithId(id);
121   if(node)
122   {
123     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
124     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
125     success                                              = true;
126   }
127   return success;
128 }
129
130 bool UpdateProxy::SetSize(uint32_t id, const Vector3& size)
131 {
132   bool              success = false;
133   SceneGraph::Node* node    = GetNodeWithId(id);
134   if(node)
135   {
136     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
137     success = true;
138   }
139   return success;
140 }
141
142 bool UpdateProxy::BakeSize(uint32_t id, const Vector3& size)
143 {
144   bool              success = false;
145   SceneGraph::Node* node    = GetNodeWithId(id);
146   if(node)
147   {
148     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
149     success = true;
150   }
151   return success;
152 }
153
154 bool UpdateProxy::GetPositionAndSize(uint32_t id, Vector3& position, Vector3& size) const
155 {
156   bool                    success = false;
157   const SceneGraph::Node* node    = GetNodeWithId(id);
158   if(node)
159   {
160     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
161     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
162     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
163     success                                              = true;
164   }
165   return success;
166 }
167
168 bool UpdateProxy::GetWorldPositionScaleAndSize(uint32_t id, Vector3& position, Vector3& scale, Vector3& size) const
169 {
170   bool                    success = false;
171   const SceneGraph::Node* node    = GetNodeWithId(id);
172   if(node)
173   {
174     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
175     const Matrix&                       worldMatrix      = transformManager.GetWorldMatrix(node->GetTransformId());
176
177     Quaternion orientation;
178     worldMatrix.GetTransformComponents(position, orientation, scale);
179
180     size    = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
181     success = true;
182   }
183   return success;
184 }
185
186 bool UpdateProxy::GetWorldTransformAndSize(uint32_t id, Vector3& position, Vector3& scale, Quaternion& orientation, Vector3& size) const
187 {
188   bool                    success = false;
189   const SceneGraph::Node* node    = GetNodeWithId(id);
190   if(node)
191   {
192     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
193     const Matrix&                       worldMatrix      = transformManager.GetWorldMatrix(node->GetTransformId());
194
195     worldMatrix.GetTransformComponents(position, orientation, scale);
196     size    = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
197     success = true;
198   }
199   return success;
200 }
201
202 bool UpdateProxy::GetScale(uint32_t id, Vector3& scale) const
203 {
204   bool                    success = false;
205   const SceneGraph::Node* node    = GetNodeWithId(id);
206   if(node)
207   {
208     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
209     scale                                                = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE);
210     success                                              = true;
211   }
212
213   return success;
214 }
215
216 bool UpdateProxy::SetScale(uint32_t id, const Vector3& scale)
217 {
218   bool              success = false;
219   SceneGraph::Node* node    = GetNodeWithId(id);
220   if(node)
221   {
222     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
223     success = true;
224   }
225   return success;
226 }
227
228 bool UpdateProxy::BakeScale(uint32_t id, const Vector3& scale)
229 {
230   bool              success = false;
231   SceneGraph::Node* node    = GetNodeWithId(id);
232   if(node)
233   {
234     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
235     success = true;
236   }
237   return success;
238 }
239
240 bool UpdateProxy::GetColor(uint32_t id, Vector4& color) const
241 {
242   bool                    success = false;
243   const SceneGraph::Node* node    = GetNodeWithId(id);
244   if(node)
245   {
246     color   = node->mColor.Get(mCurrentBufferIndex);
247     success = true;
248   }
249
250   return success;
251 }
252
253 bool UpdateProxy::SetColor(uint32_t id, const Vector4& color)
254 {
255   bool              success = false;
256   SceneGraph::Node* node    = GetNodeWithId(id);
257   if(node)
258   {
259     node->mColor.Set(mCurrentBufferIndex, color);
260     node->SetDirtyFlag(SceneGraph::NodePropertyFlags::COLOR);
261     mDirtyNodes.push_back(id);
262     AddResetter(*node, node->mColor);
263     success = true;
264   }
265   return success;
266 }
267
268 bool UpdateProxy::BakeColor(uint32_t id, const Vector4& color)
269 {
270   bool              success = false;
271   SceneGraph::Node* node    = GetNodeWithId(id);
272   if(node)
273   {
274     node->mColor.Bake(mCurrentBufferIndex, color);
275     success = true;
276   }
277   return success;
278 }
279
280 void UpdateProxy::NodeHierarchyChanged()
281 {
282   mLastCachedIdNodePair = {0u, nullptr};
283   mPropertyModifier.reset();
284 }
285
286 void UpdateProxy::Notify(Dali::UpdateProxy::NotifySyncPoint syncPoint)
287 {
288   mSyncPoints.push_back(syncPoint);
289 }
290
291 Dali::UpdateProxy::NotifySyncPoint UpdateProxy::PopSyncPoint()
292 {
293   if(!mSyncPoints.empty())
294   {
295     auto syncPoint = mSyncPoints.front();
296     mSyncPoints.pop_front();
297     return syncPoint;
298   }
299
300   return Dali::UpdateProxy::INVALID_SYNC;
301 }
302
303 SceneGraph::Node* UpdateProxy::GetNodeWithId(uint32_t id) const
304 {
305   SceneGraph::Node* node = nullptr;
306
307   // Cache the last accessed node so we don't have to traverse
308   if(mLastCachedIdNodePair.node && mLastCachedIdNodePair.id == id)
309   {
310     node = mLastCachedIdNodePair.node;
311   }
312   else
313   {
314     node = mSceneGraphTraveler->FindNode(id);
315
316     if(node)
317     {
318       mLastCachedIdNodePair = {id, node};
319     }
320   }
321
322   return node;
323 }
324
325 void UpdateProxy::AddResetter(SceneGraph::Node& node, SceneGraph::PropertyBase& propertyBase)
326 {
327   if(!mPropertyModifier)
328   {
329     mPropertyModifier = PropertyModifierPtr(new PropertyModifier(mUpdateManager));
330   }
331   mPropertyModifier->AddResetter(node, propertyBase);
332 }
333
334 void UpdateProxy::AddNodeResetters()
335 {
336   for(auto&& id : mDirtyNodes)
337   {
338     SceneGraph::Node* node = GetNodeWithId(id);
339     if(node)
340     {
341       mUpdateManager.AddNodeResetter(*node);
342     }
343   }
344 }
345
346 } // namespace Internal
347
348 } // namespace Dali