Remove a few exports by getting rid of two std::vectors and two std::sets
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / active-constraint-impl.h
1 #ifndef __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__
2 #define __DALI_INTERNAL_ACTIVE_CONSTRAINT_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 // EXTERNAL INCLUDES
22 #include <boost/function.hpp>
23
24 // INTERNAL INCLUDES
25 #include <dali/internal/common/event-to-update.h>
26 #include <dali/internal/common/message.h>
27 #include <dali/internal/event/common/proxy-object.h>
28 #include <dali/internal/event/common/thread-local-storage.h>
29 #include <dali/internal/event/common/stage-impl.h>
30 #include <dali/internal/event/animation/active-constraint-base.h>
31 #include <dali/internal/event/animation/constraint-source-impl.h>
32 #include <dali/internal/event/animation/property-constraint-ptr.h>
33 #include <dali/internal/update/common/animatable-property.h>
34 #include <dali/internal/update/common/property-owner.h>
35 #include <dali/internal/update/common/property-owner-messages.h>
36 #include <dali/internal/update/animation/scene-graph-constraint.h>
37 #include <dali/internal/update/animation/property-accessor.h>
38 #include <dali/internal/update/animation/property-component-accessor.h>
39
40 namespace Dali
41 {
42
43 namespace Internal
44 {
45
46 /**
47  * Helper to add only unique entries to the propertyOwner container
48  * @param propertyOwners to add the entries to
49  * @param object to add
50  */
51 inline void AddUnique( SceneGraph::PropertyOwnerContainer& propertyOwners, SceneGraph::PropertyOwner* object )
52 {
53   const SceneGraph::PropertyOwnerIter iter = std::find( propertyOwners.Begin(), propertyOwners.End(), object );
54   if( iter == propertyOwners.End() )
55   {
56     // each owner should only be added once
57     propertyOwners.PushBack( object );
58   }
59 }
60
61 /**
62  * Connects a constraint which takes another property as an input.
63  */
64 template < typename PropertyType >
65 class ActiveConstraint : public ActiveConstraintBase
66 {
67 public:
68
69   typedef SceneGraph::Constraint< PropertyType, PropertyAccessor<PropertyType> > SceneGraphConstraint;
70   typedef const SceneGraph::AnimatableProperty<PropertyType>* ScenePropertyPtr;
71   typedef typename PropertyConstraintPtr<PropertyType>::Type ConstraintFunctionPtr;
72   typedef boost::function< PropertyType (const PropertyType&, const PropertyType&, float) > InterpolatorFunction;
73
74   /**
75    * Construct a new active-constraint.
76    * @param[in] targetIndex The index of the property to constrain.
77    * @param[in] sources The sources of the input properties passed to func.
78    * @param[in] func The constraint function.
79    * @param[in] interpolator The interpolator function.
80    * @return A newly allocated active-constraint.
81    */
82   static ActiveConstraintBase* New( Property::Index targetIndex,
83                                     SourceContainer& sources,
84                                     ConstraintFunctionPtr func,
85                                     InterpolatorFunction interpolator )
86   {
87     ThreadLocalStorage& tls = ThreadLocalStorage::Get();
88
89     return new ActiveConstraint< PropertyType >( tls.GetEventToUpdate(), targetIndex, sources, sources.size(), func, interpolator );
90   }
91
92   /**
93    * Virtual destructor.
94    */
95   virtual ~ActiveConstraint()
96   {
97     // This is not responsible for removing constraints.
98   }
99
100   /**
101    * @copydoc ActiveConstraintBase::Clone()
102    */
103   virtual ActiveConstraintBase* Clone()
104   {
105     ActiveConstraintBase* clone( NULL );
106
107     ConstraintFunctionPtr funcPtr( mUserFunction->Clone() );
108
109     clone = new ActiveConstraint< PropertyType >( mEventToUpdate,
110                                                   mTargetIndex,
111                                                   mSources,
112                                                   mSourceCount,
113                                                   funcPtr,
114                                                   mInterpolatorFunction );
115
116     clone->SetAlphaFunction(mAlphaFunction);
117     clone->SetRemoveAction(mRemoveAction);
118     clone->SetTag( mTag );
119
120     return clone;
121   }
122
123 private:
124
125   /**
126    * Private constructor; see also ActiveConstraint::New().
127    */
128   ActiveConstraint( EventToUpdate& eventToUpdate,
129                     Property::Index targetIndex,
130                     SourceContainer& sources,
131                     unsigned int sourceCount,
132                     ConstraintFunctionPtr& func,
133                     InterpolatorFunction& interpolator )
134   : ActiveConstraintBase( eventToUpdate, targetIndex, sources, sourceCount ),
135     mTargetIndex( targetIndex ),
136     mUserFunction( func ),
137     mInterpolatorFunction( interpolator )
138   {
139   }
140
141   // Undefined
142   ActiveConstraint( const ActiveConstraint& );
143
144   // Undefined
145   ActiveConstraint& operator=( const ActiveConstraint& rhs );
146
147   /**
148    * Create and connect a constraint for a scene-object.
149    */
150   void ConnectConstraint()
151   {
152     // Should not come here any proxies have been destroyed
153     DALI_ASSERT_DEBUG( NULL != mTargetProxy );
154     DALI_ASSERT_DEBUG( mSources.size() == mSourceCount );
155
156     // Guard against double connections
157     DALI_ASSERT_DEBUG( NULL == mSceneGraphConstraint );
158
159     // Short-circuit until the target scene-object exists
160     SceneGraph::PropertyOwner* targetObject = const_cast< SceneGraph::PropertyOwner* >( mTargetProxy->GetSceneObject() );
161     if ( NULL == targetObject )
162     {
163       return;
164     }
165
166     // Build a container of property-owners, providing the scene-graph properties
167     SceneGraph::PropertyOwnerContainer propertyOwners;
168     propertyOwners.PushBack( targetObject );
169
170     // Build the constraint function; this requires a scene-graph property from each source
171     ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
172
173     if ( func )
174     {
175       // Create the SceneGraphConstraint, and connect to the scene-graph
176
177       const SceneGraph::PropertyBase* targetProperty = mTargetProxy->GetSceneObjectAnimatableProperty( mTargetIndex );
178
179       // The targetProperty should exist, when targetObject exists
180       DALI_ASSERT_ALWAYS( NULL != targetProperty && "Constraint target property does not exist" );
181
182       // Connect the constraint
183       SceneGraph::ConstraintBase* sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty,
184                                                                                      propertyOwners,
185                                                                                      func,
186                                                                                      mInterpolatorFunction,
187                                                                                      mCustomWeight );
188       DALI_ASSERT_DEBUG( NULL != sceneGraphConstraint );
189       sceneGraphConstraint->SetInitialWeight( mOffstageWeight );
190       sceneGraphConstraint->SetRemoveAction( mRemoveAction );
191
192       // object is being used in a separate thread; queue a message to apply the constraint
193       ApplyConstraintMessage( Stage::GetCurrent()->GetUpdateInterface(), *targetObject, *sceneGraphConstraint );
194
195       // Keep a raw-pointer to the scene-graph constraint
196       mSceneGraphConstraint = sceneGraphConstraint;
197
198       // Notify ProxyObject base-class that the scene-graph constraint has been added
199       OnSceneObjectAdd();
200     }
201   }
202
203   /**
204    * Helper for ConnectConstraint. Creates a connected constraint-function.
205    * Also populates the property-owner container, for each input connected to the constraint-function.
206    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
207    * @return A connected constraint-function, or NULL if the scene-graph properties are not available.
208    */
209   PropertyConstraintBase<PropertyType>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
210   {
211     PropertyConstraintBase<PropertyType>* func = mUserFunction->Clone();
212     bool usingComponentFunc( false );
213
214     for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
215     {
216       Source& source = *iter;
217
218       PropertyInputImpl* inputProperty( NULL );
219       int componentIndex( Property::INVALID_COMPONENT_INDEX );
220
221       if ( OBJECT_PROPERTY == source.sourceType )
222       {
223         DALI_ASSERT_ALWAYS( source.object->IsPropertyAConstraintInput( source.propertyIndex ) );
224
225         SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( source.object->GetSceneObject() );
226
227         // The property owner will not exist, if the target proxy-object is off-stage
228         if( NULL != owner )
229         {
230           AddUnique( propertyOwners, owner );
231           inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
232           componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
233
234           // The scene-object property should exist, when the property owner exists
235           DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
236         }
237       }
238       else if ( LOCAL_PROPERTY == source.sourceType )
239       {
240         DALI_ASSERT_ALWAYS( mTargetProxy->IsPropertyAConstraintInput( source.propertyIndex ) );
241
242         inputProperty = const_cast< PropertyInputImpl* >( mTargetProxy->GetSceneObjectInputProperty( source.propertyIndex ) );
243         componentIndex = mTargetProxy->GetPropertyComponentIndex( source.propertyIndex );
244
245         // The target scene-object should provide this property
246         DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
247       }
248       else
249       {
250         DALI_ASSERT_ALWAYS( PARENT_PROPERTY == source.sourceType && "Constraint source property type is invalid" );
251
252         ProxyObject* proxyParent = dynamic_cast< Actor& >( *mTargetProxy ).GetParent();
253
254         // This will not exist, if the target proxy-object is off-stage
255         if ( NULL != proxyParent )
256         {
257           DALI_ASSERT_ALWAYS( proxyParent->IsPropertyAConstraintInput( source.propertyIndex ) );
258
259           SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( proxyParent->GetSceneObject() );
260
261           // The property owner will not exist, if the parent proxy-object is off-stage
262           if ( NULL != owner )
263           {
264             AddUnique( propertyOwners, owner );
265             inputProperty = const_cast< PropertyInputImpl* >( proxyParent->GetSceneObjectInputProperty( source.propertyIndex ) );
266             componentIndex = proxyParent->GetPropertyComponentIndex( source.propertyIndex );
267
268             // The scene-object property should exist, when the property owner exists
269             DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
270           }
271         }
272       }
273
274       if ( NULL == inputProperty )
275       {
276         delete func;
277         func = NULL;
278
279         // Exit if a scene-graph object is not available from one of the sources
280         break;
281       }
282       else if ( Property::INVALID_COMPONENT_INDEX != componentIndex )
283       {
284         // Special case where component indices are required
285         if ( !usingComponentFunc )
286         {
287           PropertyConstraintBase<PropertyType>* componentFunc = func->CloneComponentFunc();
288           usingComponentFunc = true;
289
290           // Switch to function supporting component indices
291           delete func;
292           func = componentFunc;
293         }
294       }
295
296       func->SetInput( ( iter - mSources.begin() ), componentIndex, *inputProperty );
297     }
298
299     return func;
300   }
301
302 protected:
303
304   Property::Index mTargetIndex;
305
306   ConstraintFunctionPtr mUserFunction;
307   InterpolatorFunction mInterpolatorFunction;
308 };
309
310 /**
311  * Variant which allows float components to be animated individually.
312  */
313 template <>
314 class ActiveConstraint<float> : public ActiveConstraintBase
315 {
316 public:
317
318   typedef typename PropertyConstraintPtr<float>::Type ConstraintFunctionPtr;
319   typedef boost::function< float (const float&, const float&, float) > InterpolatorFunction;
320
321   /**
322    * Construct a new active-constraint.
323    * @param[in] targetIndex The index of the property to constrain.
324    * @param[in] sources The sources of the input properties passed to func.
325    * @param[in] func The constraint function.
326    * @param[in] interpolator The interpolator function.
327    * @return A newly allocated active-constraint.
328    */
329   static ActiveConstraintBase* New( Property::Index targetIndex,
330                                     SourceContainer& sources,
331                                     ConstraintFunctionPtr func,
332                                     InterpolatorFunction interpolator )
333   {
334     ThreadLocalStorage& tls = ThreadLocalStorage::Get();
335
336     return new ActiveConstraint< float >( tls.GetEventToUpdate(), targetIndex, sources, sources.size(), func, interpolator );
337   }
338
339   /**
340    * Virtual destructor.
341    */
342   virtual ~ActiveConstraint()
343   {
344     // This is not responsible for removing constraints.
345   }
346
347   /**
348    * @copydoc ActiveConstraintBase::Clone()
349    */
350   virtual ActiveConstraintBase* Clone()
351   {
352     ActiveConstraintBase* clone( NULL );
353
354     ConstraintFunctionPtr funcPtr( mUserFunction->Clone() );
355
356     clone = new ActiveConstraint< float >( mEventToUpdate,
357                                            mTargetIndex,
358                                            mSources,
359                                            mSourceCount,
360                                            funcPtr,
361                                            mInterpolatorFunction );
362
363     clone->SetAlphaFunction(mAlphaFunction);
364     clone->SetRemoveAction(mRemoveAction);
365     clone->SetTag( mTag );
366
367     return clone;
368   }
369
370 private:
371
372   /**
373    * Private constructor; see also ActiveConstraint::New().
374    */
375   ActiveConstraint( EventToUpdate& eventToUpdate,
376                     Property::Index targetIndex,
377                     SourceContainer& sources,
378                     unsigned int sourceCount,
379                     ConstraintFunctionPtr& func,
380                     InterpolatorFunction& interpolator )
381   : ActiveConstraintBase( eventToUpdate, targetIndex, sources, sourceCount ),
382     mTargetIndex( targetIndex ),
383     mUserFunction( func ),
384     mInterpolatorFunction( interpolator )
385   {
386   }
387
388   // Undefined
389   ActiveConstraint( const ActiveConstraint& );
390
391   // Undefined
392   ActiveConstraint& operator=( const ActiveConstraint& rhs );
393
394   /**
395    * Create and connect a constraint for a scene-object.
396    */
397   void ConnectConstraint()
398   {
399     // Should not come here any proxies have been destroyed
400     DALI_ASSERT_DEBUG( NULL != mTargetProxy );
401     DALI_ASSERT_DEBUG( mSources.size() == mSourceCount );
402
403     // Guard against double connections
404     DALI_ASSERT_DEBUG( NULL == mSceneGraphConstraint );
405
406     // Short-circuit until the target scene-object exists
407     SceneGraph::PropertyOwner* targetObject = const_cast< SceneGraph::PropertyOwner* >( mTargetProxy->GetSceneObject() );
408     if ( NULL == targetObject )
409     {
410       return;
411     }
412
413     // Build a container of property-owners, providing the scene-graph properties
414     SceneGraph::PropertyOwnerContainer propertyOwners;
415     propertyOwners.PushBack( targetObject );
416
417     // Build the constraint function; this requires a scene-graph property from each source
418     ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
419
420     if ( func )
421     {
422       // Create the SceneGraphConstraint, and connect to the scene-graph
423
424       const SceneGraph::PropertyBase* targetProperty = mTargetProxy->GetSceneObjectAnimatableProperty( mTargetIndex );
425
426       // The targetProperty should exist, when targetObject exists
427       DALI_ASSERT_ALWAYS( NULL != targetProperty && "Constraint target property does not exist" );
428
429       const int componentIndex = mTargetProxy->GetPropertyComponentIndex( mTargetIndex );
430
431       SceneGraph::ConstraintBase* sceneGraphConstraint( NULL );
432
433       if ( Property::INVALID_COMPONENT_INDEX == componentIndex )
434       {
435         // Not a Vector3 or Vector4 component, expecting float type
436         DALI_ASSERT_DEBUG( PropertyTypes::Get< float >() == targetProperty->GetType() );
437
438         typedef SceneGraph::Constraint< float, PropertyAccessor<float> > SceneGraphConstraint;
439
440         sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty,
441                                                            propertyOwners,
442                                                            func,
443                                                            mInterpolatorFunction,
444                                                            mCustomWeight );
445       }
446       else
447       {
448         // Expecting Vector3 or Vector4 type
449
450         if ( PropertyTypes::Get< Vector3 >() == targetProperty->GetType() )
451         {
452           // Constrain float component of Vector3 property
453
454           if ( 0 == componentIndex )
455           {
456             typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector3> > SceneGraphConstraint;
457             sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
458           }
459           else if ( 1 == componentIndex )
460           {
461             typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector3> > SceneGraphConstraint;
462             sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
463           }
464           else if ( 2 == componentIndex )
465           {
466             typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector3> > SceneGraphConstraint;
467             sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
468           }
469         }
470         else if ( PropertyTypes::Get< Vector4 >() == targetProperty->GetType() )
471         {
472           // Constrain float component of Vector4 property
473
474           if ( 0 == componentIndex )
475           {
476             typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector4> > SceneGraphConstraint;
477             sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
478           }
479           else if ( 1 == componentIndex )
480           {
481             typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector4> > SceneGraphConstraint;
482             sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
483           }
484           else if ( 2 == componentIndex )
485           {
486             typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector4> > SceneGraphConstraint;
487             sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
488           }
489           else if ( 3 == componentIndex )
490           {
491             typedef SceneGraph::Constraint< float, PropertyComponentAccessorW<Vector4> > SceneGraphConstraint;
492             sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
493           }
494         }
495       }
496
497       DALI_ASSERT_DEBUG( NULL != sceneGraphConstraint );
498       sceneGraphConstraint->SetInitialWeight( mOffstageWeight );
499       sceneGraphConstraint->SetRemoveAction( mRemoveAction );
500
501         // object is being used in a separate thread; queue a message to apply the constraint
502       ApplyConstraintMessage( Stage::GetCurrent()->GetUpdateInterface(), *targetObject, *sceneGraphConstraint );
503
504       // Keep a raw-pointer to the scene-graph constraint
505       mSceneGraphConstraint = sceneGraphConstraint;
506
507       // Notify ProxyObject base-class that the scene-graph constraint has been added
508       OnSceneObjectAdd();
509     }
510   }
511
512   /**
513    * Helper for ConnectConstraint. Creates a connected constraint-function.
514    * Also populates the property-owner container, for each input connected to the constraint-function.
515    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
516    * @return A connected constraint-function, or NULL if the scene-graph properties are not available.
517    */
518   PropertyConstraintBase<float>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
519   {
520     PropertyConstraintBase<float>* func = mUserFunction->Clone();
521     bool usingComponentFunc( false );
522
523     for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
524     {
525       Source& source = *iter;
526
527       PropertyInputImpl* inputProperty( NULL );
528       int componentIndex( Property::INVALID_COMPONENT_INDEX );
529
530       if ( OBJECT_PROPERTY == source.sourceType )
531       {
532         DALI_ASSERT_ALWAYS( source.object->IsPropertyAConstraintInput( source.propertyIndex ) );
533
534         SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( source.object->GetSceneObject() );
535
536         // The property owner will not exist, if the target proxy-object is off-stage
537         if( NULL != owner )
538         {
539           AddUnique( propertyOwners, owner );
540           inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
541           componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
542
543           // The scene-object property should exist, when the property owner exists
544           DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
545         }
546       }
547       else if ( LOCAL_PROPERTY == source.sourceType )
548       {
549         DALI_ASSERT_ALWAYS( mTargetProxy->IsPropertyAConstraintInput( source.propertyIndex ) );
550
551         inputProperty = const_cast< PropertyInputImpl* >( mTargetProxy->GetSceneObjectInputProperty( source.propertyIndex ) );
552         componentIndex = mTargetProxy->GetPropertyComponentIndex( source.propertyIndex );
553
554         // The target scene-object should provide this property
555         DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
556       }
557       else
558       {
559         DALI_ASSERT_ALWAYS( PARENT_PROPERTY == source.sourceType && "Constraint source property type is invalid" );
560
561         ProxyObject* proxyParent = dynamic_cast< Actor& >( *mTargetProxy ).GetParent();
562
563         // This will not exist, if the target proxy-object is off-stage
564         if ( NULL != proxyParent )
565         {
566           DALI_ASSERT_ALWAYS( proxyParent->IsPropertyAConstraintInput( source.propertyIndex ) );
567
568           SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( proxyParent->GetSceneObject() );
569
570           // The property owner will not exist, if the parent proxy-object is off-stage
571           if ( NULL != owner )
572           {
573             AddUnique( propertyOwners, owner );
574             inputProperty = const_cast< PropertyInputImpl* >( proxyParent->GetSceneObjectInputProperty( source.propertyIndex ) );
575             componentIndex = proxyParent->GetPropertyComponentIndex( source.propertyIndex );
576
577             // The scene-object property should exist, when the property owner exists
578             DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
579           }
580         }
581       }
582
583       if ( NULL == inputProperty )
584       {
585         delete func;
586         func = NULL;
587
588         // Exit if a scene-graph object is not available from one of the sources
589         break;
590       }
591       else if ( Property::INVALID_COMPONENT_INDEX != componentIndex )
592       {
593         // Special case where component indices are required
594         if ( !usingComponentFunc )
595         {
596           PropertyConstraintBase<float>* componentFunc = func->CloneComponentFunc();
597           usingComponentFunc = true;
598
599           // Switch to function supporting component indices
600           delete func;
601           func = componentFunc;
602         }
603       }
604
605       func->SetInput( ( iter - mSources.begin() ), componentIndex, *inputProperty );
606     }
607
608     return func;
609   }
610
611 protected:
612
613   Property::Index mTargetIndex;
614
615   ConstraintFunctionPtr mUserFunction;
616   InterpolatorFunction mInterpolatorFunction;
617 };
618
619 } // namespace Internal
620
621 } // namespace Dali
622
623 #endif // __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__