Merge remote-tracking branch 'origin/tizen' into devel/new_mesh
[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) 2015 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    * Set the property value. This will only persist for the current frame; the property
903    * will be reset with the base value, at the beginning of the next frame.
904    * @param[in] bufferIndex The buffer to write.
905    * @param[in] value The new X value.
906    */
907   void SetX(BufferIndex bufferIndex, float value)
908   {
909     mValue[bufferIndex].x = value;
910
911     OnSet();
912   }
913
914   /**
915    * Set the property value. This will only persist for the current frame; the property
916    * will be reset with the base value, at the beginning of the next frame.
917    * @param[in] bufferIndex The buffer to write.
918    * @param[in] value The new Y value.
919    */
920   void SetY(BufferIndex bufferIndex, float value)
921   {
922     mValue[bufferIndex].y = value;
923
924     OnSet();
925   }
926
927   /**
928    * Change the property value by a relative amount.
929    * @param[in] bufferIndex The buffer to write.
930    * @param[in] delta The property will change by this amount.
931    */
932   void SetRelative(BufferIndex bufferIndex, const Vector2& delta)
933   {
934     mValue[bufferIndex] += delta;
935
936     OnSet();
937   }
938
939   /**
940    * Change the X value by a relative amount.
941    * @param[in] bufferIndex The buffer to write.
942    * @param[in] delta The X value will change by this amount.
943    */
944   void SetXRelative(BufferIndex bufferIndex, float delta)
945   {
946     mValue[bufferIndex].x += delta;
947
948     OnSet();
949   }
950
951   /**
952    * Change the Y value by a relative amount.
953    * @param[in] bufferIndex The buffer to write.
954    * @param[in] delta The Y value will change by this amount.
955    */
956   void SetYRelative(BufferIndex bufferIndex, float delta)
957   {
958     mValue[bufferIndex].y += delta;
959
960     OnSet();
961   }
962
963   /**
964    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
965    */
966   Vector2& Get(size_t bufferIndex)
967   {
968     return mValue[bufferIndex];
969   }
970
971   /**
972    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
973    */
974   const Vector2& Get(size_t bufferIndex) const
975   {
976     return mValue[bufferIndex];
977   }
978
979   /**
980    * Retrieve the property value.
981    * @param[in] bufferIndex The buffer to read.
982    * @return The property value.
983    */
984   Vector2& operator[](size_t bufferIndex)
985   {
986     return mValue[bufferIndex];
987   }
988
989   /**
990    * Retrieve the property value.
991    * @param[in] bufferIndex The buffer to read.
992    * @return The property value.
993    */
994   const Vector2& operator[](size_t bufferIndex) const
995   {
996     return mValue[bufferIndex];
997   }
998
999   /**
1000    * Set both the property value & base value.
1001    * @param[in] bufferIndex The buffer to write for the property value.
1002    * @param[in] value The new property value.
1003    */
1004   void Bake(BufferIndex bufferIndex, const Vector2& value)
1005   {
1006     mValue[bufferIndex] = value;
1007     mBaseValue = value;
1008
1009     OnBake();
1010   }
1011
1012   /**
1013    * Set both the X value & base X value.
1014    * @param[in] bufferIndex The buffer to write for the property value.
1015    * @param[in] value The new property value.
1016    */
1017   void BakeX(BufferIndex bufferIndex, float value)
1018   {
1019     mValue[bufferIndex].x = value;
1020     mBaseValue.x = value;
1021
1022     OnBake();
1023   }
1024
1025   /**
1026    * Set both the Y value & base Y value.
1027    * @param[in] bufferIndex The buffer to write for the property value.
1028    * @param[in] value The new property value.
1029    */
1030   void BakeY(BufferIndex bufferIndex, float value)
1031   {
1032     mValue[bufferIndex].y = value;
1033     mBaseValue.y = value;
1034
1035     OnBake();
1036   }
1037
1038   /**
1039    * Change the property value & base value by a relative amount.
1040    * @param[in] bufferIndex The buffer to write for the local property value.
1041    * @param[in] delta The property will change by this amount.
1042    */
1043   void BakeRelative(BufferIndex bufferIndex, const Vector2& delta)
1044   {
1045     mValue[bufferIndex] += delta;
1046     mBaseValue = mValue[bufferIndex];
1047
1048     OnBake();
1049   }
1050
1051   /**
1052    * Change the X value & base X value by a relative amount.
1053    * @param[in] bufferIndex The buffer to write for the local property value.
1054    * @param[in] delta The X value will change by this amount.
1055    */
1056   void BakeXRelative(BufferIndex bufferIndex, float delta)
1057   {
1058     mValue[bufferIndex].x += delta;
1059     mBaseValue.x = mValue[bufferIndex].x;
1060
1061     OnBake();
1062   }
1063
1064   /**
1065    * Change the Y value & base Y value by a relative amount.
1066    * @param[in] bufferIndex The buffer to write for the local property value.
1067    * @param[in] delta The Y value will change by this amount.
1068    */
1069   void BakeYRelative(BufferIndex bufferIndex, float delta)
1070   {
1071     mValue[bufferIndex].y += delta;
1072     mBaseValue.y = mValue[bufferIndex].y;
1073
1074     OnBake();
1075   }
1076
1077 private:
1078
1079   // Undefined
1080   AnimatableProperty(const AnimatableProperty& property);
1081
1082   // Undefined
1083   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1084
1085 private:
1086
1087   DoubleBuffered<Vector2> mValue; ///< The double-buffered property value
1088   Vector2 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1089
1090 };
1091
1092 /**
1093  * A Vector3 animatable property of a scene-graph object.
1094  */
1095 template <>
1096 class AnimatableProperty<Vector3> : public AnimatablePropertyBase
1097 {
1098 public:
1099
1100   /**
1101    * Create an animatable property.
1102    */
1103   AnimatableProperty()
1104   : mValue(),
1105     mBaseValue()
1106   {
1107   }
1108
1109   /**
1110    * Create an animatable property.
1111    * @param [in] initialValue The initial value of the property.
1112    */
1113   AnimatableProperty( const Vector3& initialValue )
1114   : mValue( initialValue ),
1115     mBaseValue( initialValue )
1116   {
1117   }
1118
1119   /**
1120    * Virtual destructor.
1121    */
1122   virtual ~AnimatableProperty()
1123   {
1124   }
1125
1126   /**
1127    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1128    */
1129   virtual Dali::Property::Type GetType() const
1130   {
1131     return Dali::PropertyTypes::Get<Vector3>();
1132   }
1133
1134   /**
1135    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1136    */
1137   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1138   {
1139     if (CLEAN_FLAG != mDirtyFlags)
1140     {
1141       mValue[updateBufferIndex] = mBaseValue;
1142
1143       mDirtyFlags = ( mDirtyFlags >> 1 );
1144     }
1145   }
1146
1147   /**
1148    * @copydoc Dali::PropertyInput::GetVector3()
1149    */
1150   virtual const Vector3& GetVector3( BufferIndex bufferIndex ) const
1151   {
1152     return mValue[ bufferIndex ];
1153   }
1154
1155   /**
1156    * Set the property value. This will only persist for the current frame; the property
1157    * will be reset with the base value, at the beginning of the next frame.
1158    * @param[in] bufferIndex The buffer to write.
1159    * @param[in] value The new property value.
1160    */
1161   void Set(BufferIndex bufferIndex, const Vector3& value)
1162   {
1163     mValue[bufferIndex] = value;
1164
1165     OnSet();
1166   }
1167
1168   /**
1169    * Set the property value. This will only persist for the current frame; the property
1170    * will be reset with the base value, at the beginning of the next frame.
1171    * @param[in] bufferIndex The buffer to write.
1172    * @param[in] value The new X value.
1173    */
1174   void SetX(BufferIndex bufferIndex, float value)
1175   {
1176     mValue[bufferIndex].x = value;
1177
1178     OnSet();
1179   }
1180
1181   /**
1182    * Set the property value. This will only persist for the current frame; the property
1183    * will be reset with the base value, at the beginning of the next frame.
1184    * @param[in] bufferIndex The buffer to write.
1185    * @param[in] value The new Y value.
1186    */
1187   void SetY(BufferIndex bufferIndex, float value)
1188   {
1189     mValue[bufferIndex].y = value;
1190
1191     OnSet();
1192   }
1193
1194   /**
1195    * Set the property value. This will only persist for the current frame; the property
1196    * will be reset with the base value, at the beginning of the next frame.
1197    * @param[in] bufferIndex The buffer to write.
1198    * @param[in] value The new Z value.
1199    */
1200   void SetZ(BufferIndex bufferIndex, float value)
1201   {
1202     mValue[bufferIndex].z = value;
1203
1204     OnSet();
1205   }
1206
1207   /**
1208    * Change the property value by a relative amount.
1209    * @param[in] bufferIndex The buffer to write.
1210    * @param[in] delta The property will change by this amount.
1211    */
1212   void SetRelative(BufferIndex bufferIndex, const Vector3& delta)
1213   {
1214     mValue[bufferIndex] += delta;
1215
1216     OnSet();
1217   }
1218
1219   /**
1220    * Change the X value by a relative amount.
1221    * @param[in] bufferIndex The buffer to write.
1222    * @param[in] delta The X value will change by this amount.
1223    */
1224   void SetXRelative(BufferIndex bufferIndex, float delta)
1225   {
1226     mValue[bufferIndex].x += delta;
1227
1228     OnSet();
1229   }
1230
1231   /**
1232    * Change the Y value by a relative amount.
1233    * @param[in] bufferIndex The buffer to write.
1234    * @param[in] delta The Y value will change by this amount.
1235    */
1236   void SetYRelative(BufferIndex bufferIndex, float delta)
1237   {
1238     mValue[bufferIndex].y += delta;
1239
1240     OnSet();
1241   }
1242
1243   /**
1244    * Change the Z value by a relative amount.
1245    * @param[in] bufferIndex The buffer to write.
1246    * @param[in] delta The Z value will change by this amount.
1247    */
1248   void SetZRelative(BufferIndex bufferIndex, float delta)
1249   {
1250     mValue[bufferIndex].z += delta;
1251
1252     OnSet();
1253   }
1254
1255   /**
1256    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1257    */
1258   Vector3& Get(size_t bufferIndex)
1259   {
1260     return mValue[bufferIndex];
1261   }
1262
1263   /**
1264    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1265    */
1266   const Vector3& Get(size_t bufferIndex) const
1267   {
1268     return mValue[bufferIndex];
1269   }
1270
1271   /**
1272    * Retrieve the property value.
1273    * @param[in] bufferIndex The buffer to read.
1274    * @return The property value.
1275    */
1276   Vector3& operator[](size_t bufferIndex)
1277   {
1278     return mValue[bufferIndex];
1279   }
1280
1281   /**
1282    * Retrieve the property value.
1283    * @param[in] bufferIndex The buffer to read.
1284    * @return The property value.
1285    */
1286   const Vector3& operator[](size_t bufferIndex) const
1287   {
1288     return mValue[bufferIndex];
1289   }
1290
1291   /**
1292    * Set both the property value & base value.
1293    * @param[in] bufferIndex The buffer to write for the property value.
1294    * @param[in] value The new property value.
1295    */
1296   void Bake(BufferIndex bufferIndex, const Vector3& value)
1297   {
1298     mValue[bufferIndex] = value;
1299     mBaseValue = value;
1300
1301     OnBake();
1302   }
1303
1304   /**
1305    * Set both the X value & base X value.
1306    * @param[in] bufferIndex The buffer to write for the property value.
1307    * @param[in] value The new property value.
1308    */
1309   void BakeX(BufferIndex bufferIndex, float value)
1310   {
1311     mValue[bufferIndex].x = value;
1312     mBaseValue.x = value;
1313
1314     OnBake();
1315   }
1316
1317   /**
1318    * Set both the Y value & base Y value.
1319    * @param[in] bufferIndex The buffer to write for the property value.
1320    * @param[in] value The new property value.
1321    */
1322   void BakeY(BufferIndex bufferIndex, float value)
1323   {
1324     mValue[bufferIndex].y = value;
1325     mBaseValue.y = value;
1326
1327     OnBake();
1328   }
1329
1330   /**
1331    * Set both the Z value & base Z value.
1332    * @param[in] bufferIndex The buffer to write for the property value.
1333    * @param[in] value The new property value.
1334    */
1335   void BakeZ(BufferIndex bufferIndex, float value)
1336   {
1337     mValue[bufferIndex].z = value;
1338     mBaseValue.z = value;
1339
1340     OnBake();
1341   }
1342
1343   /**
1344    * Change the property value & base value by a relative amount.
1345    * @param[in] bufferIndex The buffer to write for the local property value.
1346    * @param[in] delta The property will change by this amount.
1347    */
1348   void BakeRelative(BufferIndex bufferIndex, const Vector3& delta)
1349   {
1350     mValue[bufferIndex] += delta;
1351     mBaseValue = mValue[bufferIndex];
1352
1353     OnBake();
1354   }
1355
1356   /**
1357    * Change the property value & base value by a relative amount.
1358    * @param[in] bufferIndex The buffer to write for the local property value.
1359    * @param[in] delta The property will change by this amount.
1360    */
1361   void BakeRelativeMultiply(BufferIndex bufferIndex, const Vector3& delta)
1362   {
1363     mValue[bufferIndex] *= delta;
1364     mBaseValue = mValue[bufferIndex];
1365
1366     OnBake();
1367   }
1368
1369   /**
1370    * Change the X value & base X value by a relative amount.
1371    * @param[in] bufferIndex The buffer to write for the local property value.
1372    * @param[in] delta The X value will change by this amount.
1373    */
1374   void BakeXRelative(BufferIndex bufferIndex, float delta)
1375   {
1376     mValue[bufferIndex].x += delta;
1377     mBaseValue.x = mValue[bufferIndex].x;
1378
1379     OnBake();
1380   }
1381
1382   /**
1383    * Change the Y value & base Y value by a relative amount.
1384    * @param[in] bufferIndex The buffer to write for the local property value.
1385    * @param[in] delta The Y value will change by this amount.
1386    */
1387   void BakeYRelative(BufferIndex bufferIndex, float delta)
1388   {
1389     mValue[bufferIndex].y += delta;
1390     mBaseValue.y = mValue[bufferIndex].y;
1391
1392     OnBake();
1393   }
1394
1395   /**
1396    * Change the Z value & base Z value by a relative amount.
1397    * @param[in] bufferIndex The buffer to write for the local property value.
1398    * @param[in] delta The Z value will change by this amount.
1399    */
1400   void BakeZRelative(BufferIndex bufferIndex, float delta)
1401   {
1402     mValue[bufferIndex].z += delta;
1403     mBaseValue.z = mValue[bufferIndex].z;
1404
1405     OnBake();
1406   }
1407
1408 private:
1409
1410   // Undefined
1411   AnimatableProperty(const AnimatableProperty& property);
1412
1413   // Undefined
1414   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1415
1416 private:
1417
1418   DoubleBuffered<Vector3> mValue; ///< The double-buffered property value
1419   Vector3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1420
1421 };
1422
1423 /**
1424  * A Vector4 animatable property of a scene-graph object.
1425  */
1426 template <>
1427 class AnimatableProperty<Vector4> : public AnimatablePropertyBase
1428 {
1429 public:
1430
1431   /**
1432    * Create an animatable property.
1433    * @param [in] initialValue The initial value of the property.
1434    */
1435   AnimatableProperty( const Vector4& initialValue )
1436   : mValue( initialValue ),
1437     mBaseValue( initialValue )
1438   {
1439   }
1440
1441   /**
1442    * Virtual destructor.
1443    */
1444   virtual ~AnimatableProperty()
1445   {
1446   }
1447
1448   /**
1449    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1450    */
1451   virtual Dali::Property::Type GetType() const
1452   {
1453     return Dali::PropertyTypes::Get<Vector4>();
1454   }
1455
1456   /**
1457    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1458    */
1459   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1460   {
1461     if (CLEAN_FLAG != mDirtyFlags)
1462     {
1463       mValue[updateBufferIndex] = mBaseValue;
1464
1465       mDirtyFlags = ( mDirtyFlags >> 1 );
1466     }
1467   }
1468
1469   /**
1470    * @copydoc Dali::PropertyInput::GetVector4()
1471    */
1472   virtual const Vector4& GetVector4( BufferIndex bufferIndex ) const
1473   {
1474     return mValue[ bufferIndex ];
1475   }
1476
1477   /**
1478    * Set the property value. This will only persist for the current frame; the property
1479    * will be reset with the base value, at the beginning of the next frame.
1480    * @param[in] bufferIndex The buffer to write.
1481    * @param[in] value The new property value.
1482    */
1483   void Set(BufferIndex bufferIndex, const Vector4& value)
1484   {
1485     mValue[bufferIndex] = value;
1486
1487     OnSet();
1488   }
1489
1490   /**
1491    * Set the X value. This will only persist for the current frame; the property
1492    * will be reset with the base value, at the beginning of the next frame.
1493    * @param[in] bufferIndex The buffer to write.
1494    * @param[in] value The new X value.
1495    */
1496   void SetX(BufferIndex bufferIndex, float value)
1497   {
1498     mValue[bufferIndex].x = value;
1499
1500     OnSet();
1501   }
1502
1503   /**
1504    * Set the Y value. This will only persist for the current frame; the property
1505    * will be reset with the base value, at the beginning of the next frame.
1506    * @param[in] bufferIndex The buffer to write.
1507    * @param[in] value The new Y value.
1508    */
1509   void SetY(BufferIndex bufferIndex, float value)
1510   {
1511     mValue[bufferIndex].y = value;
1512
1513     OnSet();
1514   }
1515
1516   /**
1517    * Set the Z value. This will only persist for the current frame; the property
1518    * will be reset with the base value, at the beginning of the next frame.
1519    * @param[in] bufferIndex The buffer to write.
1520    * @param[in] value The new Z value.
1521    */
1522   void SetZ(BufferIndex bufferIndex, float value)
1523   {
1524     mValue[bufferIndex].z = value;
1525
1526     OnSet();
1527   }
1528
1529   /**
1530    * Set the W value. This will only persist for the current frame; the property
1531    * will be reset with the base value, at the beginning of the next frame.
1532    * @param[in] bufferIndex The buffer to write.
1533    * @param[in] value The new W value.
1534    */
1535   void SetW(BufferIndex bufferIndex, float value)
1536   {
1537     mValue[bufferIndex].w = value;
1538
1539     OnSet();
1540   }
1541
1542   /**
1543    * Change the property value by a relative amount.
1544    * @param[in] bufferIndex The buffer to write.
1545    * @param[in] delta The property will change by this amount.
1546    */
1547   void SetRelative(BufferIndex bufferIndex, const Vector4& delta)
1548   {
1549     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1550
1551     OnSet();
1552   }
1553
1554   /**
1555    * Change the X value by a relative amount.
1556    * @param[in] bufferIndex The buffer to write.
1557    * @param[in] delta The X value will change by this amount.
1558    */
1559   void SetXRelative(BufferIndex bufferIndex, float delta)
1560   {
1561     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1562
1563     OnSet();
1564   }
1565
1566   /**
1567    * Change the Y value by a relative amount.
1568    * @param[in] bufferIndex The buffer to write.
1569    * @param[in] delta The Y value will change by this amount.
1570    */
1571   void SetYRelative(BufferIndex bufferIndex, float delta)
1572   {
1573     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1574
1575     OnSet();
1576   }
1577
1578   /**
1579    * Change the Z value by a relative amount.
1580    * @param[in] bufferIndex The buffer to write.
1581    * @param[in] delta The Z value will change by this amount.
1582    */
1583   void SetZRelative(BufferIndex bufferIndex, float delta)
1584   {
1585     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1586
1587     OnSet();
1588   }
1589
1590   /**
1591    * Change the W value by a relative amount.
1592    * @param[in] bufferIndex The buffer to write.
1593    * @param[in] delta The W value will change by this amount.
1594    */
1595   void SetWRelative(BufferIndex bufferIndex, float delta)
1596   {
1597     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1598
1599     OnSet();
1600   }
1601
1602   /**
1603    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1604    */
1605   Vector4& Get(size_t bufferIndex)
1606   {
1607     return mValue[bufferIndex];
1608   }
1609
1610   /**
1611    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1612    */
1613   const Vector4& Get(size_t bufferIndex) const
1614   {
1615     return mValue[bufferIndex];
1616   }
1617
1618   /**
1619    * Retrieve the property value.
1620    * @param[in] bufferIndex The buffer to read.
1621    * @return The property value.
1622    */
1623   Vector4& operator[](size_t bufferIndex)
1624   {
1625     return mValue[bufferIndex];
1626   }
1627
1628   /**
1629    * Retrieve the property value.
1630    * @param[in] bufferIndex The buffer to read.
1631    * @return The property value.
1632    */
1633   const Vector4& operator[](size_t bufferIndex) const
1634   {
1635     return mValue[bufferIndex];
1636   }
1637
1638   /**
1639    * Set both the property value & base value.
1640    * @param[in] bufferIndex The buffer to write for the property value.
1641    * @param[in] value The new property value.
1642    */
1643   void Bake(BufferIndex bufferIndex, const Vector4& value)
1644   {
1645     mValue[bufferIndex] = value;
1646     mBaseValue = mValue[bufferIndex];
1647
1648     OnBake();
1649   }
1650
1651   /**
1652    * Set both the X value & base X value.
1653    * @param[in] bufferIndex The buffer to write for the property value.
1654    * @param[in] value The new property value.
1655    */
1656   void BakeX(BufferIndex bufferIndex, float value)
1657   {
1658     mValue[bufferIndex].x = value;
1659     mBaseValue.x = mValue[bufferIndex].x;
1660
1661     OnBake();
1662   }
1663
1664   /**
1665    * Set both the Y value & base Y value.
1666    * @param[in] bufferIndex The buffer to write for the property value.
1667    * @param[in] value The new property value.
1668    */
1669   void BakeY(BufferIndex bufferIndex, float value)
1670   {
1671     mValue[bufferIndex].y = value;
1672     mBaseValue.y = mValue[bufferIndex].y;
1673
1674     OnBake();
1675   }
1676
1677   /**
1678    * Set both the Z value & base Z value.
1679    * @param[in] bufferIndex The buffer to write for the property value.
1680    * @param[in] value The new property value.
1681    */
1682   void BakeZ(BufferIndex bufferIndex, float value)
1683   {
1684     mValue[bufferIndex].z = value;
1685     mBaseValue.z = mValue[bufferIndex].z;
1686
1687     OnBake();
1688   }
1689
1690   /**
1691    * Set both the W value & base W value.
1692    * @param[in] bufferIndex The buffer to write for the property value.
1693    * @param[in] value The new property value.
1694    */
1695   void BakeW(BufferIndex bufferIndex, float value)
1696   {
1697     mValue[bufferIndex].w = value;
1698     mBaseValue.w = mValue[bufferIndex].w;
1699
1700     OnBake();
1701   }
1702
1703   /**
1704    * Change the property value & base value by a relative amount.
1705    * @param[in] bufferIndex The buffer to write for the local property value.
1706    * @param[in] delta The property will change by this amount.
1707    */
1708   void BakeRelative(BufferIndex bufferIndex, const Vector4& delta)
1709   {
1710     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1711     mBaseValue = mValue[bufferIndex];
1712
1713     OnBake();
1714   }
1715
1716   /**
1717    * Change the X value & base X value by a relative amount.
1718    * @param[in] bufferIndex The buffer to write for the local property value.
1719    * @param[in] delta The X value will change by this amount.
1720    */
1721   void BakeXRelative(BufferIndex bufferIndex, float delta)
1722   {
1723     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1724     mBaseValue.x = mValue[bufferIndex].x;
1725
1726     OnBake();
1727   }
1728
1729   /**
1730    * Change the Y value & base Y value by a relative amount.
1731    * @param[in] bufferIndex The buffer to write for the local property value.
1732    * @param[in] delta The Y value will change by this amount.
1733    */
1734   void BakeYRelative(BufferIndex bufferIndex, float delta)
1735   {
1736     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1737     mBaseValue.y = mValue[bufferIndex].y;
1738
1739     OnBake();
1740   }
1741
1742   /**
1743    * Change the Z value & base Z value by a relative amount.
1744    * @param[in] bufferIndex The buffer to write for the local property value.
1745    * @param[in] delta The Z value will change by this amount.
1746    */
1747   void BakeZRelative(BufferIndex bufferIndex, float delta)
1748   {
1749     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1750     mBaseValue.z = mValue[bufferIndex].z;
1751
1752     OnBake();
1753   }
1754
1755   /**
1756    * Change the W value & base W value by a relative amount.
1757    * @param[in] bufferIndex The buffer to write for the local property value.
1758    * @param[in] delta The W value will change by this amount.
1759    */
1760   void BakeWRelative(BufferIndex bufferIndex, float delta)
1761   {
1762     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1763     mBaseValue.w = mValue[bufferIndex].w;
1764
1765     OnBake();
1766   }
1767
1768   /**
1769    * Sets both double-buffered W values & the base W value.
1770    * This should only be used when the owning object has not been connected to the scene-graph.
1771    * @param[in] value The new W value.
1772    */
1773   void SetWInitial(float value)
1774   {
1775     mValue[0].w  = value;
1776     mValue[1].w  = mValue[0].w;
1777     mBaseValue.w = mValue[0].w;
1778   }
1779
1780 private:
1781
1782   // Undefined
1783   AnimatableProperty(const AnimatableProperty& property);
1784
1785   // Undefined
1786   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1787
1788 private:
1789
1790   DoubleBuffered<Vector4> mValue; ///< The double-buffered property value
1791   Vector4 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1792
1793 };
1794 /**
1795  * An Quaternion animatable property of a scene-graph object.
1796  */
1797 template <>
1798 class AnimatableProperty<Quaternion> : public AnimatablePropertyBase
1799 {
1800 public:
1801
1802   /**
1803    * Create an animatable property.
1804    */
1805   AnimatableProperty()
1806   : mValue(),
1807     mBaseValue()
1808   {
1809   }
1810
1811   /**
1812    * Create an animatable property.
1813    * @param [in] initialValue The initial value of the property.
1814    */
1815   AnimatableProperty( const Quaternion& initialValue )
1816   : mValue( initialValue ),
1817     mBaseValue( initialValue )
1818   {
1819   }
1820
1821   /**
1822    * Virtual destructor.
1823    */
1824   virtual ~AnimatableProperty()
1825   {
1826   }
1827
1828   /**
1829    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1830    */
1831   virtual Dali::Property::Type GetType() const
1832   {
1833     return Dali::PropertyTypes::Get<Quaternion>();
1834   }
1835
1836   /**
1837    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1838    */
1839   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1840   {
1841     if (CLEAN_FLAG != mDirtyFlags)
1842     {
1843       mValue[updateBufferIndex] = mBaseValue;
1844
1845       mDirtyFlags = ( mDirtyFlags >> 1 );
1846     }
1847   }
1848
1849   /**
1850    * @copydoc Dali::PropertyInput::GetQuaternion()
1851    */
1852   virtual const Quaternion& GetQuaternion( BufferIndex bufferIndex ) const
1853   {
1854     return mValue[ bufferIndex ];
1855   }
1856
1857   /**
1858    * Set the property value. This will only persist for the current frame; the property
1859    * will be reset with the base value, at the beginning of the next frame.
1860    * @param[in] bufferIndex The buffer to write.
1861    * @param[in] value The new property value.
1862    */
1863   void Set(BufferIndex bufferIndex, const Quaternion& value)
1864   {
1865     mValue[bufferIndex] = value;
1866
1867     OnSet();
1868   }
1869
1870   /**
1871    * Change the property value by a relative amount.
1872    * @param[in] bufferIndex The buffer to write.
1873    * @param[in] delta The property will change by this amount.
1874    */
1875   void SetRelative(BufferIndex bufferIndex, const Quaternion& delta)
1876   {
1877     mValue[bufferIndex] *= delta;
1878
1879     OnSet();
1880   }
1881
1882   /**
1883    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1884    */
1885   Quaternion& Get(size_t bufferIndex)
1886   {
1887     return mValue[bufferIndex];
1888   }
1889
1890   /**
1891    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1892    */
1893   const Quaternion& Get(size_t bufferIndex) const
1894   {
1895     return mValue[bufferIndex];
1896   }
1897
1898   /**
1899    * Retrieve the property value.
1900    * @param[in] bufferIndex The buffer to read.
1901    * @return The property value.
1902    */
1903   Quaternion& operator[](size_t bufferIndex)
1904   {
1905     return mValue[bufferIndex];
1906   }
1907
1908   /**
1909    * Retrieve the property value.
1910    * @param[in] bufferIndex The buffer to read.
1911    * @return The property value.
1912    */
1913   const Quaternion& operator[](size_t bufferIndex) const
1914   {
1915     return mValue[bufferIndex];
1916   }
1917
1918   /**
1919    * Set both the property value & base value.
1920    * @param[in] bufferIndex The buffer to write for the property value.
1921    * @param[in] value The new property value.
1922    */
1923   void Bake(BufferIndex bufferIndex, const Quaternion& value)
1924   {
1925     mValue[bufferIndex] = value;
1926     mBaseValue = value;
1927
1928     OnBake();
1929   }
1930
1931   /**
1932    * Change the property value & base value by a relative amount.
1933    * @param[in] bufferIndex The buffer to write for the local property value.
1934    * @param[in] delta The property will change by this amount.
1935    */
1936   void BakeRelative(BufferIndex bufferIndex, const Quaternion& delta)
1937   {
1938     mValue[bufferIndex] *= delta;
1939     mBaseValue = mValue[bufferIndex];
1940
1941     OnBake();
1942   }
1943
1944 private:
1945
1946   // Undefined
1947   AnimatableProperty(const AnimatableProperty& property);
1948
1949   // Undefined
1950   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1951
1952 private:
1953
1954   DoubleBuffered<Quaternion> mValue; ///< The double-buffered property value
1955   Quaternion mBaseValue;             ///< Reset to this base value at the beginning of each frame
1956
1957 };
1958
1959 /**
1960  * A Matrix animatable property of a scene-graph object.
1961  */
1962 template <>
1963 class AnimatableProperty<Matrix> : public AnimatablePropertyBase
1964 {
1965 public:
1966
1967   /**
1968    * Create an animatable property.
1969    * @param [in] initialValue The initial value of the property.
1970    */
1971   AnimatableProperty( const Matrix& initialValue )
1972   : mValue( initialValue ),
1973     mBaseValue( initialValue )
1974   {
1975   }
1976
1977   /**
1978    * Virtual destructor.
1979    */
1980   virtual ~AnimatableProperty()
1981   {
1982   }
1983
1984   /**
1985    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1986    */
1987   virtual Dali::Property::Type GetType() const
1988   {
1989     return Dali::PropertyTypes::Get<Matrix>();
1990   }
1991
1992   /**
1993    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1994    */
1995   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1996   {
1997     if (CLEAN_FLAG != mDirtyFlags)
1998     {
1999       mValue[updateBufferIndex] = mBaseValue;
2000
2001       mDirtyFlags = ( mDirtyFlags >> 1 );
2002     }
2003   }
2004
2005   /**
2006    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix()
2007    */
2008   virtual const Matrix& GetMatrix( BufferIndex bufferIndex ) const
2009   {
2010     return mValue[ bufferIndex ];
2011   }
2012
2013   /**
2014    * Set the property value. This will only persist for the current frame; the property
2015    * will be reset with the base value, at the beginning of the next frame.
2016    * @param[in] bufferIndex The buffer to write.
2017    * @param[in] value The new property value.
2018    */
2019   void Set(BufferIndex bufferIndex, const Matrix& value)
2020   {
2021     mValue[bufferIndex] = value;
2022     OnSet();
2023   }
2024
2025
2026   /**
2027    * Change the property value by a relative amount.
2028    * @param[in] bufferIndex The buffer to write.
2029    * @param[in] delta The property will change by this amount.
2030    */
2031   void SetRelative(BufferIndex bufferIndex, const Matrix& delta)
2032   {
2033     Matrix temp;
2034     Matrix::Multiply(temp, mValue[bufferIndex], delta);
2035     mValue[bufferIndex] = temp;
2036
2037     OnSet();
2038   }
2039
2040   /**
2041    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
2042    */
2043   Matrix& Get(size_t bufferIndex)
2044   {
2045     return mValue[bufferIndex];
2046   }
2047
2048   /**
2049    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
2050    */
2051   const Matrix& Get(size_t bufferIndex) const
2052   {
2053     return mValue[bufferIndex];
2054   }
2055
2056   /**
2057    * Retrieve the property value.
2058    * @param[in] bufferIndex The buffer to read.
2059    * @return The property value.
2060    */
2061   Matrix& operator[](size_t bufferIndex)
2062   {
2063     return mValue[bufferIndex];
2064   }
2065
2066   /**
2067    * Retrieve the property value.
2068    * @param[in] bufferIndex The buffer to read.
2069    * @return The property value.
2070    */
2071   const Matrix& operator[](size_t bufferIndex) const
2072   {
2073     return mValue[bufferIndex];
2074   }
2075
2076   /**
2077    * Set both the property value & base value.
2078    * @param[in] bufferIndex The buffer to write for the property value.
2079    * @param[in] value The new property value.
2080    */
2081   void Bake(BufferIndex bufferIndex, const Matrix& value)
2082   {
2083     mValue[bufferIndex] = value;
2084     mBaseValue = mValue[bufferIndex];
2085
2086     OnBake();
2087   }
2088
2089   /**
2090    * Change the property value & base value by a relative amount.
2091    * @param[in] bufferIndex The buffer to write for the local property value.
2092    * @param[in] delta The property will change by this amount.
2093    */
2094   void BakeRelative(BufferIndex bufferIndex, const Matrix& delta)
2095   {
2096     Matrix temp;
2097     Matrix::Multiply(temp, mValue[bufferIndex], delta);
2098     mValue[bufferIndex] = temp;
2099     mBaseValue = temp;
2100
2101     OnBake();
2102   }
2103
2104 private:
2105
2106   // Undefined
2107   AnimatableProperty(const AnimatableProperty& property);
2108
2109   // Undefined
2110   AnimatableProperty& operator=(const AnimatableProperty& rhs);
2111
2112 private:
2113
2114   DoubleBuffered<Matrix> mValue; ///< The double-buffered property value
2115   Matrix mBaseValue;             ///< Reset to this base value at the beginning of each frame
2116
2117 };
2118
2119 /**
2120  * A Matrix3 animatable property of a scene-graph object.
2121  */
2122 template <>
2123 class AnimatableProperty<Matrix3> : public AnimatablePropertyBase
2124 {
2125 public:
2126
2127   /**
2128    * Create an animatable property.
2129    * @param [in] initialValue The initial value of the property.
2130    */
2131   AnimatableProperty( const Matrix3& initialValue )
2132   : mValue( initialValue ),
2133     mBaseValue( initialValue )
2134   {
2135   }
2136
2137   /**
2138    * Virtual destructor.
2139    */
2140   virtual ~AnimatableProperty()
2141   {
2142   }
2143
2144   /**
2145    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
2146    */
2147   virtual Dali::Property::Type GetType() const
2148   {
2149     return Dali::PropertyTypes::Get<Matrix3>();
2150   }
2151
2152   /**
2153    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
2154    */
2155   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
2156   {
2157     if (CLEAN_FLAG != mDirtyFlags)
2158     {
2159       mValue[updateBufferIndex] = mBaseValue;
2160
2161       mDirtyFlags = ( mDirtyFlags >> 1 );
2162     }
2163   }
2164
2165   /**
2166    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix3()
2167    */
2168   virtual const Matrix3& GetMatrix3( BufferIndex bufferIndex ) const
2169   {
2170     return mValue[ bufferIndex ];
2171   }
2172
2173   /**
2174    * Set the property value. This will only persist for the current frame; the property
2175    * will be reset with the base value, at the beginning of the next frame.
2176    * @param[in] bufferIndex The buffer to write.
2177    * @param[in] value The new property value.
2178    */
2179   void Set(BufferIndex bufferIndex, const Matrix3& value)
2180   {
2181     mValue[bufferIndex] = value;
2182     OnSet();
2183   }
2184
2185   /**
2186    * Change the property value by a relative amount.
2187    * @param[in] bufferIndex The buffer to write.
2188    * @param[in] delta The property will change by this amount.
2189    */
2190   void SetRelative(BufferIndex bufferIndex, const Matrix3& delta)
2191   {
2192     Matrix3 temp;
2193     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
2194     mValue[bufferIndex] = temp;
2195     OnSet();
2196   }
2197
2198   /**
2199    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
2200    */
2201   Matrix3& Get(size_t bufferIndex)
2202   {
2203     return mValue[bufferIndex];
2204   }
2205
2206   /**
2207    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
2208    */
2209   const Matrix3& Get(size_t bufferIndex) const
2210   {
2211     return mValue[bufferIndex];
2212   }
2213
2214   /**
2215    * Retrieve the property value.
2216    * @param[in] bufferIndex The buffer to read.
2217    * @return The property value.
2218    */
2219   Matrix3& operator[](size_t bufferIndex)
2220   {
2221     return mValue[bufferIndex];
2222   }
2223
2224   /**
2225    * Retrieve the property value.
2226    * @param[in] bufferIndex The buffer to read.
2227    * @return The property value.
2228    */
2229   const Matrix3& operator[](size_t bufferIndex) const
2230   {
2231     return mValue[bufferIndex];
2232   }
2233
2234   /**
2235    * Set both the property value & base value.
2236    * @param[in] bufferIndex The buffer to write for the property value.
2237    * @param[in] value The new property value.
2238    */
2239   void Bake(BufferIndex bufferIndex, const Matrix3& value)
2240   {
2241     mValue[bufferIndex] = value;
2242     mBaseValue = mValue[bufferIndex];
2243
2244     OnBake();
2245   }
2246
2247   /**
2248    * Change the property value & base value by a relative amount.
2249    * @param[in] bufferIndex The buffer to write for the local property value.
2250    * @param[in] delta The property will change by this amount.
2251    */
2252   void BakeRelative(BufferIndex bufferIndex, const Matrix3& delta)
2253   {
2254     Matrix3 temp;
2255     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
2256     mValue[bufferIndex] = temp;
2257     mBaseValue = temp;
2258
2259     OnBake();
2260   }
2261
2262 private:
2263
2264   // Undefined
2265   AnimatableProperty(const AnimatableProperty& property);
2266
2267   // Undefined
2268   AnimatableProperty& operator=(const AnimatableProperty& rhs);
2269
2270 private:
2271
2272   DoubleBuffered<Matrix3> mValue; ///< The double-buffered property value
2273   Matrix3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
2274
2275 };
2276
2277 } // namespace SceneGraph
2278
2279 // Messages for AnimatableProperty<T>
2280
2281 template <class T>
2282 void BakeMessage( EventThreadServices& eventThreadServices,
2283                   const SceneGraph::AnimatableProperty<T>& property,
2284                   typename ParameterType< T >::PassingType newValue )
2285 {
2286   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, T > LocalType;
2287
2288   // Reserve some memory inside the message queue
2289   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2290
2291   // Construct message in the message queue memory; note that delete should not be called on the return value
2292   new (slot) LocalType( &property,
2293                         &SceneGraph::AnimatableProperty<T>::Bake,
2294                         newValue );
2295 }
2296
2297 template <class T>
2298 void BakeRelativeMessage( EventThreadServices& eventThreadServices,
2299                           const SceneGraph::AnimatableProperty<T>& property,
2300                           const T& delta )
2301 {
2302   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, const T& > LocalType;
2303
2304   // Reserve some memory inside the message queue
2305   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2306
2307   // Construct message in the message queue memory; note that delete should not be called on the return value
2308   new (slot) LocalType( &property,
2309                         &SceneGraph::AnimatableProperty<T>::BakeRelative,
2310                          delta );
2311 }
2312
2313 template <class T>
2314 void SetXComponentMessage( EventThreadServices& eventThreadServices,
2315                            const SceneGraph::AnimatableProperty<T>& property,
2316                            typename ParameterType< float >::PassingType newValue )
2317 {
2318   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2319
2320   // Reserve some memory inside the message queue
2321   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2322
2323   // Construct message in the message queue memory; note that delete should not be called on the return value
2324   new (slot) LocalType( &property,
2325                         &SceneGraph::AnimatableProperty<T>::BakeX,
2326                         newValue );
2327 }
2328
2329 template <class T>
2330 void SetYComponentMessage( EventThreadServices& eventThreadServices,
2331                            const SceneGraph::AnimatableProperty<T>& property,
2332                            typename ParameterType< float >::PassingType newValue )
2333 {
2334   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2335
2336   // Reserve some memory inside the message queue
2337   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2338
2339   // Construct message in the message queue memory; note that delete should not be called on the return value
2340   new (slot) LocalType( &property,
2341                         &SceneGraph::AnimatableProperty<T>::BakeY,
2342                         newValue );
2343 }
2344
2345 template <class T>
2346 void SetZComponentMessage( EventThreadServices& eventThreadServices,
2347                            const SceneGraph::AnimatableProperty<T>& property,
2348                            typename ParameterType< float >::PassingType newValue )
2349 {
2350   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2351
2352   // Reserve some memory inside the message queue
2353   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2354
2355   // Construct message in the message queue memory; note that delete should not be called on the return value
2356   new (slot) LocalType( &property,
2357                         &SceneGraph::AnimatableProperty<T>::BakeZ,
2358                         newValue );
2359 }
2360
2361 template <class T>
2362 void SetWComponentMessage( EventThreadServices& eventThreadServices,
2363                            const SceneGraph::AnimatableProperty<T>& property,
2364                            typename ParameterType< float >::PassingType newValue )
2365 {
2366   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2367
2368   // Reserve some memory inside the message queue
2369   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
2370
2371   // Construct message in the message queue memory; note that delete should not be called on the return value
2372   new (slot) LocalType( &property,
2373                         &SceneGraph::AnimatableProperty<T>::BakeW,
2374                         newValue );
2375 }
2376
2377 } // namespace Internal
2378
2379 } // namespace Dali
2380
2381 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__