Add a mechanism to specify a callback on every frame
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-proxy-impl.cpp
1 /*
2  * Copyright (c) 2018 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 namespace Dali
22 {
23
24 namespace Internal
25 {
26
27 namespace
28 {
29
30 SceneGraph::Node* FindNodeInSceneGraph( unsigned int id, SceneGraph::Node& node )
31 {
32   SceneGraph::Node* matchingNode = NULL;
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::TransformManager& transformManager, SceneGraph::Node& rootNode )
56 : mNodeContainer(),
57   mLastCachedIdNodePair( { 0u, NULL } ),
58   mCurrentBufferIndex( 0u ),
59   mTransformManager( transformManager ),
60   mRootNode( rootNode )
61 {
62 }
63
64 UpdateProxy::~UpdateProxy()
65 {
66 }
67
68 Vector3 UpdateProxy::GetPosition( unsigned int id ) const
69 {
70   const Dali::Matrix& matrix = GetWorldMatrix( id );
71   return matrix.GetTranslation3();
72 }
73
74 void UpdateProxy::SetPosition( unsigned int id, const Vector3& position )
75 {
76   const SceneGraph::Node* node = GetNodeWithId( id );
77   if( node )
78   {
79     Matrix& matrix = mTransformManager.GetWorldMatrix( node->mTransformId );
80     matrix.SetTranslation( position );
81   }
82 }
83
84 const Vector3& UpdateProxy::GetSize( unsigned int id ) const
85 {
86   const SceneGraph::Node* node = GetNodeWithId( id );
87   if( node )
88   {
89     return mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE );
90   }
91
92   return Vector3::ZERO;
93 }
94
95 void UpdateProxy::SetSize( unsigned int id, const Vector3& size )
96 {
97   SceneGraph::Node* node = GetNodeWithId( id );
98   if( node )
99   {
100     mTransformManager.SetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE, size );
101   }
102 }
103
104 void UpdateProxy::GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const
105 {
106   Matrix worldMatrix( false );
107   GetWorldMatrixAndSize( id, worldMatrix, size );
108   position = worldMatrix.GetTranslation3();
109 }
110
111 Vector4 UpdateProxy::GetWorldColor( unsigned int id ) const
112 {
113   SceneGraph::Node* node = GetNodeWithId( id );
114   if( node )
115   {
116     return node->mWorldColor.Get( mCurrentBufferIndex );
117   }
118
119   return Vector4::ZERO;
120 }
121
122 void UpdateProxy::SetWorldColor( unsigned int id, const Vector4& color ) const
123 {
124   SceneGraph::Node* node = GetNodeWithId( id );
125   if( node )
126   {
127     Vector4& currentColor = node->mWorldColor.Get( mCurrentBufferIndex );
128     currentColor = color;
129   }
130 }
131
132 void UpdateProxy::GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const
133 {
134   const SceneGraph::Node* node = GetNodeWithId( id );
135   if( node )
136   {
137     mTransformManager.GetWorldMatrixAndSize( node->mTransformId, worldMatrix, size );
138   }
139 }
140
141 const Matrix& UpdateProxy::GetWorldMatrix( unsigned int id ) const
142 {
143   const SceneGraph::Node* node = GetNodeWithId( id );
144   if( node )
145   {
146     return mTransformManager.GetWorldMatrix( node->mTransformId );
147   }
148
149   return Matrix::IDENTITY;
150 }
151
152 void UpdateProxy::SetWorldMatrix( unsigned int id, const Matrix& worldMatrix )
153 {
154   SceneGraph::Node* node = GetNodeWithId( id );
155   if( node )
156   {
157     Matrix& currentMatrix = mTransformManager.GetWorldMatrix( node->mTransformId );
158     currentMatrix = worldMatrix;
159   }
160 }
161
162 SceneGraph::Node* UpdateProxy::GetNodeWithId( unsigned int id ) const
163 {
164   SceneGraph::Node* node = NULL;
165
166   // Cache the last accessed node so we don't have to traverse
167   if( mLastCachedIdNodePair.node && mLastCachedIdNodePair.id == id )
168   {
169     node = mLastCachedIdNodePair.node;
170   }
171   else
172   {
173     // Find node in vector
174     for( auto&& pair : mNodeContainer )
175     {
176       if( pair.id == id )
177       {
178         node = pair.node;
179         mLastCachedIdNodePair = pair;
180         break;
181       }
182     }
183
184     if( ! node )
185     {
186       // Node not in vector, find in scene-graph
187       node = FindNodeInSceneGraph( id, mRootNode );
188       if( node )
189       {
190         mNodeContainer.push_back( { id, node } );
191         mLastCachedIdNodePair = *mNodeContainer.rbegin();
192       }
193     }
194   }
195
196   return node;
197 }
198
199 } // namespace Internal
200
201 } // namespace Dali