Merge "Added animation and constraint support for UNSIGNED_INTEGER property type...
[platform/core/uifw/dali-core.git] / dali / internal / update / common / animatable-property.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_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 <limits>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/object/property.h>
27 #include <dali/public-api/object/property-input.h>
28 #include <dali/public-api/object/property-types.h>
29 #include <dali/internal/common/message.h>
30 #include <dali/internal/event/common/event-thread-services.h>
31 #include <dali/internal/event/common/property-input-impl.h>
32 #include <dali/internal/update/common/double-buffered.h>
33 #include <dali/internal/update/common/property-base.h>
34 #include <dali/internal/update/common/scene-graph-buffers.h>
35
36 namespace Dali
37 {
38
39 namespace Internal
40 {
41
42 namespace SceneGraph
43 {
44
45 /**
46  * Dirty flags record whether an animatable property has changed.
47  * In the frame following a change, the property is reset to a base value.
48  *
49  * If the property was "Baked", then the base value matches the (double-buffered) value from the previous frame.
50  * Therefore when reset, the property is flagged as "clean".
51  *
52  * However if the property was only "Set" (and not "Baked"), then typically the base value and previous value will not match.
53  * In this case the reset operation is equivalent to a "Bake", and the value is considered "dirty" for an additional frame.
54  */
55 static const unsigned int CLEAN_FLAG = 0x00; ///< Indicates that the value did not change in this, or the previous frame
56 static const unsigned int BAKED_FLAG = 0x01; ///< Indicates that the value was Baked during the previous frame
57 static const unsigned int SET_FLAG   = 0x02; ///< Indicates that the value was Set during the previous frame
58
59 template <class T>
60 class AnimatableProperty;
61
62 /**
63  * Base class to reduce code size from the templates.
64  */
65 class AnimatablePropertyBase : public PropertyBase
66 {
67 public:
68
69   /**
70    * Constructor, initialize the dirty flag
71    */
72   AnimatablePropertyBase()
73   : PropertyBase(),
74     mDirtyFlags( BAKED_FLAG )
75   {}
76
77   /**
78    * Virtual destructor.
79    */
80   virtual ~AnimatablePropertyBase()
81   {}
82
83 protected: // for derived classes
84
85   /**
86    * Flag that the property has been Set during the current frame.
87    */
88   void OnSet()
89   {
90     mDirtyFlags = SET_FLAG;
91   }
92
93   /**
94    * Flag that the property has been Baked during the current frame.
95    */
96   void OnBake()
97   {
98     mDirtyFlags = BAKED_FLAG;
99   }
100
101 public: // From PropertyBase
102
103   /**
104    * @copydoc Dali::Internal::SceneGraph::PropertyBase::IsClean()
105    */
106   virtual bool IsClean() const
107   {
108     return ( CLEAN_FLAG == mDirtyFlags );
109   }
110
111   /**
112    * @copydoc Dali::Internal::PropertyInputImpl::InputInitialized()
113    */
114   virtual bool InputInitialized() const
115   {
116     return true; // Animatable properties are always valid
117   }
118
119 protected: // so that ResetToBaseValue can set it directly
120
121   unsigned int mDirtyFlags; ///< Flag whether value changed during previous 2 frames
122
123 };
124
125
126 /**
127  * An boolean animatable property of a scene-graph object.
128  */
129 template <>
130 class AnimatableProperty<bool> : public AnimatablePropertyBase
131 {
132 public:
133
134   /**
135    * Create an animatable property.
136    * @param [in] initialValue The initial value of the property.
137    */
138   AnimatableProperty( bool initialValue )
139   : mValue( initialValue ),
140     mBaseValue( initialValue )
141   {
142   }
143
144   /**
145    * Virtual destructor.
146    */
147   virtual ~AnimatableProperty()
148   {
149   }
150
151   /**
152    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
153    */
154   virtual Dali::Property::Type GetType() const
155   {
156     return Dali::PropertyTypes::Get<bool>();
157   }
158
159   /**
160    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
161    */
162   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
163   {
164     if (CLEAN_FLAG != mDirtyFlags)
165     {
166       mValue[updateBufferIndex] = mBaseValue;
167
168       mDirtyFlags = ( mDirtyFlags >> 1 );
169     }
170   }
171
172   /**
173    * @copydoc Dali::Internal::PropertyInputImpl::GetBoolean()
174    */
175   virtual const bool& GetBoolean( BufferIndex bufferIndex ) const
176   {
177     return mValue[ bufferIndex ];
178   }
179
180   /**
181    * Set the property value. This will only persist for the current frame; the property
182    * will be reset with the base value, at the beginning of the next frame.
183    * @param[in] bufferIndex The buffer to write.
184    * @param[in] value The new property value.
185    */
186   void Set(BufferIndex bufferIndex, bool value)
187   {
188     // check if the value actually changed to avoid dirtying nodes unnecessarily
189     if( mValue[bufferIndex] != value )
190     {
191       mValue[bufferIndex] = value;
192
193       OnSet();
194     }
195   }
196
197   /**
198    * Change the property value by a relative amount.
199    * @param[in] bufferIndex The buffer to write.
200    * @param[in] delta The property will change by this amount.
201    */
202   void SetRelative(BufferIndex bufferIndex, bool delta)
203   {
204     // check if the value actually changed to avoid dirtying nodes unnecessarily
205     // false + false does not change value, true + false does not either
206     if( delta && !mValue[bufferIndex] )
207     {
208       mValue[bufferIndex] += delta;
209
210       OnSet();
211     }
212   }
213
214   /**
215    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
216    */
217   bool& Get(size_t bufferIndex)
218   {
219     return mValue[bufferIndex];
220   }
221
222   /**
223    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
224    */
225   const bool& Get(size_t bufferIndex) const
226   {
227     return mValue[bufferIndex];
228   }
229
230   /**
231    * Retrieve the property value.
232    * @param[in] bufferIndex The buffer to read.
233    * @return The property value.
234    */
235   bool& operator[](size_t bufferIndex)
236   {
237     return mValue[bufferIndex];
238   }
239
240   /**
241    * Retrieve the property value.
242    * @param[in] bufferIndex The buffer to read.
243    * @return The property value.
244    */
245   const bool& operator[](size_t bufferIndex) const
246   {
247     return mValue[bufferIndex];
248   }
249
250   /**
251    * Set both the property value & base value.
252    * @param[in] bufferIndex The buffer to write for the property value.
253    * @param[in] value The new property value.
254    */
255   void Bake(BufferIndex bufferIndex, bool value)
256   {
257     // bake has to check the base value as current buffer value can be correct by constraint or something else
258     if( mBaseValue != value )
259     {
260       mBaseValue = value;
261       mValue[bufferIndex] = value;
262
263       OnBake();
264     }
265   }
266
267   /**
268    * Change the property value & base value by a relative amount.
269    * @param[in] bufferIndex The buffer to write for the local property value.
270    * @param[in] delta The property will change by this amount.
271    */
272   void BakeRelative(BufferIndex bufferIndex, bool delta)
273   {
274     mValue[bufferIndex] += delta;
275     mBaseValue = mValue[bufferIndex];
276
277     OnBake();
278   }
279
280 private:
281
282   // Undefined
283   AnimatableProperty(const AnimatableProperty& property);
284
285   // Undefined
286   AnimatableProperty& operator=(const AnimatableProperty& rhs);
287
288 private:
289
290   DoubleBuffered<bool> mValue; ///< The double-buffered property value
291   bool mBaseValue;             ///< Reset to this base value at the beginning of each frame
292
293 };
294
295
296 /**
297  * An integer animatable property of a scene-graph object.
298  */
299 template <>
300 class AnimatableProperty<int> : public AnimatablePropertyBase
301 {
302 public:
303
304   /**
305    * Create an animatable property.
306    * @param [in] initialValue The initial value of the property.
307    */
308   AnimatableProperty( int initialValue )
309   : mValue( initialValue ),
310     mBaseValue( initialValue )
311   {
312   }
313
314   /**
315    * Virtual destructor.
316    */
317   virtual ~AnimatableProperty()
318   {
319   }
320
321   /**
322    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
323    */
324   virtual Dali::Property::Type GetType() const
325   {
326     return Dali::PropertyTypes::Get<int>();
327   }
328
329   /**
330    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
331    */
332   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
333   {
334     if (CLEAN_FLAG != mDirtyFlags)
335     {
336       mValue[updateBufferIndex] = mBaseValue;
337
338       mDirtyFlags = ( mDirtyFlags >> 1 );
339     }
340   }
341
342   /**
343    * @copydoc Dali::Internal::PropertyInputImpl::GetInteger()
344    */
345   virtual const int& GetInteger( BufferIndex bufferIndex ) const
346   {
347     return mValue[ bufferIndex ];
348   }
349
350   /**
351    * Set the property value. This will only persist for the current frame; the property
352    * will be reset with the base value, at the beginning of the next frame.
353    * @param[in] bufferIndex The buffer to write.
354    * @param[in] value The new property value.
355    */
356   void Set(BufferIndex bufferIndex, int value)
357   {
358     mValue[bufferIndex] = value;
359
360     OnSet();
361   }
362
363   /**
364    * Change the property value by a relative amount.
365    * @param[in] bufferIndex The buffer to write.
366    * @param[in] delta The property will change by this amount.
367    */
368   void SetRelative(BufferIndex bufferIndex, int delta)
369   {
370     mValue[bufferIndex] = mValue[bufferIndex] + delta;
371
372     OnSet();
373   }
374
375   /**
376    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
377    */
378   int& Get(size_t bufferIndex)
379   {
380     return mValue[bufferIndex];
381   }
382
383   /**
384    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
385    */
386   const int& Get(size_t bufferIndex) const
387   {
388     return mValue[bufferIndex];
389   }
390
391   /**
392    * Retrieve the property value.
393    * @param[in] bufferIndex The buffer to read.
394    * @return The property value.
395    */
396   int& operator[](size_t bufferIndex)
397   {
398     return mValue[bufferIndex];
399   }
400
401   /**
402    * Retrieve the property value.
403    * @param[in] bufferIndex The buffer to read.
404    * @return The property value.
405    */
406   const int& operator[](size_t bufferIndex) const
407   {
408     return mValue[bufferIndex];
409   }
410
411   /**
412    * Set both the property value & base value.
413    * @param[in] bufferIndex The buffer to write for the property value.
414    * @param[in] value The new property value.
415    */
416   void Bake(BufferIndex bufferIndex, int value)
417   {
418     mValue[bufferIndex] = value;
419     mBaseValue = mValue[bufferIndex];
420
421     OnBake();
422   }
423
424   /**
425    * Change the property value & base value by a relative amount.
426    * @param[in] bufferIndex The buffer to write for the local property value.
427    * @param[in] delta The property will change by this amount.
428    */
429   void BakeRelative(BufferIndex bufferIndex, int delta)
430   {
431     mValue[bufferIndex] = mValue[bufferIndex] + delta;
432     mBaseValue = mValue[bufferIndex];
433
434     OnBake();
435   }
436
437   /**
438    * Sets both double-buffered values & the base value.
439    * This should only be used when the owning object has not been connected to the scene-graph.
440    * @param[in] value The new property value.
441    */
442   void SetInitial(const int& value)
443   {
444     mValue[0]  = value;
445     mValue[1]  = mValue[0];
446     mBaseValue = mValue[0];
447   }
448
449   /**
450    * Change both double-buffered values & the base value by a relative amount.
451    * This should only be used when the owning object has not been connected to the scene-graph.
452    * @param[in] delta The property will change by this amount.
453    */
454   void SetInitialRelative(const int& delta)
455   {
456     mValue[0] = mValue[0] + delta;
457     mValue[1] = mValue[0];
458     mBaseValue = mValue[0];
459   }
460
461 private:
462
463   // Undefined
464   AnimatableProperty(const AnimatableProperty& property);
465
466   // Undefined
467   AnimatableProperty& operator=(const AnimatableProperty& rhs);
468
469 private:
470
471   DoubleBuffered<int> mValue; ///< The double-buffered property value
472   int mBaseValue;             ///< Reset to this base value at the beginning of each frame
473
474 };
475
476 /**
477  * An unsigned integer animatable property of a scene-graph object.
478  */
479 template <>
480 class AnimatableProperty<unsigned int> : public AnimatablePropertyBase
481 {
482 public:
483
484   /**
485    * Create an animatable property.
486    * @param [in] initialValue The initial value of the property.
487    */
488   AnimatableProperty( unsigned int initialValue )
489   : mValue( initialValue ),
490     mBaseValue( initialValue )
491   {
492   }
493
494   /**
495    * Virtual destructor.
496    */
497   virtual ~AnimatableProperty()
498   {
499   }
500
501   /**
502    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
503    */
504   virtual Dali::Property::Type GetType() const
505   {
506     return Dali::PropertyTypes::Get<unsigned int>();
507   }
508
509   /**
510    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
511    */
512   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
513   {
514     if (CLEAN_FLAG != mDirtyFlags)
515     {
516       mValue[updateBufferIndex] = mBaseValue;
517
518       mDirtyFlags = ( mDirtyFlags >> 1 );
519     }
520   }
521
522   /**
523    * @copydoc Dali::Internal::PropertyInputImpl::GetUnsignedInteger()
524    */
525   virtual const unsigned int& GetUnsignedInteger( BufferIndex bufferIndex ) const
526   {
527     return mValue[ bufferIndex ];
528   }
529
530   /**
531    * Set the property value. This will only persist for the current frame; the property
532    * will be reset with the base value, at the beginning of the next frame.
533    * @param[in] bufferIndex The buffer to write.
534    * @param[in] value The new property value.
535    */
536   void Set(BufferIndex bufferIndex, unsigned int value)
537   {
538     mValue[bufferIndex] = value;
539
540     OnSet();
541   }
542
543   /**
544    * Change the property value by a relative amount.
545    * @param[in] bufferIndex The buffer to write.
546    * @param[in] delta The property will change by this amount.
547    */
548   void SetRelative(BufferIndex bufferIndex, unsigned int delta)
549   {
550     mValue[bufferIndex] = mValue[bufferIndex] + delta;
551
552     OnSet();
553   }
554
555   /**
556    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
557    */
558   unsigned int& Get(size_t bufferIndex)
559   {
560     return mValue[bufferIndex];
561   }
562
563   /**
564    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
565    */
566   const unsigned int& Get(size_t bufferIndex) const
567   {
568     return mValue[bufferIndex];
569   }
570
571   /**
572    * Retrieve the property value.
573    * @param[in] bufferIndex The buffer to read.
574    * @return The property value.
575    */
576   unsigned int& operator[](size_t bufferIndex)
577   {
578     return mValue[bufferIndex];
579   }
580
581   /**
582    * Retrieve the property value.
583    * @param[in] bufferIndex The buffer to read.
584    * @return The property value.
585    */
586   const unsigned int& operator[](size_t bufferIndex) const
587   {
588     return mValue[bufferIndex];
589   }
590
591   /**
592    * Set both the property value & base value.
593    * @param[in] bufferIndex The buffer to write for the property value.
594    * @param[in] value The new property value.
595    */
596   void Bake(BufferIndex bufferIndex, unsigned int value)
597   {
598     mValue[bufferIndex] = value;
599     mBaseValue = mValue[bufferIndex];
600
601     OnBake();
602   }
603
604   /**
605    * Change the property value & base value by a relative amount.
606    * @param[in] bufferIndex The buffer to write for the local property value.
607    * @param[in] delta The property will change by this amount.
608    */
609   void BakeRelative(BufferIndex bufferIndex, unsigned int delta)
610   {
611     mValue[bufferIndex] = mValue[bufferIndex] + delta;
612     mBaseValue = mValue[bufferIndex];
613
614     OnBake();
615   }
616
617   /**
618    * Sets both double-buffered values & the base value.
619    * This should only be used when the owning object has not been connected to the scene-graph.
620    * @param[in] value The new property value.
621    */
622   void SetInitial(const unsigned int& value)
623   {
624     mValue[0]  = value;
625     mValue[1]  = mValue[0];
626     mBaseValue = mValue[0];
627   }
628
629   /**
630    * Change both double-buffered values & the base value by a relative amount.
631    * This should only be used when the owning object has not been connected to the scene-graph.
632    * @param[in] delta The property will change by this amount.
633    */
634   void SetInitialRelative(const unsigned int& delta)
635   {
636     mValue[0] = mValue[0] + delta;
637     mValue[1] = mValue[0];
638     mBaseValue = mValue[0];
639   }
640
641 private:
642
643   // Undefined
644   AnimatableProperty(const AnimatableProperty& property);
645
646   // Undefined
647   AnimatableProperty& operator=(const AnimatableProperty& rhs);
648
649 private:
650   DoubleBuffered<unsigned int> mValue; ///< The double-buffered property value
651   unsigned int mBaseValue;             ///< Reset to this base value at the beginning of each frame
652 };
653
654
655 /**
656  * An float animatable property of a scene-graph object.
657  */
658 template <>
659 class AnimatableProperty<float> : public AnimatablePropertyBase
660 {
661 public:
662
663   /**
664    * Create an animatable property.
665    * @param [in] initialValue The initial value of the property.
666    */
667   AnimatableProperty( float initialValue )
668   : mValue( initialValue ),
669     mBaseValue( initialValue )
670   {
671   }
672
673   /**
674    * Virtual destructor.
675    */
676   virtual ~AnimatableProperty()
677   {
678   }
679
680   /**
681    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
682    */
683   virtual Dali::Property::Type GetType() const
684   {
685     return Dali::PropertyTypes::Get<float>();
686   }
687
688   /**
689    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
690    */
691   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
692   {
693     if (CLEAN_FLAG != mDirtyFlags)
694     {
695       mValue[updateBufferIndex] = mBaseValue;
696
697       mDirtyFlags = ( mDirtyFlags >> 1 );
698     }
699   }
700
701   /**
702    * @copydoc Dali::Internal::PropertyInputImpl::GetFloat()
703    */
704   virtual const float& GetFloat( BufferIndex bufferIndex ) const
705   {
706     return mValue[ bufferIndex ];
707   }
708
709   /**
710    * Set the property value. This will only persist for the current frame; the property
711    * will be reset with the base value, at the beginning of the next frame.
712    * @param[in] bufferIndex The buffer to write.
713    * @param[in] value The new property value.
714    */
715   void Set(BufferIndex bufferIndex, float value)
716   {
717     mValue[bufferIndex] = value;
718
719     OnSet();
720   }
721
722   /**
723    * Change the property value by a relative amount.
724    * @param[in] bufferIndex The buffer to write.
725    * @param[in] delta The property will change by this amount.
726    */
727   void SetRelative(BufferIndex bufferIndex, float delta)
728   {
729     mValue[bufferIndex] = mValue[bufferIndex] + delta;
730
731     OnSet();
732   }
733
734   /**
735    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
736    */
737   float& Get(size_t bufferIndex)
738   {
739     return mValue[bufferIndex];
740   }
741
742   /**
743    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
744    */
745   const float& Get(size_t bufferIndex) const
746   {
747     return mValue[bufferIndex];
748   }
749
750   /**
751    * Retrieve the property value.
752    * @param[in] bufferIndex The buffer to read.
753    * @return The property value.
754    */
755   float& operator[](size_t bufferIndex)
756   {
757     return mValue[bufferIndex];
758   }
759
760   /**
761    * Retrieve the property value.
762    * @param[in] bufferIndex The buffer to read.
763    * @return The property value.
764    */
765   const float& operator[](size_t bufferIndex) const
766   {
767     return mValue[bufferIndex];
768   }
769
770   /**
771    * Set both the property value & base value.
772    * @param[in] bufferIndex The buffer to write for the property value.
773    * @param[in] value The new property value.
774    */
775   void Bake(BufferIndex bufferIndex, float value)
776   {
777     mValue[bufferIndex] = value;
778     mBaseValue = mValue[bufferIndex];
779
780     OnBake();
781   }
782
783   /**
784    * Change the property value & base value by a relative amount.
785    * @param[in] bufferIndex The buffer to write for the local property value.
786    * @param[in] delta The property will change by this amount.
787    */
788   void BakeRelative(BufferIndex bufferIndex, float delta)
789   {
790     mValue[bufferIndex] = mValue[bufferIndex] + delta;
791     mBaseValue = mValue[bufferIndex];
792
793     OnBake();
794   }
795
796   /**
797    * Sets both double-buffered values & the base value.
798    * This should only be used when the owning object has not been connected to the scene-graph.
799    * @param[in] value The new property value.
800    */
801   void SetInitial(const float& value)
802   {
803     mValue[0]  = value;
804     mValue[1]  = mValue[0];
805     mBaseValue = mValue[0];
806   }
807
808   /**
809    * Change both double-buffered values & the base value by a relative amount.
810    * This should only be used when the owning object has not been connected to the scene-graph.
811    * @param[in] delta The property will change by this amount.
812    */
813   void SetInitialRelative(const float& delta)
814   {
815     mValue[0] = mValue[0] + delta;
816     mValue[1] = mValue[0];
817     mBaseValue = mValue[0];
818   }
819
820 private:
821
822   // Undefined
823   AnimatableProperty(const AnimatableProperty& property);
824
825   // Undefined
826   AnimatableProperty& operator=(const AnimatableProperty& rhs);
827
828 private:
829
830   DoubleBuffered<float> mValue; ///< The double-buffered property value
831   float mBaseValue;             ///< Reset to this base value at the beginning of each frame
832 };
833
834 /**
835  * An Vector2 animatable property of a scene-graph object.
836  */
837 template <>
838 class AnimatableProperty<Vector2> : public AnimatablePropertyBase
839 {
840 public:
841
842   /**
843    * Create an animatable property.
844    * @param [in] initialValue The initial value of the property.
845    */
846   AnimatableProperty( const Vector2& initialValue )
847   : mValue( initialValue ),
848     mBaseValue( initialValue )
849   {
850   }
851
852   /**
853    * Virtual destructor.
854    */
855   virtual ~AnimatableProperty()
856   {
857   }
858
859   /**
860    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
861    */
862   virtual Dali::Property::Type GetType() const
863   {
864     return Dali::PropertyTypes::Get<Vector2>();
865   }
866
867   /**
868    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
869    */
870   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
871   {
872     if (CLEAN_FLAG != mDirtyFlags)
873     {
874       mValue[updateBufferIndex] = mBaseValue;
875
876       mDirtyFlags = ( mDirtyFlags >> 1 );
877     }
878   }
879
880   /**
881    * @copydoc Dali::PropertyInput::GetVector2()
882    */
883   virtual const Vector2& GetVector2( BufferIndex bufferIndex ) const
884   {
885     return mValue[ bufferIndex ];
886   }
887
888   /**
889    * Set the property value. This will only persist for the current frame; the property
890    * will be reset with the base value, at the beginning of the next frame.
891    * @param[in] bufferIndex The buffer to write.
892    * @param[in] value The new property value.
893    */
894   void Set(BufferIndex bufferIndex, const Vector2& value)
895   {
896     mValue[bufferIndex] = value;
897
898     OnSet();
899   }
900
901   /**
902    * Change the property value by a relative amount.
903    * @param[in] bufferIndex The buffer to write.
904    * @param[in] delta The property will change by this amount.
905    */
906   void SetRelative(BufferIndex bufferIndex, const Vector2& delta)
907   {
908     mValue[bufferIndex] += delta;
909
910     OnSet();
911   }
912
913   /**
914    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
915    */
916   Vector2& Get(size_t bufferIndex)
917   {
918     return mValue[bufferIndex];
919   }
920
921   /**
922    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
923    */
924   const Vector2& Get(size_t bufferIndex) const
925   {
926     return mValue[bufferIndex];
927   }
928
929   /**
930    * Retrieve the property value.
931    * @param[in] bufferIndex The buffer to read.
932    * @return The property value.
933    */
934   Vector2& operator[](size_t bufferIndex)
935   {
936     return mValue[bufferIndex];
937   }
938
939   /**
940    * Retrieve the property value.
941    * @param[in] bufferIndex The buffer to read.
942    * @return The property value.
943    */
944   const Vector2& operator[](size_t bufferIndex) const
945   {
946     return mValue[bufferIndex];
947   }
948
949   /**
950    * Set both the property value & base value.
951    * @param[in] bufferIndex The buffer to write for the property value.
952    * @param[in] value The new property value.
953    */
954   void Bake(BufferIndex bufferIndex, const Vector2& value)
955   {
956     mValue[bufferIndex] = value;
957     mBaseValue = value;
958
959     OnBake();
960   }
961
962   /**
963    * Change the property value & base value by a relative amount.
964    * @param[in] bufferIndex The buffer to write for the local property value.
965    * @param[in] delta The property will change by this amount.
966    */
967   void BakeRelative(BufferIndex bufferIndex, const Vector2& delta)
968   {
969     mValue[bufferIndex] += delta;
970     mBaseValue = mValue[bufferIndex];
971
972     OnBake();
973   }
974
975 private:
976
977   // Undefined
978   AnimatableProperty(const AnimatableProperty& property);
979
980   // Undefined
981   AnimatableProperty& operator=(const AnimatableProperty& rhs);
982
983 private:
984
985   DoubleBuffered<Vector2> mValue; ///< The double-buffered property value
986   Vector2 mBaseValue;             ///< Reset to this base value at the beginning of each frame
987
988 };
989
990 /**
991  * A Vector3 animatable property of a scene-graph object.
992  */
993 template <>
994 class AnimatableProperty<Vector3> : public AnimatablePropertyBase
995 {
996 public:
997
998   /**
999    * Create an animatable property.
1000    */
1001   AnimatableProperty()
1002   : mValue(),
1003     mBaseValue()
1004   {
1005   }
1006
1007   /**
1008    * Create an animatable property.
1009    * @param [in] initialValue The initial value of the property.
1010    */
1011   AnimatableProperty( const Vector3& initialValue )
1012   : mValue( initialValue ),
1013     mBaseValue( initialValue )
1014   {
1015   }
1016
1017   /**
1018    * Virtual destructor.
1019    */
1020   virtual ~AnimatableProperty()
1021   {
1022   }
1023
1024   /**
1025    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1026    */
1027   virtual Dali::Property::Type GetType() const
1028   {
1029     return Dali::PropertyTypes::Get<Vector3>();
1030   }
1031
1032   /**
1033    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1034    */
1035   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1036   {
1037     if (CLEAN_FLAG != mDirtyFlags)
1038     {
1039       mValue[updateBufferIndex] = mBaseValue;
1040
1041       mDirtyFlags = ( mDirtyFlags >> 1 );
1042     }
1043   }
1044
1045   /**
1046    * @copydoc Dali::PropertyInput::GetVector3()
1047    */
1048   virtual const Vector3& GetVector3( BufferIndex bufferIndex ) const
1049   {
1050     return mValue[ bufferIndex ];
1051   }
1052
1053   /**
1054    * Set the property value. This will only persist for the current frame; the property
1055    * will be reset with the base value, at the beginning of the next frame.
1056    * @param[in] bufferIndex The buffer to write.
1057    * @param[in] value The new property value.
1058    */
1059   void Set(BufferIndex bufferIndex, const Vector3& value)
1060   {
1061     mValue[bufferIndex] = value;
1062
1063     OnSet();
1064   }
1065
1066   /**
1067    * Set the property value. This will only persist for the current frame; the property
1068    * will be reset with the base value, at the beginning of the next frame.
1069    * @param[in] bufferIndex The buffer to write.
1070    * @param[in] value The new X value.
1071    */
1072   void SetX(BufferIndex bufferIndex, float value)
1073   {
1074     mValue[bufferIndex].x = value;
1075
1076     OnSet();
1077   }
1078
1079   /**
1080    * Set the property value. This will only persist for the current frame; the property
1081    * will be reset with the base value, at the beginning of the next frame.
1082    * @param[in] bufferIndex The buffer to write.
1083    * @param[in] value The new Y value.
1084    */
1085   void SetY(BufferIndex bufferIndex, float value)
1086   {
1087     mValue[bufferIndex].y = value;
1088
1089     OnSet();
1090   }
1091
1092   /**
1093    * Set the property value. This will only persist for the current frame; the property
1094    * will be reset with the base value, at the beginning of the next frame.
1095    * @param[in] bufferIndex The buffer to write.
1096    * @param[in] value The new Z value.
1097    */
1098   void SetZ(BufferIndex bufferIndex, float value)
1099   {
1100     mValue[bufferIndex].z = value;
1101
1102     OnSet();
1103   }
1104
1105   /**
1106    * Change the property value by a relative amount.
1107    * @param[in] bufferIndex The buffer to write.
1108    * @param[in] delta The property will change by this amount.
1109    */
1110   void SetRelative(BufferIndex bufferIndex, const Vector3& delta)
1111   {
1112     mValue[bufferIndex] += delta;
1113
1114     OnSet();
1115   }
1116
1117   /**
1118    * Change the X value by a relative amount.
1119    * @param[in] bufferIndex The buffer to write.
1120    * @param[in] delta The X value will change by this amount.
1121    */
1122   void SetXRelative(BufferIndex bufferIndex, float delta)
1123   {
1124     mValue[bufferIndex].x += delta;
1125
1126     OnSet();
1127   }
1128
1129   /**
1130    * Change the Y value by a relative amount.
1131    * @param[in] bufferIndex The buffer to write.
1132    * @param[in] delta The Y value will change by this amount.
1133    */
1134   void SetYRelative(BufferIndex bufferIndex, float delta)
1135   {
1136     mValue[bufferIndex].y += delta;
1137
1138     OnSet();
1139   }
1140
1141   /**
1142    * Change the Z value by a relative amount.
1143    * @param[in] bufferIndex The buffer to write.
1144    * @param[in] delta The Z value will change by this amount.
1145    */
1146   void SetZRelative(BufferIndex bufferIndex, float delta)
1147   {
1148     mValue[bufferIndex].z += delta;
1149
1150     OnSet();
1151   }
1152
1153   /**
1154    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1155    */
1156   Vector3& Get(size_t bufferIndex)
1157   {
1158     return mValue[bufferIndex];
1159   }
1160
1161   /**
1162    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1163    */
1164   const Vector3& Get(size_t bufferIndex) const
1165   {
1166     return mValue[bufferIndex];
1167   }
1168
1169   /**
1170    * Retrieve the property value.
1171    * @param[in] bufferIndex The buffer to read.
1172    * @return The property value.
1173    */
1174   Vector3& operator[](size_t bufferIndex)
1175   {
1176     return mValue[bufferIndex];
1177   }
1178
1179   /**
1180    * Retrieve the property value.
1181    * @param[in] bufferIndex The buffer to read.
1182    * @return The property value.
1183    */
1184   const Vector3& operator[](size_t bufferIndex) const
1185   {
1186     return mValue[bufferIndex];
1187   }
1188
1189   /**
1190    * Set both the property value & base value.
1191    * @param[in] bufferIndex The buffer to write for the property value.
1192    * @param[in] value The new property value.
1193    */
1194   void Bake(BufferIndex bufferIndex, const Vector3& value)
1195   {
1196     mValue[bufferIndex] = value;
1197     mBaseValue = value;
1198
1199     OnBake();
1200   }
1201
1202   /**
1203    * Set both the X value & base X value.
1204    * @param[in] bufferIndex The buffer to write for the property value.
1205    * @param[in] value The new property value.
1206    */
1207   void BakeX(BufferIndex bufferIndex, float value)
1208   {
1209     mValue[bufferIndex].x = value;
1210     mBaseValue.x = value;
1211
1212     OnBake();
1213   }
1214
1215   /**
1216    * Set both the Y value & base Y value.
1217    * @param[in] bufferIndex The buffer to write for the property value.
1218    * @param[in] value The new property value.
1219    */
1220   void BakeY(BufferIndex bufferIndex, float value)
1221   {
1222     mValue[bufferIndex].y = value;
1223     mBaseValue.y = value;
1224
1225     OnBake();
1226   }
1227
1228   /**
1229    * Set both the Z value & base Z value.
1230    * @param[in] bufferIndex The buffer to write for the property value.
1231    * @param[in] value The new property value.
1232    */
1233   void BakeZ(BufferIndex bufferIndex, float value)
1234   {
1235     mValue[bufferIndex].z = value;
1236     mBaseValue.z = value;
1237
1238     OnBake();
1239   }
1240
1241   /**
1242    * Change the property value & base value by a relative amount.
1243    * @param[in] bufferIndex The buffer to write for the local property value.
1244    * @param[in] delta The property will change by this amount.
1245    */
1246   void BakeRelative(BufferIndex bufferIndex, const Vector3& delta)
1247   {
1248     mValue[bufferIndex] += delta;
1249     mBaseValue = mValue[bufferIndex];
1250
1251     OnBake();
1252   }
1253
1254   /**
1255    * Change the property value & base value by a relative amount.
1256    * @param[in] bufferIndex The buffer to write for the local property value.
1257    * @param[in] delta The property will change by this amount.
1258    */
1259   void BakeRelativeMultiply(BufferIndex bufferIndex, const Vector3& delta)
1260   {
1261     mValue[bufferIndex] *= delta;
1262     mBaseValue = mValue[bufferIndex];
1263
1264     OnBake();
1265   }
1266
1267   /**
1268    * Change the X value & base X value by a relative amount.
1269    * @param[in] bufferIndex The buffer to write for the local property value.
1270    * @param[in] delta The X value will change by this amount.
1271    */
1272   void BakeXRelative(BufferIndex bufferIndex, float delta)
1273   {
1274     mValue[bufferIndex].x += delta;
1275     mBaseValue.x = mValue[bufferIndex].x;
1276
1277     OnBake();
1278   }
1279
1280   /**
1281    * Change the Y value & base Y value by a relative amount.
1282    * @param[in] bufferIndex The buffer to write for the local property value.
1283    * @param[in] delta The Y value will change by this amount.
1284    */
1285   void BakeYRelative(BufferIndex bufferIndex, float delta)
1286   {
1287     mValue[bufferIndex].y += delta;
1288     mBaseValue.y = mValue[bufferIndex].y;
1289
1290     OnBake();
1291   }
1292
1293   /**
1294    * Change the Z value & base Z value by a relative amount.
1295    * @param[in] bufferIndex The buffer to write for the local property value.
1296    * @param[in] delta The Z value will change by this amount.
1297    */
1298   void BakeZRelative(BufferIndex bufferIndex, float delta)
1299   {
1300     mValue[bufferIndex].z += delta;
1301     mBaseValue.z = mValue[bufferIndex].z;
1302
1303     OnBake();
1304   }
1305
1306 private:
1307
1308   // Undefined
1309   AnimatableProperty(const AnimatableProperty& property);
1310
1311   // Undefined
1312   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1313
1314 private:
1315
1316   DoubleBuffered<Vector3> mValue; ///< The double-buffered property value
1317   Vector3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1318
1319 };
1320
1321 /**
1322  * A Vector4 animatable property of a scene-graph object.
1323  */
1324 template <>
1325 class AnimatableProperty<Vector4> : public AnimatablePropertyBase
1326 {
1327 public:
1328
1329   /**
1330    * Create an animatable property.
1331    * @param [in] initialValue The initial value of the property.
1332    */
1333   AnimatableProperty( const Vector4& initialValue )
1334   : mValue( initialValue ),
1335     mBaseValue( initialValue )
1336   {
1337   }
1338
1339   /**
1340    * Virtual destructor.
1341    */
1342   virtual ~AnimatableProperty()
1343   {
1344   }
1345
1346   /**
1347    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1348    */
1349   virtual Dali::Property::Type GetType() const
1350   {
1351     return Dali::PropertyTypes::Get<Vector4>();
1352   }
1353
1354   /**
1355    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1356    */
1357   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1358   {
1359     if (CLEAN_FLAG != mDirtyFlags)
1360     {
1361       mValue[updateBufferIndex] = mBaseValue;
1362
1363       mDirtyFlags = ( mDirtyFlags >> 1 );
1364     }
1365   }
1366
1367   /**
1368    * @copydoc Dali::PropertyInput::GetVector4()
1369    */
1370   virtual const Vector4& GetVector4( BufferIndex bufferIndex ) const
1371   {
1372     return mValue[ bufferIndex ];
1373   }
1374
1375   /**
1376    * Set the property value. This will only persist for the current frame; the property
1377    * will be reset with the base value, at the beginning of the next frame.
1378    * @param[in] bufferIndex The buffer to write.
1379    * @param[in] value The new property value.
1380    */
1381   void Set(BufferIndex bufferIndex, const Vector4& value)
1382   {
1383     mValue[bufferIndex] = value;
1384
1385     OnSet();
1386   }
1387
1388   /**
1389    * Set the X value. This will only persist for the current frame; the property
1390    * will be reset with the base value, at the beginning of the next frame.
1391    * @param[in] bufferIndex The buffer to write.
1392    * @param[in] value The new X value.
1393    */
1394   void SetX(BufferIndex bufferIndex, float value)
1395   {
1396     mValue[bufferIndex].x = value;
1397
1398     OnSet();
1399   }
1400
1401   /**
1402    * Set the Y value. This will only persist for the current frame; the property
1403    * will be reset with the base value, at the beginning of the next frame.
1404    * @param[in] bufferIndex The buffer to write.
1405    * @param[in] value The new Y value.
1406    */
1407   void SetY(BufferIndex bufferIndex, float value)
1408   {
1409     mValue[bufferIndex].y = value;
1410
1411     OnSet();
1412   }
1413
1414   /**
1415    * Set the Z value. This will only persist for the current frame; the property
1416    * will be reset with the base value, at the beginning of the next frame.
1417    * @param[in] bufferIndex The buffer to write.
1418    * @param[in] value The new Z value.
1419    */
1420   void SetZ(BufferIndex bufferIndex, float value)
1421   {
1422     mValue[bufferIndex].z = value;
1423
1424     OnSet();
1425   }
1426
1427   /**
1428    * Set the W value. This will only persist for the current frame; the property
1429    * will be reset with the base value, at the beginning of the next frame.
1430    * @param[in] bufferIndex The buffer to write.
1431    * @param[in] value The new W value.
1432    */
1433   void SetW(BufferIndex bufferIndex, float value)
1434   {
1435     mValue[bufferIndex].w = value;
1436
1437     OnSet();
1438   }
1439
1440   /**
1441    * Change the property value by a relative amount.
1442    * @param[in] bufferIndex The buffer to write.
1443    * @param[in] delta The property will change by this amount.
1444    */
1445   void SetRelative(BufferIndex bufferIndex, const Vector4& delta)
1446   {
1447     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1448
1449     OnSet();
1450   }
1451
1452   /**
1453    * Change the X value by a relative amount.
1454    * @param[in] bufferIndex The buffer to write.
1455    * @param[in] delta The X value will change by this amount.
1456    */
1457   void SetXRelative(BufferIndex bufferIndex, float delta)
1458   {
1459     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1460
1461     OnSet();
1462   }
1463
1464   /**
1465    * Change the Y value by a relative amount.
1466    * @param[in] bufferIndex The buffer to write.
1467    * @param[in] delta The Y value will change by this amount.
1468    */
1469   void SetYRelative(BufferIndex bufferIndex, float delta)
1470   {
1471     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1472
1473     OnSet();
1474   }
1475
1476   /**
1477    * Change the Z value by a relative amount.
1478    * @param[in] bufferIndex The buffer to write.
1479    * @param[in] delta The Z value will change by this amount.
1480    */
1481   void SetZRelative(BufferIndex bufferIndex, float delta)
1482   {
1483     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1484
1485     OnSet();
1486   }
1487
1488   /**
1489    * Change the W value by a relative amount.
1490    * @param[in] bufferIndex The buffer to write.
1491    * @param[in] delta The W value will change by this amount.
1492    */
1493   void SetWRelative(BufferIndex bufferIndex, float delta)
1494   {
1495     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1496
1497     OnSet();
1498   }
1499
1500   /**
1501    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1502    */
1503   Vector4& Get(size_t bufferIndex)
1504   {
1505     return mValue[bufferIndex];
1506   }
1507
1508   /**
1509    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1510    */
1511   const Vector4& Get(size_t bufferIndex) const
1512   {
1513     return mValue[bufferIndex];
1514   }
1515
1516   /**
1517    * Retrieve the property value.
1518    * @param[in] bufferIndex The buffer to read.
1519    * @return The property value.
1520    */
1521   Vector4& operator[](size_t bufferIndex)
1522   {
1523     return mValue[bufferIndex];
1524   }
1525
1526   /**
1527    * Retrieve the property value.
1528    * @param[in] bufferIndex The buffer to read.
1529    * @return The property value.
1530    */
1531   const Vector4& operator[](size_t bufferIndex) const
1532   {
1533     return mValue[bufferIndex];
1534   }
1535
1536   /**
1537    * Set both the property value & base value.
1538    * @param[in] bufferIndex The buffer to write for the property value.
1539    * @param[in] value The new property value.
1540    */
1541   void Bake(BufferIndex bufferIndex, const Vector4& value)
1542   {
1543     mValue[bufferIndex] = value;
1544     mBaseValue = mValue[bufferIndex];
1545
1546     OnBake();
1547   }
1548
1549   /**
1550    * Set both the X value & base X value.
1551    * @param[in] bufferIndex The buffer to write for the property value.
1552    * @param[in] value The new property value.
1553    */
1554   void BakeX(BufferIndex bufferIndex, float value)
1555   {
1556     mValue[bufferIndex].x = value;
1557     mBaseValue.x = mValue[bufferIndex].x;
1558
1559     OnBake();
1560   }
1561
1562   /**
1563    * Set both the Y value & base Y value.
1564    * @param[in] bufferIndex The buffer to write for the property value.
1565    * @param[in] value The new property value.
1566    */
1567   void BakeY(BufferIndex bufferIndex, float value)
1568   {
1569     mValue[bufferIndex].y = value;
1570     mBaseValue.y = mValue[bufferIndex].y;
1571
1572     OnBake();
1573   }
1574
1575   /**
1576    * Set both the Z value & base Z value.
1577    * @param[in] bufferIndex The buffer to write for the property value.
1578    * @param[in] value The new property value.
1579    */
1580   void BakeZ(BufferIndex bufferIndex, float value)
1581   {
1582     mValue[bufferIndex].z = value;
1583     mBaseValue.z = mValue[bufferIndex].z;
1584
1585     OnBake();
1586   }
1587
1588   /**
1589    * Set both the W value & base W value.
1590    * @param[in] bufferIndex The buffer to write for the property value.
1591    * @param[in] value The new property value.
1592    */
1593   void BakeW(BufferIndex bufferIndex, float value)
1594   {
1595     mValue[bufferIndex].w = value;
1596     mBaseValue.w = mValue[bufferIndex].w;
1597
1598     OnBake();
1599   }
1600
1601   /**
1602    * Change the property value & base value by a relative amount.
1603    * @param[in] bufferIndex The buffer to write for the local property value.
1604    * @param[in] delta The property will change by this amount.
1605    */
1606   void BakeRelative(BufferIndex bufferIndex, const Vector4& delta)
1607   {
1608     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1609     mBaseValue = mValue[bufferIndex];
1610
1611     OnBake();
1612   }
1613
1614   /**
1615    * Change the X value & base X value by a relative amount.
1616    * @param[in] bufferIndex The buffer to write for the local property value.
1617    * @param[in] delta The X value will change by this amount.
1618    */
1619   void BakeXRelative(BufferIndex bufferIndex, float delta)
1620   {
1621     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1622     mBaseValue.x = mValue[bufferIndex].x;
1623
1624     OnBake();
1625   }
1626
1627   /**
1628    * Change the Y value & base Y value by a relative amount.
1629    * @param[in] bufferIndex The buffer to write for the local property value.
1630    * @param[in] delta The Y value will change by this amount.
1631    */
1632   void BakeYRelative(BufferIndex bufferIndex, float delta)
1633   {
1634     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1635     mBaseValue.y = mValue[bufferIndex].y;
1636
1637     OnBake();
1638   }
1639
1640   /**
1641    * Change the Z value & base Z value by a relative amount.
1642    * @param[in] bufferIndex The buffer to write for the local property value.
1643    * @param[in] delta The Z value will change by this amount.
1644    */
1645   void BakeZRelative(BufferIndex bufferIndex, float delta)
1646   {
1647     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1648     mBaseValue.z = mValue[bufferIndex].z;
1649
1650     OnBake();
1651   }
1652
1653   /**
1654    * Change the W value & base W value by a relative amount.
1655    * @param[in] bufferIndex The buffer to write for the local property value.
1656    * @param[in] delta The W value will change by this amount.
1657    */
1658   void BakeWRelative(BufferIndex bufferIndex, float delta)
1659   {
1660     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1661     mBaseValue.w = mValue[bufferIndex].w;
1662
1663     OnBake();
1664   }
1665
1666   /**
1667    * Sets both double-buffered W values & the base W value.
1668    * This should only be used when the owning object has not been connected to the scene-graph.
1669    * @param[in] value The new W value.
1670    */
1671   void SetWInitial(float value)
1672   {
1673     mValue[0].w  = value;
1674     mValue[1].w  = mValue[0].w;
1675     mBaseValue.w = mValue[0].w;
1676   }
1677
1678 private:
1679
1680   // Undefined
1681   AnimatableProperty(const AnimatableProperty& property);
1682
1683   // Undefined
1684   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1685
1686 private:
1687
1688   DoubleBuffered<Vector4> mValue; ///< The double-buffered property value
1689   Vector4 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1690
1691 };
1692 /**
1693  * An Quaternion animatable property of a scene-graph object.
1694  */
1695 template <>
1696 class AnimatableProperty<Quaternion> : public AnimatablePropertyBase
1697 {
1698 public:
1699
1700   /**
1701    * Create an animatable property.
1702    */
1703   AnimatableProperty()
1704   : mValue(),
1705     mBaseValue()
1706   {
1707   }
1708
1709   /**
1710    * Create an animatable property.
1711    * @param [in] initialValue The initial value of the property.
1712    */
1713   AnimatableProperty( const Quaternion& initialValue )
1714   : mValue( initialValue ),
1715     mBaseValue( initialValue )
1716   {
1717   }
1718
1719   /**
1720    * Virtual destructor.
1721    */
1722   virtual ~AnimatableProperty()
1723   {
1724   }
1725
1726   /**
1727    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1728    */
1729   virtual Dali::Property::Type GetType() const
1730   {
1731     return Dali::PropertyTypes::Get<Quaternion>();
1732   }
1733
1734   /**
1735    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1736    */
1737   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1738   {
1739     if (CLEAN_FLAG != mDirtyFlags)
1740     {
1741       mValue[updateBufferIndex] = mBaseValue;
1742
1743       mDirtyFlags = ( mDirtyFlags >> 1 );
1744     }
1745   }
1746
1747   /**
1748    * @copydoc Dali::PropertyInput::GetQuaternion()
1749    */
1750   virtual const Quaternion& GetQuaternion( BufferIndex bufferIndex ) const
1751   {
1752     return mValue[ bufferIndex ];
1753   }
1754
1755   /**
1756    * Set the property value. This will only persist for the current frame; the property
1757    * will be reset with the base value, at the beginning of the next frame.
1758    * @param[in] bufferIndex The buffer to write.
1759    * @param[in] value The new property value.
1760    */
1761   void Set(BufferIndex bufferIndex, const Quaternion& value)
1762   {
1763     mValue[bufferIndex] = value;
1764
1765     OnSet();
1766   }
1767
1768   /**
1769    * Change the property value by a relative amount.
1770    * @param[in] bufferIndex The buffer to write.
1771    * @param[in] delta The property will change by this amount.
1772    */
1773   void SetRelative(BufferIndex bufferIndex, const Quaternion& delta)
1774   {
1775     mValue[bufferIndex] *= delta;
1776
1777     OnSet();
1778   }
1779
1780   /**
1781    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1782    */
1783   Quaternion& Get(size_t bufferIndex)
1784   {
1785     return mValue[bufferIndex];
1786   }
1787
1788   /**
1789    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1790    */
1791   const Quaternion& Get(size_t bufferIndex) const
1792   {
1793     return mValue[bufferIndex];
1794   }
1795
1796   /**
1797    * Retrieve the property value.
1798    * @param[in] bufferIndex The buffer to read.
1799    * @return The property value.
1800    */
1801   Quaternion& operator[](size_t bufferIndex)
1802   {
1803     return mValue[bufferIndex];
1804   }
1805
1806   /**
1807    * Retrieve the property value.
1808    * @param[in] bufferIndex The buffer to read.
1809    * @return The property value.
1810    */
1811   const Quaternion& operator[](size_t bufferIndex) const
1812   {
1813     return mValue[bufferIndex];
1814   }
1815
1816   /**
1817    * Set both the property value & base value.
1818    * @param[in] bufferIndex The buffer to write for the property value.
1819    * @param[in] value The new property value.
1820    */
1821   void Bake(BufferIndex bufferIndex, const Quaternion& value)
1822   {
1823     mValue[bufferIndex] = value;
1824     mBaseValue = value;
1825
1826     OnBake();
1827   }
1828
1829   /**
1830    * Change the property value & base value by a relative amount.
1831    * @param[in] bufferIndex The buffer to write for the local property value.
1832    * @param[in] delta The property will change by this amount.
1833    */
1834   void BakeRelative(BufferIndex bufferIndex, const Quaternion& delta)
1835   {
1836     mValue[bufferIndex] *= delta;
1837     mBaseValue = mValue[bufferIndex];
1838
1839     OnBake();
1840   }
1841
1842 private:
1843
1844   // Undefined
1845   AnimatableProperty(const AnimatableProperty& property);
1846
1847   // Undefined
1848   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1849
1850 private:
1851
1852   DoubleBuffered<Quaternion> mValue; ///< The double-buffered property value
1853   Quaternion mBaseValue;             ///< Reset to this base value at the beginning of each frame
1854
1855 };
1856
1857 /**
1858  * A Matrix animatable property of a scene-graph object.
1859  */
1860 template <>
1861 class AnimatableProperty<Matrix> : public AnimatablePropertyBase
1862 {
1863 public:
1864
1865   /**
1866    * Create an animatable property.
1867    * @param [in] initialValue The initial value of the property.
1868    */
1869   AnimatableProperty( const Matrix& initialValue )
1870   : mValue( initialValue ),
1871     mBaseValue( initialValue )
1872   {
1873   }
1874
1875   /**
1876    * Virtual destructor.
1877    */
1878   virtual ~AnimatableProperty()
1879   {
1880   }
1881
1882   /**
1883    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1884    */
1885   virtual Dali::Property::Type GetType() const
1886   {
1887     return Dali::PropertyTypes::Get<Matrix>();
1888   }
1889
1890   /**
1891    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1892    */
1893   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1894   {
1895     if (CLEAN_FLAG != mDirtyFlags)
1896     {
1897       mValue[updateBufferIndex] = mBaseValue;
1898
1899       mDirtyFlags = ( mDirtyFlags >> 1 );
1900     }
1901   }
1902
1903   /**
1904    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix()
1905    */
1906   virtual const Matrix& GetMatrix( BufferIndex bufferIndex ) const
1907   {
1908     return mValue[ bufferIndex ];
1909   }
1910
1911   /**
1912    * Set the property value. This will only persist for the current frame; the property
1913    * will be reset with the base value, at the beginning of the next frame.
1914    * @param[in] bufferIndex The buffer to write.
1915    * @param[in] value The new property value.
1916    */
1917   void Set(BufferIndex bufferIndex, const Matrix& value)
1918   {
1919     mValue[bufferIndex] = value;
1920     OnSet();
1921   }
1922
1923
1924   /**
1925    * Change the property value by a relative amount.
1926    * @param[in] bufferIndex The buffer to write.
1927    * @param[in] delta The property will change by this amount.
1928    */
1929   void SetRelative(BufferIndex bufferIndex, const Matrix& delta)
1930   {
1931     Matrix temp;
1932     Matrix::Multiply(temp, mValue[bufferIndex], delta);
1933     mValue[bufferIndex] = temp;
1934
1935     OnSet();
1936   }
1937
1938   /**
1939    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1940    */
1941   Matrix& Get(size_t bufferIndex)
1942   {
1943     return mValue[bufferIndex];
1944   }
1945
1946   /**
1947    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1948    */
1949   const Matrix& Get(size_t bufferIndex) const
1950   {
1951     return mValue[bufferIndex];
1952   }
1953
1954   /**
1955    * Retrieve the property value.
1956    * @param[in] bufferIndex The buffer to read.
1957    * @return The property value.
1958    */
1959   Matrix& operator[](size_t bufferIndex)
1960   {
1961     return mValue[bufferIndex];
1962   }
1963
1964   /**
1965    * Retrieve the property value.
1966    * @param[in] bufferIndex The buffer to read.
1967    * @return The property value.
1968    */
1969   const Matrix& operator[](size_t bufferIndex) const
1970   {
1971     return mValue[bufferIndex];
1972   }
1973
1974   /**
1975    * Set both the property value & base value.
1976    * @param[in] bufferIndex The buffer to write for the property value.
1977    * @param[in] value The new property value.
1978    */
1979   void Bake(BufferIndex bufferIndex, const Matrix& value)
1980   {
1981     mValue[bufferIndex] = value;
1982     mBaseValue = mValue[bufferIndex];
1983
1984     OnBake();
1985   }
1986
1987   /**
1988    * Change the property value & base value by a relative amount.
1989    * @param[in] bufferIndex The buffer to write for the local property value.
1990    * @param[in] delta The property will change by this amount.
1991    */
1992   void BakeRelative(BufferIndex bufferIndex, const Matrix& delta)
1993   {
1994     Matrix temp;
1995     Matrix::Multiply(temp, mValue[bufferIndex], delta);
1996     mValue[bufferIndex] = temp;
1997     mBaseValue = temp;
1998
1999     OnBake();
2000   }
2001
2002 private:
2003
2004   // Undefined
2005   AnimatableProperty(const AnimatableProperty& property);
2006
2007   // Undefined
2008   AnimatableProperty& operator=(const AnimatableProperty& rhs);
2009
2010 private:
2011
2012   DoubleBuffered<Matrix> mValue; ///< The double-buffered property value
2013   Matrix mBaseValue;             ///< Reset to this base value at the beginning of each frame
2014
2015 };
2016
2017 /**
2018  * A Matrix3 animatable property of a scene-graph object.
2019  */
2020 template <>
2021 class AnimatableProperty<Matrix3> : public AnimatablePropertyBase
2022 {
2023 public:
2024
2025   /**
2026    * Create an animatable property.
2027    * @param [in] initialValue The initial value of the property.
2028    */
2029   AnimatableProperty( const Matrix3& initialValue )
2030   : mValue( initialValue ),
2031     mBaseValue( initialValue )
2032   {
2033   }
2034
2035   /**
2036    * Virtual destructor.
2037    */
2038   virtual ~AnimatableProperty()
2039   {
2040   }
2041
2042   /**
2043    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
2044    */
2045   virtual Dali::Property::Type GetType() const
2046   {
2047     return Dali::PropertyTypes::Get<Matrix3>();
2048   }
2049
2050   /**
2051    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
2052    */
2053   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
2054   {
2055     if (CLEAN_FLAG != mDirtyFlags)
2056     {
2057       mValue[updateBufferIndex] = mBaseValue;
2058
2059       mDirtyFlags = ( mDirtyFlags >> 1 );
2060     }
2061   }
2062
2063   /**
2064    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix3()
2065    */
2066   virtual const Matrix3& GetMatrix3( BufferIndex bufferIndex ) const
2067   {
2068     return mValue[ bufferIndex ];
2069   }
2070
2071   /**
2072    * Set the property value. This will only persist for the current frame; the property
2073    * will be reset with the base value, at the beginning of the next frame.
2074    * @param[in] bufferIndex The buffer to write.
2075    * @param[in] value The new property value.
2076    */
2077   void Set(BufferIndex bufferIndex, const Matrix3& value)
2078   {
2079     mValue[bufferIndex] = value;
2080     OnSet();
2081   }
2082
2083   /**
2084    * Change the property value by a relative amount.
2085    * @param[in] bufferIndex The buffer to write.
2086    * @param[in] delta The property will change by this amount.
2087    */
2088   void SetRelative(BufferIndex bufferIndex, const Matrix3& delta)
2089   {
2090     Matrix3 temp;
2091     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
2092     mValue[bufferIndex] = temp;
2093     OnSet();
2094   }
2095
2096   /**
2097    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
2098    */
2099   Matrix3& Get(size_t bufferIndex)
2100   {
2101     return mValue[bufferIndex];
2102   }
2103
2104   /**
2105    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
2106    */
2107   const Matrix3& Get(size_t bufferIndex) const
2108   {
2109     return mValue[bufferIndex];
2110   }
2111
2112   /**
2113    * Retrieve the property value.
2114    * @param[in] bufferIndex The buffer to read.
2115    * @return The property value.
2116    */
2117   Matrix3& operator[](size_t bufferIndex)
2118   {
2119     return mValue[bufferIndex];
2120   }
2121
2122   /**
2123    * Retrieve the property value.
2124    * @param[in] bufferIndex The buffer to read.
2125    * @return The property value.
2126    */
2127   const Matrix3& operator[](size_t bufferIndex) const
2128   {
2129     return mValue[bufferIndex];
2130   }
2131
2132   /**
2133    * Set both the property value & base value.
2134    * @param[in] bufferIndex The buffer to write for the property value.
2135    * @param[in] value The new property value.
2136    */
2137   void Bake(BufferIndex bufferIndex, const Matrix3& value)
2138   {
2139     mValue[bufferIndex] = value;
2140     mBaseValue = mValue[bufferIndex];
2141
2142     OnBake();
2143   }
2144
2145   /**
2146    * Change the property value & base value by a relative amount.
2147    * @param[in] bufferIndex The buffer to write for the local property value.
2148    * @param[in] delta The property will change by this amount.
2149    */
2150   void BakeRelative(BufferIndex bufferIndex, const Matrix3& delta)
2151   {
2152     Matrix3 temp;
2153     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
2154     mValue[bufferIndex] = temp;
2155     mBaseValue = temp;
2156
2157     OnBake();
2158   }
2159
2160 private:
2161
2162   // Undefined
2163   AnimatableProperty(const AnimatableProperty& property);
2164
2165   // Undefined
2166   AnimatableProperty& operator=(const AnimatableProperty& rhs);
2167
2168 private:
2169
2170   DoubleBuffered<Matrix3> mValue; ///< The double-buffered property value
2171   Matrix3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
2172
2173 };
2174
2175 } // namespace SceneGraph
2176
2177 // Messages for AnimatableProperty<T>
2178
2179 template <class T>
2180 void BakeMessage( EventThreadServices& eventThreadServices,
2181                   const SceneGraph::AnimatableProperty<T>& property,
2182                   typename ParameterType< T >::PassingType newValue )
2183 {
2184   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, T > LocalType;
2185
2186   // Reserve some memory inside the message queue
2187   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2188
2189   // Construct message in the message queue memory; note that delete should not be called on the return value
2190   new (slot) LocalType( &property,
2191                         &SceneGraph::AnimatableProperty<T>::Bake,
2192                         newValue );
2193 }
2194
2195 template <class T>
2196 void BakeRelativeMessage( EventThreadServices& eventThreadServices,
2197                           const SceneGraph::AnimatableProperty<T>& property,
2198                           const T& delta )
2199 {
2200   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, const T& > LocalType;
2201
2202   // Reserve some memory inside the message queue
2203   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2204
2205   // Construct message in the message queue memory; note that delete should not be called on the return value
2206   new (slot) LocalType( &property,
2207                         &SceneGraph::AnimatableProperty<T>::BakeRelative,
2208                          delta );
2209 }
2210
2211 template <class T>
2212 void SetXComponentMessage( EventThreadServices& eventThreadServices,
2213                            const SceneGraph::AnimatableProperty<T>& property,
2214                            typename ParameterType< float >::PassingType newValue )
2215 {
2216   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2217
2218   // Reserve some memory inside the message queue
2219   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2220
2221   // Construct message in the message queue memory; note that delete should not be called on the return value
2222   new (slot) LocalType( &property,
2223                         &SceneGraph::AnimatableProperty<T>::BakeX,
2224                         newValue );
2225 }
2226
2227 template <class T>
2228 void SetYComponentMessage( EventThreadServices& eventThreadServices,
2229                            const SceneGraph::AnimatableProperty<T>& property,
2230                            typename ParameterType< float >::PassingType newValue )
2231 {
2232   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2233
2234   // Reserve some memory inside the message queue
2235   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2236
2237   // Construct message in the message queue memory; note that delete should not be called on the return value
2238   new (slot) LocalType( &property,
2239                         &SceneGraph::AnimatableProperty<T>::BakeY,
2240                         newValue );
2241 }
2242
2243 template <class T>
2244 void SetZComponentMessage( EventThreadServices& eventThreadServices,
2245                            const SceneGraph::AnimatableProperty<T>& property,
2246                            typename ParameterType< float >::PassingType newValue )
2247 {
2248   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2249
2250   // Reserve some memory inside the message queue
2251   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2252
2253   // Construct message in the message queue memory; note that delete should not be called on the return value
2254   new (slot) LocalType( &property,
2255                         &SceneGraph::AnimatableProperty<T>::BakeZ,
2256                         newValue );
2257 }
2258
2259 template <class T>
2260 void SetWComponentMessage( EventThreadServices& eventThreadServices,
2261                            const SceneGraph::AnimatableProperty<T>& property,
2262                            typename ParameterType< float >::PassingType newValue )
2263 {
2264   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2265
2266   // Reserve some memory inside the message queue
2267   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2268
2269   // Construct message in the message queue memory; note that delete should not be called on the return value
2270   new (slot) LocalType( &property,
2271                         &SceneGraph::AnimatableProperty<T>::BakeW,
2272                         newValue );
2273 }
2274
2275 } // namespace Internal
2276
2277 } // namespace Dali
2278
2279 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__