Merge "Removed unnecessary code from Uint16Pair UTC" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / nodes / node.cpp
1 /*
2  * Copyright (c) 2014 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/nodes/node.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/update/node-attachments/node-attachment.h>
23 #include <dali/internal/update/common/discard-queue.h>
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/public-api/common/constants.h>
26 #include <dali/internal/common/internal-constants.h>
27
28 namespace Dali
29 {
30
31 namespace Internal
32 {
33
34 namespace SceneGraph
35 {
36
37 const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
38 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
39
40 Node* Node::New()
41 {
42   return new Node();
43 }
44
45 Node::Node()
46 : mParentOrigin( ParentOrigin::DEFAULT ),
47   mAnchorPoint( AnchorPoint::DEFAULT ),
48   mSize(),     // zero initialized by default
49   mPosition(), // zero initialized by default
50   mOrientation(), // initialized to identity by default
51   mScale( Vector3::ONE ),
52   mVisible( true ),
53   mColor( Color::WHITE ),
54   mWorldPosition(), // zero initialized by default
55   mWorldOrientation(), // initialized to identity by default
56   mWorldScale( Vector3::ONE ),
57   mWorldMatrix(),
58   mWorldColor( Color::WHITE ),
59   mParent( NULL ),
60   mExclusiveRenderTask( NULL ),
61   mAttachment( NULL ),
62   mChildren(),
63   mRegenerateUniformMap( 0 ),
64   mDepth(0u),
65   mDirtyFlags(AllFlags),
66   mIsRoot( false ),
67   mInheritOrientation( true ),
68   mInheritScale( true ),
69   mIsActive( true ),
70   mDrawMode( DrawMode::NORMAL ),
71   mPositionInheritanceMode( DEFAULT_POSITION_INHERITANCE_MODE ),
72   mColorMode( DEFAULT_COLOR_MODE )
73 {
74   mUniformMapChanged[0] = 0u;
75   mUniformMapChanged[1] = 0u;
76 }
77
78 Node::~Node()
79 {
80 }
81
82 void Node::OnDestroy()
83 {
84   // Node attachments should be notified about the disconnection.
85   if ( mAttachment )
86   {
87     mAttachment->OnDestroy();
88   }
89
90   // Animators, Constraints etc. should be disconnected from the child's properties.
91   PropertyOwner::Destroy();
92 }
93
94 void Node::Attach( NodeAttachment& object )
95 {
96   DALI_ASSERT_DEBUG(!mAttachment);
97
98   object.SetParent(*this);
99
100   mAttachment = &object;
101   SetAllDirtyFlags();
102
103   if( mIsActive )
104   {
105     mAttachment->ConnectedToSceneGraph();
106   }
107 }
108
109 void Node::SetRoot(bool isRoot)
110 {
111   DALI_ASSERT_DEBUG(!isRoot || mParent == NULL); // Root nodes cannot have a parent
112
113   mIsRoot = isRoot;
114 }
115
116 void Node::AddUniformMapping( UniformPropertyMapping* map )
117 {
118   PropertyOwner::AddUniformMapping( map );
119   mRegenerateUniformMap = 2;
120 }
121
122 void Node::RemoveUniformMapping( const std::string& uniformName )
123 {
124   PropertyOwner::RemoveUniformMapping( uniformName );
125   mRegenerateUniformMap = 2;
126 }
127
128 void Node::PrepareRender( BufferIndex bufferIndex )
129 {
130   if(mRegenerateUniformMap != 0 )
131   {
132     if( mRegenerateUniformMap == 2 )
133     {
134       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
135       localMap.Resize(0);
136
137       for( unsigned int i=0, count=mUniformMaps.Count(); i<count; ++i )
138       {
139         localMap.PushBack( &mUniformMaps[i] );
140       }
141     }
142     else if( mRegenerateUniformMap == 1 )
143     {
144       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
145       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-bufferIndex ];
146
147       localMap.Resize( oldMap.Count() );
148
149       unsigned int index=0;
150       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
151       {
152         localMap[index] = *iter;
153       }
154     }
155     --mRegenerateUniformMap;
156     mUniformMapChanged[bufferIndex] = 1u;
157   }
158 }
159
160 void Node::ConnectChild( Node* childNode )
161 {
162   DALI_ASSERT_ALWAYS( this != childNode );
163   DALI_ASSERT_ALWAYS( IsRoot() || NULL != mParent ); // Parent should be connected first
164   DALI_ASSERT_ALWAYS( !childNode->IsRoot() && NULL == childNode->GetParent() ); // Child should be disconnected
165
166   childNode->SetParent( *this );
167
168   // Everything should be reinherited when reconnected to scene-graph
169   childNode->SetAllDirtyFlags();
170
171   // Add the node to the end of the child list.
172   mChildren.PushBack( childNode );
173
174   // Inform property observers of new connection
175   childNode->ConnectToSceneGraph();
176
177   // Inform child node attachment that the node has been added to the stage
178   if( childNode->mAttachment )
179   {
180     childNode->mAttachment->ConnectedToSceneGraph();
181   }
182 }
183
184 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
185 {
186   DALI_ASSERT_ALWAYS( this != &childNode );
187   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
188
189   // Find the childNode and remove it
190   Node* found( NULL );
191
192   const NodeIter endIter = mChildren.End();
193   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
194   {
195     Node* current = *iter;
196     if ( current == &childNode )
197     {
198       found = current;
199       mChildren.Erase( iter ); // order matters here
200       break; // iter is no longer valid
201     }
202   }
203   DALI_ASSERT_ALWAYS( NULL != found );
204
205   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
206 }
207
208 void Node::RemoveRenderer( Renderer* renderer )
209 {
210   unsigned int rendererCount( mRenderer.Size() );
211   for( unsigned int i(0); i<rendererCount; ++i )
212   {
213     if( mRenderer[i] == renderer )
214     {
215       mRenderer.Erase( mRenderer.Begin()+i);
216       return;
217     }
218   }
219 }
220
221 int Node::GetDirtyFlags() const
222 {
223   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
224   int flags = mDirtyFlags;
225   const bool sizeFlag = mSize.IsClean();
226
227   if ( !(flags & TransformFlag) )
228   {
229     // Check whether the transform related properties have changed
230     if( !sizeFlag            ||
231         !mPosition.IsClean() ||
232         !mOrientation.IsClean() ||
233         !mScale.IsClean()    ||
234         mParentOrigin.InputChanged() || // parent origin and anchor point rarely change
235         mAnchorPoint.InputChanged() )
236     {
237       flags |= TransformFlag;
238     }
239   }
240
241   // Check whether the visible property has changed
242   if ( !mVisible.IsClean() )
243   {
244     flags |= VisibleFlag;
245   }
246
247   // Check whether the color property has changed
248   if ( !mColor.IsClean() )
249   {
250     flags |= ColorFlag;
251   }
252
253   // Check whether the size property has changed
254   if ( !sizeFlag )
255   {
256     flags |= SizeFlag;
257    }
258
259   return flags;
260 }
261
262 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
263 {
264   // clear dirty flags in parent origin & anchor point
265   mParentOrigin.Clear();
266   mAnchorPoint.Clear();
267   // Reset default properties
268   mSize.ResetToBaseValue( updateBufferIndex );
269   mPosition.ResetToBaseValue( updateBufferIndex );
270   mOrientation.ResetToBaseValue( updateBufferIndex );
271   mScale.ResetToBaseValue( updateBufferIndex );
272   mVisible.ResetToBaseValue( updateBufferIndex );
273   mColor.ResetToBaseValue( updateBufferIndex );
274
275   mDirtyFlags = NothingFlag;
276 }
277
278 void Node::SetParent(Node& parentNode)
279 {
280   DALI_ASSERT_ALWAYS(this != &parentNode);
281   DALI_ASSERT_ALWAYS(!mIsRoot);
282   DALI_ASSERT_ALWAYS(mParent == NULL);
283
284   mParent = &parentNode;
285   mDepth = mParent->GetDepth() + 1u;
286 }
287
288 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
289 {
290   DALI_ASSERT_ALWAYS(!mIsRoot);
291   DALI_ASSERT_ALWAYS(mParent != NULL);
292
293   const NodeIter endIter = mChildren.End();
294   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
295   {
296     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
297   }
298
299   // Animators, Constraints etc. should be disconnected from the child's properties.
300   PropertyOwner::DisconnectFromSceneGraph( updateBufferIndex );
301
302   // Remove back-pointer to parent
303   mParent = NULL;
304   mDepth = 0u;
305
306   // Remove all child pointers
307   mChildren.Clear();
308
309   // Inform child node attachment that the node has been removed from the stage
310   if( mAttachment )
311   {
312     mAttachment->DisconnectedFromSceneGraph();
313   }
314
315   // Move into disconnectedNodes
316   std::set<Node*>::size_type removed = connectedNodes.erase( this );
317   DALI_ASSERT_ALWAYS( removed );
318   disconnectedNodes.insert( this );
319 }
320
321 } // namespace SceneGraph
322
323 } // namespace Internal
324
325 } // namespace Dali