Align data members, pointers first, classes then, next built in types and flags last...
[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 Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/update/nodes/node.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/internal/update/node-attachments/node-attachment.h>
22 #include <dali/internal/update/common/discard-queue.h>
23 #include <dali/internal/render/shaders/shader.h>
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/public-api/common/constants.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 namespace SceneGraph
34 {
35
36 const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
37 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
38
39 Node* Node::New()
40 {
41   return new Node();
42 }
43
44 Node::Node()
45 : mParentOrigin( ParentOrigin::DEFAULT ),
46   mAnchorPoint( AnchorPoint::DEFAULT ),
47   mSize( Vector3::ZERO ),
48   mPosition( Vector3::ZERO ),
49   mRotation( Quaternion::IDENTITY ),
50   mScale( Vector3::ONE ),
51   mVisible( true ),
52   mColor( Color::WHITE ),
53   mWorldPosition( Vector3::ZERO ),
54   mWorldRotation( Quaternion::IDENTITY ),
55   mWorldScale( Vector3::ONE ),
56   mWorldMatrix( Matrix::IDENTITY ),
57   mWorldColor( Color::WHITE ),
58   mParent( NULL ),
59   mAppliedShader( NULL ),
60   mInheritedShader( NULL ),
61   mExclusiveRenderTask( NULL ),
62   mAttachment( NULL ),
63   mChildren(),
64   mGeometryScale( Vector3::ONE ),
65   mInitialVolume( Vector3::ONE ),
66   mDirtyFlags(AllFlags),
67   mIsRoot( false ),
68   mInheritShader( true ),
69   mInheritRotation( true ),
70   mInheritScale( true ),
71   mTransmitGeometryScaling( false ),
72   mInhibitLocalTransform( false ),
73   mIsActive( true ),
74   mDrawMode( DrawMode::NORMAL ),
75   mPositionInheritanceMode( DEFAULT_POSITION_INHERITANCE_MODE ),
76   mColorMode( DEFAULT_COLOR_MODE )
77 {
78 }
79
80 Node::~Node()
81 {
82 }
83
84 void Node::OnDestroy()
85 {
86   // Node attachments should be notified about the disconnection.
87   if ( mAttachment )
88   {
89     mAttachment->OnDestroy();
90   }
91
92   // Animators, Constraints etc. should be disconnected from the child's properties.
93   PropertyOwner::DisconnectFromSceneGraph();
94 }
95
96 void Node::Attach( NodeAttachment& object )
97 {
98   DALI_ASSERT_DEBUG(!mAttachment);
99
100   object.SetParent(*this);
101
102   mAttachment = &object;
103   SetAllDirtyFlags();
104 }
105
106 void Node::SetRoot(bool isRoot)
107 {
108   DALI_ASSERT_DEBUG(!isRoot || mParent == NULL); // Root nodes cannot have a parent
109
110   mIsRoot = isRoot;
111 }
112
113 void Node::ConnectChild( Node* childNode )
114 {
115   DALI_ASSERT_ALWAYS( this != childNode );
116   DALI_ASSERT_ALWAYS( IsRoot() || NULL != mParent ); // Parent should be connected first
117   DALI_ASSERT_ALWAYS( !childNode->IsRoot() && NULL == childNode->GetParent() ); // Child should be disconnected
118
119   childNode->SetParent( *this );
120
121   // Everything should be reinherited when reconnected to scene-graph
122   childNode->SetAllDirtyFlags();
123
124   mChildren.PushBack( childNode );
125 }
126
127 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
128 {
129   DALI_ASSERT_ALWAYS( this != &childNode );
130   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
131
132   // Find the childNode and remove it
133   Node* found( NULL );
134
135   const NodeIter endIter = mChildren.End();
136   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
137   {
138     Node* current = *iter;
139     if ( current == &childNode )
140     {
141       found = current;
142       mChildren.Erase( iter ); // order matters here
143       break; // iter is no longer valid
144     }
145   }
146   DALI_ASSERT_ALWAYS( NULL != found );
147
148   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
149 }
150
151 void Node::ApplyShader( Shader* shader )
152 {
153   DALI_ASSERT_DEBUG( shader && "null shader passed to node" );
154
155   mAppliedShader = shader;
156
157   SetDirtyFlag(ShaderFlag);
158 }
159
160 void Node::RemoveShader()
161 {
162   mAppliedShader = NULL; // Wait until InheritShader to grab default shader
163
164   SetDirtyFlag(ShaderFlag);
165 }
166
167 Shader* Node::GetAppliedShader() const
168 {
169   return mAppliedShader;
170 }
171
172 void Node::SetInheritedShader(Shader* shader)
173 {
174   mInheritedShader = shader;
175 }
176
177 Shader* Node::GetInheritedShader() const
178 {
179   return mInheritedShader;
180 }
181
182 void Node::InheritShader(Shader* defaultShader)
183 {
184   DALI_ASSERT_DEBUG(mParent != NULL);
185
186   // If we have a custom shader for this node, then use it
187   if ( mAppliedShader != NULL )
188   {
189     mInheritedShader = mAppliedShader;
190   }
191   else
192   {
193     // Otherwise we either inherit a shader, or fall-back to the default
194     if (mInheritShader)
195     {
196       mInheritedShader = mParent->GetInheritedShader();
197     }
198     else
199     {
200       mInheritedShader = defaultShader;
201     }
202   }
203   DALI_ASSERT_DEBUG( mInheritedShader != NULL );
204 }
205
206 int Node::GetDirtyFlags() const
207 {
208   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
209   int flags = mDirtyFlags;
210   const bool sizeFlag = mSize.IsClean();
211
212   if ( !(flags & TransformFlag) )
213   {
214     // Check whether the transform related properties have changed
215     if( !sizeFlag            ||
216         !mPosition.IsClean() ||
217         !mRotation.IsClean() ||
218         !mScale.IsClean()    ||
219         mParentOrigin.InputChanged() || // parent origin and anchor point rarely change
220         mAnchorPoint.InputChanged() )
221     {
222       flags |= TransformFlag;
223     }
224   }
225
226   // Check whether the visible property has changed
227   if ( !mVisible.IsClean() )
228   {
229     flags |= VisibleFlag;
230   }
231
232   // Check whether the color property has changed
233   if ( !mColor.IsClean() )
234   {
235     flags |= ColorFlag;
236   }
237
238   // Check whether the size property has changed
239   if ( !sizeFlag )
240   {
241     flags |= SizeFlag;
242    }
243
244   return flags;
245 }
246
247 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
248 {
249   // Reset default properties
250   mSize.ResetToBaseValue( updateBufferIndex );
251   mPosition.ResetToBaseValue( updateBufferIndex );
252   mRotation.ResetToBaseValue( updateBufferIndex );
253   mScale.ResetToBaseValue( updateBufferIndex );
254   mVisible.ResetToBaseValue( updateBufferIndex );
255   mColor.ResetToBaseValue( updateBufferIndex );
256
257   mDirtyFlags = NothingFlag;
258 }
259
260 bool Node::IsFullyVisible( BufferIndex updateBufferIndex ) const
261 {
262   if( !IsVisible( updateBufferIndex ) )
263   {
264     return false;
265   }
266
267   Node* parent = mParent;
268
269   while( NULL != parent )
270   {
271     if( !parent->IsVisible( updateBufferIndex ) )
272     {
273       return false;
274     }
275
276     parent = parent->GetParent();
277   }
278
279   return true;
280 }
281
282 void Node::SetParent(Node& parentNode)
283 {
284   DALI_ASSERT_ALWAYS(this != &parentNode);
285   DALI_ASSERT_ALWAYS(!mIsRoot);
286   DALI_ASSERT_ALWAYS(mParent == NULL);
287
288   mParent = &parentNode;
289 }
290
291 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
292 {
293   DALI_ASSERT_ALWAYS(!mIsRoot);
294   DALI_ASSERT_ALWAYS(mParent != NULL);
295
296   const NodeIter endIter = mChildren.End();
297   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
298   {
299     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
300   }
301
302   // Animators, Constraints etc. should be disconnected from the child's properties.
303   PropertyOwner::DisconnectFromSceneGraph();
304
305   // Remove effects
306   mAppliedShader         = NULL;
307   mInheritedShader       = NULL;
308
309   // Remove back-pointer to parent
310   mParent = NULL;
311
312   // Remove all child pointers
313   mChildren.Clear();
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