Merge "Added api function to specify speed factor of an animation" into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / property-constraint.h
1 #ifndef __DALI_PROPERTY_CONSTRAINT_H__
2 #define __DALI_PROPERTY_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 // INTERNAL INCLUDES
22 #include <dali/public-api/object/property-types.h>
23 #include <dali/internal/event/animation/property-input-accessor.h>
24 #include <dali/internal/event/animation/property-input-indexer.h>
25 #include <dali/internal/event/common/property-input-impl.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 /**
34  * A base class for connecting properties to a constraint function.
35  */
36 template < typename PropertyType >
37 class PropertyConstraintBase
38 {
39 public:
40
41   /**
42    * Create a property constraint.
43    */
44   PropertyConstraintBase()
45   : mInputsInitialized( false )
46   {
47   }
48
49   /**
50    * Virtual destructor.
51    */
52   virtual ~PropertyConstraintBase()
53   {
54   }
55
56   /**
57    * Clone a property constraint.
58    */
59   virtual PropertyConstraintBase< PropertyType >* Clone() = 0;
60
61   /**
62    * Clone a property constraint supporting component indices.
63    */
64   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc() = 0;
65
66   /**
67    * Set the input for one of the property constraint parameters.
68    * @param [in] index The parameter index.
69    * @param [in] input The interface for receiving a property value.
70    */
71   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input ) = 0;
72
73   /**
74    * Retrieve the input for one of the property constraint parameters.
75    * @param [in] index The parameter index.
76    * @return The property input, or NULL if no input exists with this index.
77    */
78   virtual const PropertyInputImpl* GetInput( unsigned int index ) const = 0;
79
80   /**
81    * Query whether all of the inputs have been initialized.
82    * @return True if all of the inputs have been initialized.
83    */
84   bool InputsInitialized()
85   {
86     if ( !mInputsInitialized )
87     {
88       // Check whether the inputs are initialized yet
89       unsigned int index( 0u );
90       for ( const PropertyInputImpl* input = GetInput( index );
91             NULL != input;
92             input = GetInput( ++index ) )
93       {
94         if ( !input->InputInitialized() )
95         {
96           return false;
97         }
98       }
99
100       // All inputs are now initialized
101       mInputsInitialized = true;
102     }
103
104     return true;
105   }
106
107   /**
108    * Query whether any of the inputs have changed
109    * @return True if any of the inputs have changed.
110    */
111   bool InputsChanged()
112   {
113     unsigned int index( 0u );
114     for ( const PropertyInputImpl* input = GetInput( index );
115           NULL != input;
116           input = GetInput( ++index ) )
117     {
118       if ( input->InputChanged() )
119       {
120         // At least one of the inputs has changed
121         return true;
122       }
123     }
124
125     return false;
126   }
127
128   /**
129    * Apply the constraint.
130    * @param [in] bufferIndex The current update buffer index.
131    * @param [in] current The current property value.
132    * @return The constrained property value.
133    */
134   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current ) = 0;
135
136 private:
137
138   bool mInputsInitialized;
139 };
140
141 /**
142  * Connects a constraint function with a target property & zero input properties.
143  */
144 template < typename PropertyType >
145 class PropertyConstraint0 : public PropertyConstraintBase< PropertyType >
146 {
147 public:
148
149   typedef boost::function< PropertyType (const PropertyType&)> ConstraintFunction;
150
151   /**
152    * Constructor.
153    * @param [in] func A constraint function.
154    */
155   PropertyConstraint0( const ConstraintFunction& func )
156   : mFunction( func )
157   {
158   }
159
160   /**
161    * Virtual destructor.
162    */
163   virtual ~PropertyConstraint0()
164   {
165   }
166
167   /**
168    * @copydoc PropertyConstraintBase::Clone()
169    */
170   virtual PropertyConstraintBase< PropertyType >* Clone()
171   {
172     return new PropertyConstraint0< PropertyType >( mFunction );
173   }
174
175   /**
176    * @copydoc PropertyConstraintBase::CloneComponentFunc()
177    */
178   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc()
179   {
180     DALI_ASSERT_ALWAYS( false && "PropertyConstraint0 does not support (property component) inputs" );
181     return NULL;
182   }
183
184   /**
185    * @copydoc PropertyConstraintBase::SetInput()
186    */
187   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input )
188   {
189     DALI_ASSERT_ALWAYS( false && "PropertyConstraintBase::SetInput() needs overriding" ); // No additional inputs
190   }
191
192   /**
193    * @copydoc PropertyConstraintBase::GetInput()
194    */
195   virtual const PropertyInputImpl* GetInput( unsigned int index ) const
196   {
197     return NULL; // No additional inputs
198   }
199
200   /**
201    * @copydoc PropertyConstraintBase::Apply()
202    */
203   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current )
204   {
205     return mFunction( current );
206   }
207
208 private:
209
210   // Undefined
211   PropertyConstraint0(const PropertyConstraint0&);
212
213   // Undefined
214   PropertyConstraint0& operator=(const PropertyConstraint0& rhs);
215
216 private:
217
218   ConstraintFunction mFunction;
219 };
220
221 /**
222  * Connects a constraint function with a target property & 1 input property.
223  */
224 template < typename PropertyType, typename PropertyInputAccessorType >
225 class PropertyConstraint1 : public PropertyConstraintBase< PropertyType >
226 {
227 public:
228
229   typedef boost::function< PropertyType (const PropertyType&, const PropertyInput&) > ConstraintFunction;
230
231   /**
232    * Constructor.
233    * @param [in] func A constraint function.
234    */
235   PropertyConstraint1( const ConstraintFunction& func )
236   : mFunction( func )
237   {
238   }
239
240   /**
241    * Constructor.
242    * @param [in] func A constraint function.
243    * @param [in] input1 A property input.
244    */
245   PropertyConstraint1( const ConstraintFunction& func,
246                        const PropertyInputAccessorType& input1 )
247   : mFunction( func ),
248     mInput1( input1 )
249   {
250   }
251
252   /**
253    * Virtual destructor.
254    */
255   virtual ~PropertyConstraint1()
256   {
257   }
258
259   /**
260    * @copydoc PropertyConstraintBase::Clone()
261    */
262   virtual PropertyConstraintBase< PropertyType >* Clone()
263   {
264     return new PropertyConstraint1< PropertyType, PropertyInputAccessorType >( mFunction, mInput1 );
265   }
266
267   /**
268    * @copydoc PropertyConstraintBase::CloneComponentFunc()
269    */
270   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc()
271   {
272     return new PropertyConstraint1< PropertyType, PropertyInputComponentAccessor >( mFunction, mInput1 );
273   }
274
275   /**
276    * @copydoc PropertyConstraintBase::SetInput()
277    */
278   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input )
279   {
280     DALI_ASSERT_ALWAYS( 0u == index && "Constraint only has one input property" );
281
282     mInput1.SetInput( input, componentIndex );
283   }
284
285   /**
286    * @copydoc PropertyConstraintBase::GetInput()
287    */
288   virtual const PropertyInputImpl* GetInput( unsigned int index ) const
289   {
290     if ( 0u == index )
291     {
292       return mInput1.GetInput();
293     }
294
295     return NULL;
296   }
297
298   /**
299    * @copydoc PropertyConstraintBase::Apply()
300    */
301   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current )
302   {
303     DALI_ASSERT_DEBUG( NULL != mInput1.GetInput() );
304
305     const PropertyInputIndexer< PropertyInputAccessorType > input1( bufferIndex, &mInput1 );
306
307     return mFunction( current, input1 );
308   }
309
310 private:
311
312   // Undefined
313   PropertyConstraint1(const PropertyConstraint1&);
314
315   // Undefined
316   PropertyConstraint1& operator=(const PropertyConstraint1& rhs);
317
318 private:
319
320   ConstraintFunction mFunction;
321
322   PropertyInputAccessorType mInput1;
323 };
324
325 /**
326  * Connects a constraint function with a target property & 2 input properties.
327  */
328 template < typename PropertyType, typename PropertyInputAccessorType >
329 class PropertyConstraint2 : public PropertyConstraintBase< PropertyType >
330 {
331 public:
332
333   typedef boost::function< PropertyType (const PropertyType&, const PropertyInput&, const PropertyInput&) > ConstraintFunction;
334
335   /**
336    * Constructor.
337    * @param [in] func A constraint function.
338    */
339   PropertyConstraint2( const ConstraintFunction& func )
340   : mFunction( func )
341   {
342   }
343
344   /**
345    * Constructor.
346    * @param [in] func A constraint function.
347    * @param [in] input1 A property input.
348    * @param [in] input2 A 2nd property input.
349    */
350   PropertyConstraint2( const ConstraintFunction& func,
351                        const PropertyInputAccessorType& input1,
352                        const PropertyInputAccessorType& input2 )
353   : mFunction( func ),
354     mInput1( input1 ),
355     mInput2( input2 )
356   {
357   }
358
359   /**
360    * Virtual destructor.
361    */
362   virtual ~PropertyConstraint2()
363   {
364   }
365
366   /**
367    * @copydoc PropertyConstraintBase::Clone()
368    */
369   virtual PropertyConstraintBase< PropertyType >* Clone()
370   {
371     return new PropertyConstraint2< PropertyType, PropertyInputAccessorType >( mFunction, mInput1, mInput2 );
372   }
373
374   /**
375    * @copydoc PropertyConstraintBase::CloneComponentFunc()
376    */
377   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc()
378   {
379     return new PropertyConstraint2< PropertyType, PropertyInputComponentAccessor >( mFunction, mInput1, mInput2 );
380   }
381
382   /**
383    * @copydoc PropertyConstraintBase::SetInput()
384    */
385   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input )
386   {
387     DALI_ASSERT_ALWAYS( 2u > index && "Constraint only has 2 properties" );
388
389     if ( 0u == index )
390     {
391       mInput1.SetInput( input, componentIndex );
392     }
393     else
394     {
395       mInput2.SetInput( input, componentIndex );
396     }
397   }
398
399   /**
400    * @copydoc PropertyConstraintBase::GetInput()
401    */
402   virtual const PropertyInputImpl* GetInput( unsigned int index ) const
403   {
404     if ( 0u == index )
405     {
406       return mInput1.GetInput();
407     }
408     else if ( 1u == index )
409     {
410       return mInput2.GetInput();
411     }
412
413     return NULL;
414   }
415
416   /**
417    * @copydoc PropertyConstraintBase::Apply()
418    */
419   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current )
420   {
421     DALI_ASSERT_DEBUG( NULL != mInput1.GetInput() );
422     DALI_ASSERT_DEBUG( NULL != mInput2.GetInput() );
423
424     const PropertyInputIndexer< PropertyInputAccessorType > input1( bufferIndex, &mInput1 );
425     const PropertyInputIndexer< PropertyInputAccessorType > input2( bufferIndex, &mInput2 );
426
427     return mFunction( current,
428                       input1,
429                       input2 );
430   }
431
432 private:
433
434   // Undefined
435   PropertyConstraint2(const PropertyConstraint2&);
436
437   // Undefined
438   PropertyConstraint2& operator=(const PropertyConstraint2& rhs);
439
440 private:
441
442   ConstraintFunction mFunction;
443
444   PropertyInputAccessorType mInput1;
445   PropertyInputAccessorType mInput2;
446 };
447
448 /**
449  * Connects a constraint function with a target property & 3 input properties.
450  */
451 template < class PropertyType, typename PropertyInputAccessorType >
452 class PropertyConstraint3 : public PropertyConstraintBase< PropertyType >
453 {
454 public:
455
456   typedef boost::function< PropertyType (const PropertyType&, const PropertyInput&, const PropertyInput&, const PropertyInput&)> ConstraintFunction;
457
458   /**
459    * Constructor.
460    * @param [in] func A constraint function.
461    */
462   PropertyConstraint3( const ConstraintFunction& func )
463   : mFunction( func )
464   {
465   }
466
467   /**
468    * Constructor.
469    * @param [in] func A constraint function.
470    * @param [in] input1 A property input.
471    * @param [in] input2 A 2nd property input.
472    * @param [in] input3 A 3rd property input.
473    */
474   PropertyConstraint3( const ConstraintFunction& func,
475                        const PropertyInputAccessorType& input1,
476                        const PropertyInputAccessorType& input2,
477                        const PropertyInputAccessorType& input3 )
478   : mFunction( func ),
479     mInput1( input1 ),
480     mInput2( input2 ),
481     mInput3( input3 )
482   {
483   }
484
485   /**
486    * Virtual destructor.
487    */
488   virtual ~PropertyConstraint3()
489   {
490   }
491
492   /**
493    * @copydoc PropertyConstraintBase::Clone()
494    */
495   virtual PropertyConstraintBase< PropertyType >* Clone()
496   {
497     return new PropertyConstraint3< PropertyType, PropertyInputAccessorType >( mFunction, mInput1, mInput2, mInput3 );
498   }
499
500   /**
501    * @copydoc PropertyConstraintBase::CloneComponentFunc()
502    */
503   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc()
504   {
505     return new PropertyConstraint3< PropertyType, PropertyInputComponentAccessor >( mFunction, mInput1, mInput2, mInput3 );
506   }
507
508   /**
509    * @copydoc PropertyConstraintBase::SetInput()
510    */
511   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input )
512   {
513     DALI_ASSERT_ALWAYS( 3u > index && "Constraint only has 3 properties" );
514
515     if ( 0u == index )
516     {
517       mInput1.SetInput( input, componentIndex );
518     }
519     else if ( 1u == index )
520     {
521       mInput2.SetInput( input, componentIndex );
522     }
523     else
524     {
525       mInput3.SetInput( input, componentIndex );
526     }
527   }
528
529   /**
530    * @copydoc PropertyConstraintBase::GetInput()
531    */
532   virtual const PropertyInputImpl* GetInput( unsigned int index ) const
533   {
534     if ( 0u == index )
535     {
536       return mInput1.GetInput();
537     }
538     else if ( 1u == index )
539     {
540       return mInput2.GetInput();
541     }
542     else if ( 2u == index )
543     {
544       return mInput3.GetInput();
545     }
546
547     return NULL;
548   }
549
550   /**
551    * @copydoc PropertyConstraintBase::Apply()
552    */
553   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current )
554   {
555     DALI_ASSERT_DEBUG( NULL != mInput1.GetInput() );
556     DALI_ASSERT_DEBUG( NULL != mInput2.GetInput() );
557     DALI_ASSERT_DEBUG( NULL != mInput3.GetInput() );
558
559     const PropertyInputIndexer< PropertyInputAccessorType > input1( bufferIndex, &mInput1 );
560     const PropertyInputIndexer< PropertyInputAccessorType > input2( bufferIndex, &mInput2 );
561     const PropertyInputIndexer< PropertyInputAccessorType > input3( bufferIndex, &mInput3 );
562
563     return mFunction( current,
564                       input1,
565                       input2,
566                       input3 );
567   }
568
569 private:
570
571   // Undefined
572   PropertyConstraint3(const PropertyConstraint3&);
573
574   // Undefined
575   PropertyConstraint3& operator=(const PropertyConstraint3& rhs);
576
577 private:
578
579   ConstraintFunction mFunction;
580
581   PropertyInputAccessorType mInput1;
582   PropertyInputAccessorType mInput2;
583   PropertyInputAccessorType mInput3;
584 };
585
586 /**
587  * Connects a constraint function with a target property & 4 input properties.
588  */
589 template < class PropertyType, typename PropertyInputAccessorType >
590 class PropertyConstraint4 : public PropertyConstraintBase< PropertyType >
591 {
592 public:
593
594   typedef boost::function< PropertyType (const PropertyType&, const PropertyInput&, const PropertyInput&, const PropertyInput&, const PropertyInput&) > ConstraintFunction;
595
596   /**
597    * Constructor.
598    * @param [in] func A constraint function.
599    */
600   PropertyConstraint4( const ConstraintFunction& func )
601   : mFunction( func )
602   {
603   }
604
605   /**
606    * Constructor.
607    * @param [in] func A constraint function.
608    * @param [in] input1 A property input.
609    * @param [in] input2 A 2nd property input.
610    * @param [in] input3 A 3rd property input.
611    * @param [in] input4 A 4th property input.
612    */
613   PropertyConstraint4( const ConstraintFunction& func,
614                        const PropertyInputAccessorType& input1,
615                        const PropertyInputAccessorType& input2,
616                        const PropertyInputAccessorType& input3,
617                        const PropertyInputAccessorType& input4 )
618   : mFunction( func ),
619     mInput1( input1 ),
620     mInput2( input2 ),
621     mInput3( input3 ),
622     mInput4( input4 )
623   {
624   }
625
626   /**
627    * Create a PropertyConstraint4 instance.
628    * @param [in] func A constraint function.
629    * @return A newly heap-allocated object.
630    */
631   static PropertyConstraintBase< PropertyType >* New( ConstraintFunction func )
632   {
633     return new PropertyConstraint4< PropertyType, PropertyInputAccessorType >( func );
634   }
635
636   /**
637    * Virtual destructor.
638    */
639   virtual ~PropertyConstraint4()
640   {
641   }
642
643   /**
644    * @copydoc PropertyConstraintBase::Clone()
645    */
646   virtual PropertyConstraintBase< PropertyType >* Clone()
647   {
648     return new PropertyConstraint4< PropertyType, PropertyInputAccessorType >( mFunction, mInput1, mInput2, mInput3, mInput4 );
649   }
650
651   /**
652    * @copydoc PropertyConstraintBase::CloneComponentFunc()
653    */
654   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc()
655   {
656     return new PropertyConstraint4< PropertyType, PropertyInputComponentAccessor >( mFunction, mInput1, mInput2, mInput3, mInput4 );
657   }
658
659   /**
660    * @copydoc PropertyConstraintBase::SetInput()
661    */
662   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input )
663   {
664     DALI_ASSERT_ALWAYS( 4u > index && "Constraint only has 4 properties" );
665
666     if ( 0u == index )
667     {
668       mInput1.SetInput( input, componentIndex );
669     }
670     else if ( 1u == index )
671     {
672       mInput2.SetInput( input, componentIndex );
673     }
674     else if ( 2u == index )
675     {
676       mInput3.SetInput( input, componentIndex );
677     }
678     else
679     {
680       mInput4.SetInput( input, componentIndex );
681     }
682   }
683
684   /**
685    * @copydoc PropertyConstraintBase::GetInput()
686    */
687   virtual const PropertyInputImpl* GetInput( unsigned int index ) const
688   {
689     if ( 0u == index )
690     {
691       return mInput1.GetInput();
692     }
693     else if ( 1u == index )
694     {
695       return mInput2.GetInput();
696     }
697     else if ( 2u == index )
698     {
699       return mInput3.GetInput();
700     }
701     else if ( 3u == index )
702     {
703       return mInput4.GetInput();
704     }
705
706     return NULL;
707   }
708
709   /**
710    * @copydoc PropertyConstraintBase::Apply()
711    */
712   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current )
713   {
714     DALI_ASSERT_DEBUG( NULL != mInput1.GetInput() );
715     DALI_ASSERT_DEBUG( NULL != mInput2.GetInput() );
716     DALI_ASSERT_DEBUG( NULL != mInput3.GetInput() );
717     DALI_ASSERT_DEBUG( NULL != mInput4.GetInput() );
718
719     const PropertyInputIndexer< PropertyInputAccessorType > input1( bufferIndex, &mInput1 );
720     const PropertyInputIndexer< PropertyInputAccessorType > input2( bufferIndex, &mInput2 );
721     const PropertyInputIndexer< PropertyInputAccessorType > input3( bufferIndex, &mInput3 );
722     const PropertyInputIndexer< PropertyInputAccessorType > input4( bufferIndex, &mInput4 );
723
724     return mFunction( current,
725                       input1,
726                       input2,
727                       input3,
728                       input4 );
729   }
730
731 private:
732
733   // Undefined
734   PropertyConstraint4(const PropertyConstraint4&);
735
736   // Undefined
737   PropertyConstraint4& operator=(const PropertyConstraint4& rhs);
738
739 private:
740
741   ConstraintFunction mFunction;
742
743   PropertyInputAccessorType mInput1;
744   PropertyInputAccessorType mInput2;
745   PropertyInputAccessorType mInput3;
746   PropertyInputAccessorType mInput4;
747 };
748
749 /**
750  * Connects a constraint function with a target property & 5 input properties.
751  */
752 template < class PropertyType, typename PropertyInputAccessorType >
753 class PropertyConstraint5 : public PropertyConstraintBase< PropertyType >
754 {
755 public:
756
757   typedef boost::function< PropertyType (const PropertyType&, const PropertyInput&, const PropertyInput&, const PropertyInput&, const PropertyInput&, const PropertyInput&) > ConstraintFunction;
758
759   /**
760    * Constructor.
761    * @param [in] func A constraint function.
762    */
763   PropertyConstraint5( const ConstraintFunction& func )
764   : mFunction( func )
765   {
766   }
767
768   /**
769    * Constructor.
770    * @param [in] func A constraint function.
771    * @param [in] input1 A property input.
772    * @param [in] input2 A 2nd property input.
773    * @param [in] input3 A 3rd property input.
774    * @param [in] input4 A 4th property input.
775    * @param [in] input5 A 5th property input.
776    */
777   PropertyConstraint5( const ConstraintFunction& func,
778                        const PropertyInputAccessorType& input1,
779                        const PropertyInputAccessorType& input2,
780                        const PropertyInputAccessorType& input3,
781                        const PropertyInputAccessorType& input4,
782                        const PropertyInputAccessorType& input5 )
783   : mFunction( func ),
784     mInput1( input1 ),
785     mInput2( input2 ),
786     mInput3( input3 ),
787     mInput4( input4 ),
788     mInput5( input5 )
789   {
790   }
791
792   /**
793    * Virtual destructor.
794    */
795   virtual ~PropertyConstraint5()
796   {
797   }
798
799   /**
800    * @copydoc PropertyConstraintBase::Clone()
801    */
802   virtual PropertyConstraintBase< PropertyType >* Clone()
803   {
804     return new PropertyConstraint5< PropertyType, PropertyInputAccessorType >( mFunction, mInput1, mInput2, mInput3, mInput4, mInput5 );
805   }
806
807   /**
808    * @copydoc PropertyConstraintBase::CloneComponentFunc()
809    */
810   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc()
811   {
812     return new PropertyConstraint5< PropertyType, PropertyInputComponentAccessor >( mFunction, mInput1, mInput2, mInput3, mInput4, mInput5 );
813   }
814
815   /**
816    * @copydoc PropertyConstraintBase::SetInput()
817    */
818   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input )
819   {
820     DALI_ASSERT_ALWAYS( 5u > index && "Constraint only has 5 properties");
821
822     if ( 0u == index )
823     {
824       mInput1.SetInput( input, componentIndex );
825     }
826     else if ( 1u == index )
827     {
828       mInput2.SetInput( input, componentIndex );
829     }
830     else if ( 2u == index )
831     {
832       mInput3.SetInput( input, componentIndex );
833     }
834     else if ( 3u == index )
835     {
836       mInput4.SetInput( input, componentIndex );
837     }
838     else
839     {
840       mInput5.SetInput( input, componentIndex );
841     }
842   }
843
844   /**
845    * @copydoc PropertyConstraintBase::GetInput()
846    */
847   virtual const PropertyInputImpl* GetInput( unsigned int index ) const
848   {
849     if ( 0u == index )
850     {
851       return mInput1.GetInput();
852     }
853     else if ( 1u == index )
854     {
855       return mInput2.GetInput();
856     }
857     else if ( 2u == index )
858     {
859       return mInput3.GetInput();
860     }
861     else if ( 3u == index )
862     {
863       return mInput4.GetInput();
864     }
865     else if ( 4u == index )
866     {
867       return mInput5.GetInput();
868     }
869
870     return NULL;
871   }
872
873   /**
874    * @copydoc PropertyConstraintBase::Apply()
875    */
876   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current )
877   {
878     DALI_ASSERT_DEBUG( NULL != mInput1.GetInput() );
879     DALI_ASSERT_DEBUG( NULL != mInput2.GetInput() );
880     DALI_ASSERT_DEBUG( NULL != mInput3.GetInput() );
881     DALI_ASSERT_DEBUG( NULL != mInput4.GetInput() );
882     DALI_ASSERT_DEBUG( NULL != mInput5.GetInput() );
883
884     const PropertyInputIndexer< PropertyInputAccessorType > input1( bufferIndex, &mInput1 );
885     const PropertyInputIndexer< PropertyInputAccessorType > input2( bufferIndex, &mInput2 );
886     const PropertyInputIndexer< PropertyInputAccessorType > input3( bufferIndex, &mInput3 );
887     const PropertyInputIndexer< PropertyInputAccessorType > input4( bufferIndex, &mInput4 );
888     const PropertyInputIndexer< PropertyInputAccessorType > input5( bufferIndex, &mInput5 );
889
890     return mFunction( current,
891                       input1,
892                       input2,
893                       input3,
894                       input4,
895                       input5 );
896   }
897
898 private:
899
900   // Undefined
901   PropertyConstraint5(const PropertyConstraint5&);
902
903   // Undefined
904   PropertyConstraint5& operator=(const PropertyConstraint5& rhs);
905
906 private:
907
908   ConstraintFunction mFunction;
909
910   PropertyInputAccessorType mInput1;
911   PropertyInputAccessorType mInput2;
912   PropertyInputAccessorType mInput3;
913   PropertyInputAccessorType mInput4;
914   PropertyInputAccessorType mInput5;
915 };
916
917 /**
918  * Connects a constraint function with a target property & 6 input properties.
919  */
920 template < class PropertyType, typename PropertyInputAccessorType >
921 class PropertyConstraint6 : public PropertyConstraintBase< PropertyType >
922 {
923 public:
924
925   typedef boost::function< PropertyType (const PropertyType&, const PropertyInput&, const PropertyInput&, const PropertyInput&, const PropertyInput&, const PropertyInput&, const PropertyInput&)> ConstraintFunction;
926
927   /**
928    * Constructor.
929    * @param [in] func A constraint function.
930    */
931   PropertyConstraint6( const ConstraintFunction& func )
932   : mFunction( func )
933   {
934   }
935
936   /**
937    * Constructor.
938    * @param [in] func A constraint function.
939    * @param [in] input1 A property input.
940    * @param [in] input2 A 2nd property input.
941    * @param [in] input3 A 3rd property input.
942    * @param [in] input4 A 4th property input.
943    * @param [in] input5 A 5th property input.
944    * @param [in] input6 A 6th property input.
945    */
946   PropertyConstraint6( const ConstraintFunction& func,
947                        const PropertyInputAccessorType& input1,
948                        const PropertyInputAccessorType& input2,
949                        const PropertyInputAccessorType& input3,
950                        const PropertyInputAccessorType& input4,
951                        const PropertyInputAccessorType& input5,
952                        const PropertyInputAccessorType& input6 )
953   : mFunction( func ),
954     mInput1( input1 ),
955     mInput2( input2 ),
956     mInput3( input3 ),
957     mInput4( input4 ),
958     mInput5( input5 ),
959     mInput6( input6 )
960   {
961   }
962
963   /**
964    * Virtual destructor.
965    */
966   virtual ~PropertyConstraint6()
967   {
968   }
969
970   /**
971    * @copydoc PropertyConstraintBase::Clone()
972    */
973   virtual PropertyConstraintBase< PropertyType >* Clone()
974   {
975     return new PropertyConstraint6< PropertyType, PropertyInputAccessorType >( mFunction, mInput1, mInput2, mInput3, mInput4, mInput5, mInput6 );
976   }
977
978   /**
979    * @copydoc PropertyConstraintBase::CloneComponentFunc()
980    */
981   virtual PropertyConstraintBase< PropertyType >* CloneComponentFunc()
982   {
983     return new PropertyConstraint6< PropertyType, PropertyInputComponentAccessor >( mFunction, mInput1, mInput2, mInput3, mInput4, mInput5, mInput6 );
984   }
985
986   /**
987    * @copydoc PropertyConstraintBase::SetInput()
988    */
989   virtual void SetInput( unsigned int index, int componentIndex, const PropertyInputImpl& input )
990   {
991     DALI_ASSERT_ALWAYS( 6u > index && "Constraint only has 6 properties" );
992
993     if ( 0u == index )
994     {
995       mInput1.SetInput( input, componentIndex );
996     }
997     else if ( 1u == index )
998     {
999       mInput2.SetInput( input, componentIndex );
1000     }
1001     else if ( 2u == index )
1002     {
1003       mInput3.SetInput( input, componentIndex );
1004     }
1005     else if ( 3u == index )
1006     {
1007       mInput4.SetInput( input, componentIndex );
1008     }
1009     else if ( 4u == index )
1010     {
1011       mInput5.SetInput( input, componentIndex );
1012     }
1013     else
1014     {
1015       mInput6.SetInput( input, componentIndex );
1016     }
1017   }
1018
1019   /**
1020    * @copydoc PropertyConstraintBase::GetInput()
1021    */
1022   virtual const PropertyInputImpl* GetInput( unsigned int index ) const
1023   {
1024     if ( 0u == index )
1025     {
1026       return mInput1.GetInput();
1027     }
1028     else if ( 1u == index )
1029     {
1030       return mInput2.GetInput();
1031     }
1032     else if ( 2u == index )
1033     {
1034       return mInput3.GetInput();
1035     }
1036     else if ( 3u == index )
1037     {
1038       return mInput4.GetInput();
1039     }
1040     else if ( 4u == index )
1041     {
1042       return mInput5.GetInput();
1043     }
1044     else if ( 5u == index )
1045     {
1046       return mInput6.GetInput();
1047     }
1048
1049     return NULL;
1050   }
1051
1052   /**
1053    * @copydoc PropertyConstraintBase::Apply()
1054    */
1055   virtual PropertyType Apply( BufferIndex bufferIndex, const PropertyType& current )
1056   {
1057     DALI_ASSERT_DEBUG( NULL != mInput1.GetInput() );
1058     DALI_ASSERT_DEBUG( NULL != mInput2.GetInput() );
1059     DALI_ASSERT_DEBUG( NULL != mInput3.GetInput() );
1060     DALI_ASSERT_DEBUG( NULL != mInput4.GetInput() );
1061     DALI_ASSERT_DEBUG( NULL != mInput5.GetInput() );
1062     DALI_ASSERT_DEBUG( NULL != mInput6.GetInput() );
1063
1064     const PropertyInputIndexer< PropertyInputAccessorType > input1( bufferIndex, &mInput1 );
1065     const PropertyInputIndexer< PropertyInputAccessorType > input2( bufferIndex, &mInput2 );
1066     const PropertyInputIndexer< PropertyInputAccessorType > input3( bufferIndex, &mInput3 );
1067     const PropertyInputIndexer< PropertyInputAccessorType > input4( bufferIndex, &mInput4 );
1068     const PropertyInputIndexer< PropertyInputAccessorType > input5( bufferIndex, &mInput5 );
1069     const PropertyInputIndexer< PropertyInputAccessorType > input6( bufferIndex, &mInput6 );
1070
1071     return mFunction( current,
1072                       input1,
1073                       input2,
1074                       input3,
1075                       input4,
1076                       input5,
1077                       input6 );
1078   }
1079
1080 private:
1081
1082   // Undefined
1083   PropertyConstraint6(const PropertyConstraint6&);
1084
1085   // Undefined
1086   PropertyConstraint6& operator=(const PropertyConstraint6& rhs);
1087
1088 private:
1089
1090   ConstraintFunction mFunction;
1091
1092   PropertyInputAccessorType mInput1;
1093   PropertyInputAccessorType mInput2;
1094   PropertyInputAccessorType mInput3;
1095   PropertyInputAccessorType mInput4;
1096   PropertyInputAccessorType mInput5;
1097   PropertyInputAccessorType mInput6;
1098 };
1099
1100 } // namespace Internal
1101
1102 } // namespace Dali
1103
1104 #endif // __DALI_PROPERTY_CONSTRAINT_H__