[SRUK] Initial copy from Tizen 2.2 version
[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, mDirtyFlags ),
46   mAnchorPoint( AnchorPoint::DEFAULT, mDirtyFlags ),
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   mIsRoot( false ),
59   mInheritShader( true ),
60   mInheritRotation( true ),
61   mInheritScale( true ),
62   mTransmitGeometryScaling( false ),
63   mInhibitLocalTransform( false ),
64   mIsActive( true ),
65   mDrawMode( DrawMode::NORMAL ),
66   mPositionInheritanceMode( DEFAULT_POSITION_INHERITANCE_MODE ),
67   mColorMode( DEFAULT_COLOR_MODE ),
68   mParent( NULL ),
69   mAttachment( NULL ),
70   mAppliedShader( NULL ),
71   mInheritedShader( NULL ),
72   mDirtyFlags(AllFlags),
73   mGeometryScale( Vector3::ONE ),
74   mInitialVolume( Vector3::ONE ),
75   mExclusiveRenderTask( NULL )
76 {
77 }
78
79 Node::~Node()
80 {
81 }
82
83 void Node::OnDestroy()
84 {
85   // Node attachments should be notified about the disconnection.
86   if ( mAttachment )
87   {
88     mAttachment->OnDestroy();
89   }
90
91   // Animators, Constraints etc. should be disconnected from the child's properties.
92   PropertyOwner::DisconnectFromSceneGraph();
93 }
94
95 void Node::Attach( NodeAttachment& object )
96 {
97   DALI_ASSERT_DEBUG(!mAttachment);
98
99   object.SetParent(*this);
100
101   mAttachment = &object;
102   SetAllDirtyFlags();
103 }
104
105 void Node::SetRoot(bool isRoot)
106 {
107   DALI_ASSERT_DEBUG(!isRoot || mParent == NULL); // Root nodes cannot have a parent
108
109   mIsRoot = isRoot;
110 }
111
112 void Node::ConnectChild( Node* childNode )
113 {
114   DALI_ASSERT_ALWAYS( this != childNode );
115   DALI_ASSERT_ALWAYS( IsRoot() || NULL != mParent ); // Parent should be connected first
116   DALI_ASSERT_ALWAYS( !childNode->IsRoot() && NULL == childNode->GetParent() ); // Child should be disconnected
117
118   childNode->SetParent( *this );
119
120   // Everything should be reinherited when reconnected to scene-graph
121   childNode->SetAllDirtyFlags();
122
123   mChildren.PushBack( childNode );
124 }
125
126 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
127 {
128   DALI_ASSERT_ALWAYS( this != &childNode );
129   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
130
131   // Find the childNode and remove it
132   Node* found( NULL );
133
134   const NodeIter endIter = mChildren.End();
135   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
136   {
137     Node* current = *iter;
138     if ( current == &childNode )
139     {
140       found = current;
141       mChildren.Erase( iter ); // order matters here
142       break; // iter is no longer valid
143     }
144   }
145   DALI_ASSERT_ALWAYS( NULL != found );
146
147   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
148 }
149
150 void Node::ApplyShader( Shader* shader )
151 {
152   DALI_ASSERT_DEBUG( shader && "null shader passed to node" );
153
154   mAppliedShader = shader;
155
156   SetDirtyFlag(ShaderFlag);
157 }
158
159 void Node::RemoveShader()
160 {
161   mAppliedShader = NULL; // Wait until InheritShader to grab default shader
162
163   SetDirtyFlag(ShaderFlag);
164 }
165
166 Shader* Node::GetAppliedShader() const
167 {
168   return mAppliedShader;
169 }
170
171 void Node::SetInheritedShader(Shader* shader)
172 {
173   mInheritedShader = shader;
174 }
175
176 Shader* Node::GetInheritedShader() const
177 {
178   return mInheritedShader;
179 }
180
181 void Node::InheritShader(Shader* defaultShader)
182 {
183   DALI_ASSERT_DEBUG(mParent != NULL);
184
185   // If we have a custom shader for this node, then use it
186   if ( mAppliedShader != NULL )
187   {
188     mInheritedShader = mAppliedShader;
189   }
190   else
191   {
192     // Otherwise we either inherit a shader, or fall-back to the default
193     if (mInheritShader)
194     {
195       mInheritedShader = mParent->GetInheritedShader();
196     }
197     else
198     {
199       mInheritedShader = defaultShader;
200     }
201   }
202   DALI_ASSERT_DEBUG( mInheritedShader != NULL );
203 }
204
205 int Node::GetDirtyFlags() const
206 {
207   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
208   int flags = mDirtyFlags;
209   const bool sizeFlag = mSize.IsClean();
210
211   if ( !(flags & TransformFlag) )
212   {
213     // Check whether the transform related properties have changed, ParentOrigin and AnchorPoint modify mDirtyFlags directly when being modified
214     if( !sizeFlag            ||
215         !mPosition.IsClean() ||
216         !mRotation.IsClean() ||
217         !mScale.IsClean() )
218     {
219       flags |= TransformFlag;
220     }
221   }
222
223   // Check whether the visible property has changed
224   if ( !mVisible.IsClean() )
225   {
226     flags |= VisibleFlag;
227   }
228
229   // Check whether the color property has changed
230   if ( !mColor.IsClean() )
231   {
232     flags |= ColorFlag;
233   }
234
235   // Check whether the size property has changed
236   if ( !sizeFlag )
237   {
238     flags |= SizeFlag;
239    }
240
241   return flags;
242 }
243
244 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
245 {
246   // Reset default properties
247   mSize.ResetToBaseValue( updateBufferIndex );
248   mPosition.ResetToBaseValue( updateBufferIndex );
249   mRotation.ResetToBaseValue( updateBufferIndex );
250   mScale.ResetToBaseValue( updateBufferIndex );
251   mVisible.ResetToBaseValue( updateBufferIndex );
252   mColor.ResetToBaseValue( updateBufferIndex );
253
254   mDirtyFlags = NothingFlag;
255 }
256
257 bool Node::IsFullyVisible( BufferIndex updateBufferIndex ) const
258 {
259   if( !IsVisible( updateBufferIndex ) )
260   {
261     return false;
262   }
263
264   Node* parent = mParent;
265
266   while( NULL != parent )
267   {
268     if( !parent->IsVisible( updateBufferIndex ) )
269     {
270       return false;
271     }
272
273     parent = parent->GetParent();
274   }
275
276   return true;
277 }
278
279 void Node::SetParent(Node& parentNode)
280 {
281   DALI_ASSERT_ALWAYS(this != &parentNode);
282   DALI_ASSERT_ALWAYS(!mIsRoot);
283   DALI_ASSERT_ALWAYS(mParent == NULL);
284
285   mParent = &parentNode;
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();
301
302   // Remove effects
303   mAppliedShader         = NULL;
304   mInheritedShader       = NULL;
305
306   // Remove back-pointer to parent
307   mParent = NULL;
308
309   // Remove all child pointers
310   mChildren.Clear();
311
312   // Move into disconnectedNodes
313   std::set<Node*>::size_type removed = connectedNodes.erase( this );
314   DALI_ASSERT_ALWAYS( removed );
315   disconnectedNodes.insert( this );
316 }
317
318 } // namespace SceneGraph
319
320 } // namespace Internal
321
322 } // namespace Dali