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