Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-constraint-base.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/animation/constraint.h>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/internal/common/message.h>
25 #include <dali/internal/event/common/event-thread-services.h>
26 #include <dali/internal/update/common/animatable-property.h>
27 #include <dali/internal/update/common/property-owner.h>
28 #include <dali/internal/update/common/scene-graph-buffers.h>
29 #include <dali/internal/update/animation/scene-graph-constraint-declarations.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 // value types used by messages
38 template <> struct ParameterType< Dali::Constraint::RemoveAction >
39 : public BasicType< Dali::Constraint::RemoveAction > {};
40
41 namespace SceneGraph
42 {
43
44 typedef Dali::Vector<PropertyOwner*>     PropertyOwnerContainer;
45 typedef PropertyOwnerContainer::Iterator PropertyOwnerIter;
46
47 /**
48  * An abstract base class for Constraints.
49  * This can be used to constrain a property of a scene-object, after animations have been applied.
50  */
51 class ConstraintBase : public PropertyOwner, public PropertyOwner::Observer
52 {
53 public:
54
55   typedef Dali::Constraint::RemoveAction RemoveAction;
56
57   /**
58    * Constructor
59    */
60   ConstraintBase( PropertyOwnerContainer& ownerContainer );
61
62   /**
63    * Virtual destructor.
64    */
65   virtual ~ConstraintBase();
66
67   /**
68    * Initialize the constraint.
69    * This should by called by a scene-object, when the constraint is connected.
70    */
71   void OnConnect()
72   {
73     StartObservation();
74
75     mDisconnected = false;
76   }
77
78   /**
79    * @copydoc Dali::Constraint::SetRemoveAction()
80    */
81   void SetRemoveAction( RemoveAction action )
82   {
83     mRemoveAction = action;
84   }
85
86   /**
87    * @copydoc Dali::Constraint::GetRemoveAction()
88    */
89   RemoveAction GetRemoveAction() const
90   {
91     return mRemoveAction;
92   }
93
94   /**
95    * Constrain the associated scene object.
96    * @param[in] updateBufferIndex The current update buffer index.
97    */
98   virtual void Apply( BufferIndex updateBufferIndex ) = 0;
99
100   /**
101    * Helper for internal test cases; only available for debug builds.
102    * @return The current number of Constraint instances in existence.
103    */
104   static unsigned int GetCurrentInstanceCount();
105
106   /**
107    * Helper for internal test cases; only available for debug builds.
108    * @return The total number of Constraint instances created during the Dali core lifetime.
109    */
110   static unsigned int GetTotalInstanceCount();
111
112 private:
113
114   /**
115    * Helper to start observing property owners
116    */
117   void StartObservation()
118   {
119     const PropertyOwnerIter end =  mObservedOwners.End();
120     for( PropertyOwnerIter iter = mObservedOwners.Begin(); end != iter; ++iter )
121     {
122       (*iter)->AddObserver( *this );
123     }
124   }
125
126   /**
127    * Helper to stop observing property owners
128    */
129   void StopObservation()
130   {
131     const PropertyOwnerIter end =  mObservedOwners.End();
132     for( PropertyOwnerIter iter = mObservedOwners.Begin(); end != iter; ++iter )
133     {
134       (*iter)->RemoveObserver( *this );
135     }
136
137     mObservedOwners.Clear();
138   }
139
140   /**
141    * @copydoc PropertyOwner::Observer::PropertyOwnerConnected()
142    */
143   virtual void PropertyOwnerConnected( PropertyOwner& owner )
144   {
145   }
146
147   /**
148    * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected()
149    */
150   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
151   {
152     if ( !mDisconnected )
153     {
154       // Stop observing property owners
155       StopObservation();
156
157       // Notification for derived class
158       OnDisconnect();
159
160       mDisconnected = true;
161     }
162   }
163
164   /**
165    * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed()
166    */
167   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
168   {
169     if ( !mDisconnected )
170     {
171       // Discard pointer to destroyed property owner. Otherwise StopObservation() would crash when trying to remove
172       //the constraint from the destroyed PropertyOwner's observers list
173       PropertyOwnerIter iter = std::find( mObservedOwners.Begin(), mObservedOwners.End(), &owner );
174       if( mObservedOwners.End() != iter )
175       {
176         mObservedOwners.Erase( iter );
177       }
178
179       // Stop observing the rest of property owners
180       StopObservation();
181
182       // Notification for derived class
183       OnDisconnect();
184
185       mDisconnected = true;
186
187     }
188   }
189
190   /**
191    * @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties()
192    */
193   virtual void ResetDefaultProperties( BufferIndex updateBufferIndex );
194
195   /**
196    * Notify the derived class to disconnect from property owners
197    */
198   virtual void OnDisconnect() = 0;
199
200 protected:
201
202   RemoveAction mRemoveAction;
203
204   bool mFirstApply   : 1;
205   bool mDisconnected : 1;
206
207 private:
208
209   PropertyOwnerContainer mObservedOwners; ///< A set of pointers to each observed object. Not owned.
210
211 #ifdef DEBUG_ENABLED
212   static unsigned int mCurrentInstanceCount;  ///< The current number of Constraint instances in existence.
213   static unsigned int mTotalInstanceCount;    ///< The total number of Constraint instances created during the Dali core lifetime.
214 #endif
215 };
216
217 // Messages for ConstraintBase
218
219 inline void  SetRemoveActionMessage( EventThreadServices& eventThreadServices, const ConstraintBase& constraint, Dali::Constraint::RemoveAction removeAction )
220 {
221   typedef MessageValue1< ConstraintBase, Dali::Constraint::RemoveAction > LocalType;
222
223   // Reserve some memory inside the message queue
224   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
225
226   // Construct message in the message queue memory; note that delete should not be called on the return value
227   new (slot) LocalType( &constraint, &ConstraintBase::SetRemoveAction, removeAction );
228 }
229
230 } // namespace SceneGraph
231
232 } // namespace Internal
233
234 } // namespace Dali
235
236 #endif // __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H__