Merge "Refactored EventToUpdate into EventThreadServices" into tizen
[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
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 const SizeMode Node::DEFAULT_SIZE_MODE( USE_OWN_SIZE );
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   mGeometryScale( Vector3::ONE ),
64   mInitialVolume( Vector3::ONE ),
65   mSizeModeFactor( Vector3::ONE ),
66   mDirtyFlags(AllFlags),
67   mIsRoot( false ),
68   mInheritOrientation( true ),
69   mInheritScale( true ),
70   mTransmitGeometryScaling( false ),
71   mInhibitLocalTransform( false ),
72   mIsActive( true ),
73   mDrawMode( DrawMode::NORMAL ),
74   mPositionInheritanceMode( DEFAULT_POSITION_INHERITANCE_MODE ),
75   mColorMode( DEFAULT_COLOR_MODE ),
76   mSizeMode( DEFAULT_SIZE_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::Destroy();
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, int index )
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   if (index == -1)
125   {
126     mChildren.PushBack( childNode );
127   }
128   else
129   {
130     mChildren.Insert(mChildren.Begin()+index, childNode);
131   }
132
133   childNode->ConnectToSceneGraph();
134 }
135
136 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
137 {
138   DALI_ASSERT_ALWAYS( this != &childNode );
139   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
140
141   // Find the childNode and remove it
142   Node* found( NULL );
143
144   const NodeIter endIter = mChildren.End();
145   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
146   {
147     Node* current = *iter;
148     if ( current == &childNode )
149     {
150       found = current;
151       mChildren.Erase( iter ); // order matters here
152       break; // iter is no longer valid
153     }
154   }
155   DALI_ASSERT_ALWAYS( NULL != found );
156
157   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
158 }
159
160 int Node::GetDirtyFlags() const
161 {
162   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
163   int flags = mDirtyFlags;
164   const bool sizeFlag = mSize.IsClean();
165
166   if ( !(flags & TransformFlag) )
167   {
168     // Check whether the transform related properties have changed
169     if( !sizeFlag            ||
170         !mPosition.IsClean() ||
171         !mOrientation.IsClean() ||
172         !mScale.IsClean()    ||
173         mParentOrigin.InputChanged() || // parent origin and anchor point rarely change
174         mAnchorPoint.InputChanged() )
175     {
176       flags |= TransformFlag;
177     }
178   }
179
180   // Check whether the visible property has changed
181   if ( !mVisible.IsClean() )
182   {
183     flags |= VisibleFlag;
184   }
185
186   // Check whether the color property has changed
187   if ( !mColor.IsClean() )
188   {
189     flags |= ColorFlag;
190   }
191
192   // Check whether the size property has changed
193   if ( !sizeFlag )
194   {
195     flags |= SizeFlag;
196    }
197
198   return flags;
199 }
200
201 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
202 {
203   // clear dirty flags in parent origin & anchor point
204   mParentOrigin.Clear();
205   mAnchorPoint.Clear();
206   // Reset default properties
207   mSize.ResetToBaseValue( updateBufferIndex );
208   mPosition.ResetToBaseValue( updateBufferIndex );
209   mOrientation.ResetToBaseValue( updateBufferIndex );
210   mScale.ResetToBaseValue( updateBufferIndex );
211   mVisible.ResetToBaseValue( updateBufferIndex );
212   mColor.ResetToBaseValue( updateBufferIndex );
213
214   mDirtyFlags = NothingFlag;
215 }
216
217 bool Node::IsFullyVisible( BufferIndex updateBufferIndex ) const
218 {
219   if( !IsVisible( updateBufferIndex ) )
220   {
221     return false;
222   }
223
224   Node* parent = mParent;
225
226   while( NULL != parent )
227   {
228     if( !parent->IsVisible( updateBufferIndex ) )
229     {
230       return false;
231     }
232
233     parent = parent->GetParent();
234   }
235
236   return true;
237 }
238
239 void Node::SetParent(Node& parentNode)
240 {
241   DALI_ASSERT_ALWAYS(this != &parentNode);
242   DALI_ASSERT_ALWAYS(!mIsRoot);
243   DALI_ASSERT_ALWAYS(mParent == NULL);
244
245   mParent = &parentNode;
246 }
247
248 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
249 {
250   DALI_ASSERT_ALWAYS(!mIsRoot);
251   DALI_ASSERT_ALWAYS(mParent != NULL);
252
253   const NodeIter endIter = mChildren.End();
254   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
255   {
256     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
257   }
258
259   // Animators, Constraints etc. should be disconnected from the child's properties.
260   PropertyOwner::DisconnectFromSceneGraph( updateBufferIndex );
261
262   // Remove back-pointer to parent
263   mParent = NULL;
264
265   // Remove all child pointers
266   mChildren.Clear();
267
268   // Move into disconnectedNodes
269   std::set<Node*>::size_type removed = connectedNodes.erase( this );
270   DALI_ASSERT_ALWAYS( removed );
271   disconnectedNodes.insert( this );
272 }
273
274 } // namespace SceneGraph
275
276 } // namespace Internal
277
278 } // namespace Dali