1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H__
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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/common/event-to-update.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>
37 // value types used by messages
38 template <> struct ParameterType< Dali::Constraint::RemoveAction >
39 : public BasicType< Dali::Constraint::RemoveAction > {};
44 typedef Dali::Vector<PropertyOwner*> PropertyOwnerContainer;
45 typedef PropertyOwnerContainer::Iterator PropertyOwnerIter;
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.
51 class ConstraintBase : public PropertyOwner, public PropertyOwner::Observer
55 typedef Dali::Constraint::RemoveAction RemoveAction;
60 ConstraintBase( PropertyOwnerContainer& ownerContainer );
65 virtual ~ConstraintBase();
68 * Initialize the constraint.
69 * This should by called by a scene-object, when the constraint is connected.
75 mDisconnected = false;
79 * @copydoc Dali::Constraint::SetRemoveAction()
81 void SetRemoveAction( RemoveAction action )
83 mRemoveAction = action;
87 * @copydoc Dali::Constraint::GetRemoveAction()
89 RemoveAction GetRemoveAction() const
95 * Bake the weight property.
96 * @param[in] updateBufferIndex The current update buffer index.
97 * @param[in] weight The new weight.
99 void BakeWeight( BufferIndex updateBufferIndex, float weight )
101 mWeight.Bake( updateBufferIndex, weight );
105 * Set the initial weight.
106 * @pre The constraint has not been connected to the scene-graph.
107 * @param[in] weight The new weight.
109 void SetInitialWeight( float weight )
111 mWeight.SetInitial( weight );
115 * Retrieve the weight property.
116 * @param[in] bufferIndex The buffer index to read from.
117 * @return The current weight.
119 float GetWeight( BufferIndex bufferIndex ) const
121 return mWeight[ bufferIndex ];
125 * Constrain the associated scene object.
126 * @param[in] updateBufferIndex The current update buffer index.
128 virtual void Apply( BufferIndex updateBufferIndex ) = 0;
131 * Helper for internal test cases; only available for debug builds.
132 * @return The current number of Constraint instances in existence.
134 static unsigned int GetCurrentInstanceCount();
137 * Helper for internal test cases; only available for debug builds.
138 * @return The total number of Constraint instances created during the Dali core lifetime.
140 static unsigned int GetTotalInstanceCount();
145 * Helper to start observing property owners
147 void StartObservation()
149 const PropertyOwnerIter end = mObservedOwners.End();
150 for( PropertyOwnerIter iter = mObservedOwners.Begin(); end != iter; ++iter )
152 (*iter)->AddObserver( *this );
157 * Helper to stop observing property owners
159 void StopObservation()
161 const PropertyOwnerIter end = mObservedOwners.End();
162 for( PropertyOwnerIter iter = mObservedOwners.Begin(); end != iter; ++iter )
164 (*iter)->RemoveObserver( *this );
167 mObservedOwners.Clear();
171 * @copydoc PropertyOwner::Observer::PropertyOwnerConnected()
173 virtual void PropertyOwnerConnected( PropertyOwner& owner )
178 * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected()
180 virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
182 if ( !mDisconnected )
184 // Stop observing property owners
187 // Notification for derived class
190 mDisconnected = true;
195 * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed()
197 virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
199 if ( !mDisconnected )
201 // Discard pointer to destroyed property owner. Otherwise StopObservation() would crash when trying to remove
202 //the constraint from the destroyed PropertyOwner's observers list
203 PropertyOwnerIter iter = std::find( mObservedOwners.Begin(), mObservedOwners.End(), &owner );
204 if( mObservedOwners.End() != iter )
206 mObservedOwners.Erase( iter );
209 // Stop observing the rest of property owners
212 // Notification for derived class
215 mDisconnected = true;
221 * @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties()
223 virtual void ResetDefaultProperties( BufferIndex updateBufferIndex );
226 * Notify the derived class to disconnect from property owners
228 virtual void OnDisconnect() = 0;
232 AnimatableProperty<float> mWeight; ///< The constraint is "fully-applied" when weight = 1
236 RemoveAction mRemoveAction;
238 bool mFirstApply : 1;
239 bool mDisconnected : 1;
243 PropertyOwnerContainer mObservedOwners; ///< A set of pointers to each observed object. Not owned.
246 static unsigned int mCurrentInstanceCount; ///< The current number of Constraint instances in existence.
247 static unsigned int mTotalInstanceCount; ///< The total number of Constraint instances created during the Dali core lifetime.
251 // Messages for ConstraintBase
253 inline void BakeWeightMessage( EventToUpdate& eventToUpdate, const ConstraintBase& constraint, float weight )
255 typedef MessageDoubleBuffered1< ConstraintBase, float > LocalType;
257 // Reserve some memory inside the message queue
258 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
260 // Construct message in the message queue memory; note that delete should not be called on the return value
261 new (slot) LocalType( &constraint, &ConstraintBase::BakeWeight, weight );
264 inline void SetRemoveActionMessage( EventToUpdate& eventToUpdate, const ConstraintBase& constraint, Dali::Constraint::RemoveAction removeAction )
266 typedef MessageValue1< ConstraintBase, Dali::Constraint::RemoveAction > LocalType;
268 // Reserve some memory inside the message queue
269 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
271 // Construct message in the message queue memory; note that delete should not be called on the return value
272 new (slot) LocalType( &constraint, &ConstraintBase::SetRemoveAction, removeAction );
275 } // namespace SceneGraph
277 } // namespace Internal
281 #endif // __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H__