Merge "Fixed test case to match new stencil hit rules" into tizen
[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/common/event-to-update.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     // check if the value actually changed to avoid dirtying nodes unnecessarily
258     if( mValue[bufferIndex] != value )
259     {
260       mValue[bufferIndex] = value;
261       mBaseValue = 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  * An float animatable property of a scene-graph object.
297  */
298 template <>
299 class AnimatableProperty<float> : public AnimatablePropertyBase
300 {
301 public:
302
303   /**
304    * Create an animatable property.
305    * @param [in] initialValue The initial value of the property.
306    */
307   AnimatableProperty( float initialValue )
308   : mValue( initialValue ),
309     mBaseValue( initialValue )
310   {
311   }
312
313   /**
314    * Virtual destructor.
315    */
316   virtual ~AnimatableProperty()
317   {
318   }
319
320   /**
321    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
322    */
323   virtual Dali::Property::Type GetType() const
324   {
325     return Dali::PropertyTypes::Get<float>();
326   }
327
328   /**
329    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
330    */
331   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
332   {
333     if (CLEAN_FLAG != mDirtyFlags)
334     {
335       mValue[updateBufferIndex] = mBaseValue;
336
337       mDirtyFlags = ( mDirtyFlags >> 1 );
338     }
339   }
340
341   /**
342    * @copydoc Dali::Internal::PropertyInputImpl::GetFloat()
343    */
344   virtual const float& GetFloat( BufferIndex bufferIndex ) const
345   {
346     return mValue[ bufferIndex ];
347   }
348
349   /**
350    * Set the property value. This will only persist for the current frame; the property
351    * will be reset with the base value, at the beginning of the next frame.
352    * @param[in] bufferIndex The buffer to write.
353    * @param[in] value The new property value.
354    */
355   void Set(BufferIndex bufferIndex, float value)
356   {
357     mValue[bufferIndex] = value;
358
359     OnSet();
360   }
361
362   /**
363    * Change the property value by a relative amount.
364    * @param[in] bufferIndex The buffer to write.
365    * @param[in] delta The property will change by this amount.
366    */
367   void SetRelative(BufferIndex bufferIndex, float delta)
368   {
369     mValue[bufferIndex] = mValue[bufferIndex] + delta;
370
371     OnSet();
372   }
373
374   /**
375    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
376    */
377   float& Get(size_t bufferIndex)
378   {
379     return mValue[bufferIndex];
380   }
381
382   /**
383    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
384    */
385   const float& Get(size_t bufferIndex) const
386   {
387     return mValue[bufferIndex];
388   }
389
390   /**
391    * Retrieve the property value.
392    * @param[in] bufferIndex The buffer to read.
393    * @return The property value.
394    */
395   float& operator[](size_t bufferIndex)
396   {
397     return mValue[bufferIndex];
398   }
399
400   /**
401    * Retrieve the property value.
402    * @param[in] bufferIndex The buffer to read.
403    * @return The property value.
404    */
405   const float& operator[](size_t bufferIndex) const
406   {
407     return mValue[bufferIndex];
408   }
409
410   /**
411    * Set both the property value & base value.
412    * @param[in] bufferIndex The buffer to write for the property value.
413    * @param[in] value The new property value.
414    */
415   void Bake(BufferIndex bufferIndex, float value)
416   {
417     mValue[bufferIndex] = value;
418     mBaseValue = mValue[bufferIndex];
419
420     OnBake();
421   }
422
423   /**
424    * Change the property value & base value by a relative amount.
425    * @param[in] bufferIndex The buffer to write for the local property value.
426    * @param[in] delta The property will change by this amount.
427    */
428   void BakeRelative(BufferIndex bufferIndex, float delta)
429   {
430     mValue[bufferIndex] = mValue[bufferIndex] + delta;
431     mBaseValue = mValue[bufferIndex];
432
433     OnBake();
434   }
435
436   /**
437    * Sets both double-buffered values & the base value.
438    * This should only be used when the owning object has not been connected to the scene-graph.
439    * @param[in] value The new property value.
440    */
441   void SetInitial(const float& value)
442   {
443     mValue[0]  = value;
444     mValue[1]  = mValue[0];
445     mBaseValue = mValue[0];
446   }
447
448   /**
449    * Change both double-buffered values & the base value by a relative amount.
450    * This should only be used when the owning object has not been connected to the scene-graph.
451    * @param[in] delta The property will change by this amount.
452    */
453   void SetInitialRelative(const float& delta)
454   {
455     mValue[0] = mValue[0] + delta;
456     mValue[1] = mValue[0];
457     mBaseValue = mValue[0];
458   }
459
460 private:
461
462   // Undefined
463   AnimatableProperty(const AnimatableProperty& property);
464
465   // Undefined
466   AnimatableProperty& operator=(const AnimatableProperty& rhs);
467
468 private:
469
470   DoubleBuffered<float> mValue; ///< The double-buffered property value
471   float mBaseValue;             ///< Reset to this base value at the beginning of each frame
472
473 };
474
475 /**
476  * An integer animatable property of a scene-graph object.
477  */
478 template <>
479 class AnimatableProperty<int> : public AnimatablePropertyBase
480 {
481 public:
482
483   /**
484    * Create an animatable property.
485    * @param [in] initialValue The initial value of the property.
486    */
487   AnimatableProperty( int initialValue )
488   : mValue( initialValue ),
489     mBaseValue( initialValue )
490   {
491   }
492
493   /**
494    * Virtual destructor.
495    */
496   virtual ~AnimatableProperty()
497   {
498   }
499
500   /**
501    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
502    */
503   virtual Dali::Property::Type GetType() const
504   {
505     return Dali::PropertyTypes::Get<int>();
506   }
507
508   /**
509    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
510    */
511   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
512   {
513     if (CLEAN_FLAG != mDirtyFlags)
514     {
515       mValue[updateBufferIndex] = mBaseValue;
516
517       mDirtyFlags = ( mDirtyFlags >> 1 );
518     }
519   }
520
521   /**
522    * @copydoc Dali::Internal::PropertyInputImpl::GetInteger()
523    */
524   virtual const int& GetInteger( BufferIndex bufferIndex ) const
525   {
526     return mValue[ bufferIndex ];
527   }
528
529   /**
530    * Set the property value. This will only persist for the current frame; the property
531    * will be reset with the base value, at the beginning of the next frame.
532    * @param[in] bufferIndex The buffer to write.
533    * @param[in] value The new property value.
534    */
535   void Set(BufferIndex bufferIndex, int value)
536   {
537     mValue[bufferIndex] = value;
538
539     OnSet();
540   }
541
542   /**
543    * Change the property value by a relative amount.
544    * @param[in] bufferIndex The buffer to write.
545    * @param[in] delta The property will change by this amount.
546    */
547   void SetRelative(BufferIndex bufferIndex, int delta)
548   {
549     mValue[bufferIndex] = mValue[bufferIndex] + delta;
550
551     OnSet();
552   }
553
554   /**
555    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
556    */
557   int& Get(size_t bufferIndex)
558   {
559     return mValue[bufferIndex];
560   }
561
562   /**
563    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
564    */
565   const int& Get(size_t bufferIndex) const
566   {
567     return mValue[bufferIndex];
568   }
569
570   /**
571    * Retrieve the property value.
572    * @param[in] bufferIndex The buffer to read.
573    * @return The property value.
574    */
575   int& operator[](size_t bufferIndex)
576   {
577     return mValue[bufferIndex];
578   }
579
580   /**
581    * Retrieve the property value.
582    * @param[in] bufferIndex The buffer to read.
583    * @return The property value.
584    */
585   const int& operator[](size_t bufferIndex) const
586   {
587     return mValue[bufferIndex];
588   }
589
590   /**
591    * Set both the property value & base value.
592    * @param[in] bufferIndex The buffer to write for the property value.
593    * @param[in] value The new property value.
594    */
595   void Bake(BufferIndex bufferIndex, int value)
596   {
597     mValue[bufferIndex] = value;
598     mBaseValue = mValue[bufferIndex];
599
600     OnBake();
601   }
602
603   /**
604    * Change the property value & base value by a relative amount.
605    * @param[in] bufferIndex The buffer to write for the local property value.
606    * @param[in] delta The property will change by this amount.
607    */
608   void BakeRelative(BufferIndex bufferIndex, int delta)
609   {
610     mValue[bufferIndex] = mValue[bufferIndex] + delta;
611     mBaseValue = mValue[bufferIndex];
612
613     OnBake();
614   }
615
616   /**
617    * Sets both double-buffered values & the base value.
618    * This should only be used when the owning object has not been connected to the scene-graph.
619    * @param[in] value The new property value.
620    */
621   void SetInitial(const int& value)
622   {
623     mValue[0]  = value;
624     mValue[1]  = mValue[0];
625     mBaseValue = mValue[0];
626   }
627
628   /**
629    * Change both double-buffered values & the base value by a relative amount.
630    * This should only be used when the owning object has not been connected to the scene-graph.
631    * @param[in] delta The property will change by this amount.
632    */
633   void SetInitialRelative(const int& delta)
634   {
635     mValue[0] = mValue[0] + delta;
636     mValue[1] = mValue[0];
637     mBaseValue = mValue[0];
638   }
639
640 private:
641
642   // Undefined
643   AnimatableProperty(const AnimatableProperty& property);
644
645   // Undefined
646   AnimatableProperty& operator=(const AnimatableProperty& rhs);
647
648 private:
649
650   DoubleBuffered<int> mValue; ///< The double-buffered property value
651   int mBaseValue;             ///< Reset to this base value at the beginning of each frame
652
653 };
654
655 /**
656  * An Vector2 animatable property of a scene-graph object.
657  */
658 template <>
659 class AnimatableProperty<Vector2> : 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( const Vector2& 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<Vector2>();
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::PropertyInput::GetVector2()
703    */
704   virtual const Vector2& GetVector2( 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, const Vector2& 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, const Vector2& delta)
728   {
729     mValue[bufferIndex] += delta;
730
731     OnSet();
732   }
733
734   /**
735    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
736    */
737   Vector2& Get(size_t bufferIndex)
738   {
739     return mValue[bufferIndex];
740   }
741
742   /**
743    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
744    */
745   const Vector2& 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   Vector2& 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 Vector2& 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, const Vector2& value)
776   {
777     mValue[bufferIndex] = value;
778     mBaseValue = value;
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, const Vector2& delta)
789   {
790     mValue[bufferIndex] += delta;
791     mBaseValue = mValue[bufferIndex];
792
793     OnBake();
794   }
795
796 private:
797
798   // Undefined
799   AnimatableProperty(const AnimatableProperty& property);
800
801   // Undefined
802   AnimatableProperty& operator=(const AnimatableProperty& rhs);
803
804 private:
805
806   DoubleBuffered<Vector2> mValue; ///< The double-buffered property value
807   Vector2 mBaseValue;             ///< Reset to this base value at the beginning of each frame
808
809 };
810
811 /**
812  * A Vector3 animatable property of a scene-graph object.
813  */
814 template <>
815 class AnimatableProperty<Vector3> : public AnimatablePropertyBase
816 {
817 public:
818
819   /**
820    * Create an animatable property.
821    * @param [in] initialValue The initial value of the property.
822    */
823   AnimatableProperty( const Vector3& initialValue )
824   : mValue( initialValue ),
825     mBaseValue( initialValue )
826   {
827   }
828
829   /**
830    * Virtual destructor.
831    */
832   virtual ~AnimatableProperty()
833   {
834   }
835
836   /**
837    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
838    */
839   virtual Dali::Property::Type GetType() const
840   {
841     return Dali::PropertyTypes::Get<Vector3>();
842   }
843
844   /**
845    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
846    */
847   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
848   {
849     if (CLEAN_FLAG != mDirtyFlags)
850     {
851       mValue[updateBufferIndex] = mBaseValue;
852
853       mDirtyFlags = ( mDirtyFlags >> 1 );
854     }
855   }
856
857   /**
858    * @copydoc Dali::PropertyInput::GetVector3()
859    */
860   virtual const Vector3& GetVector3( BufferIndex bufferIndex ) const
861   {
862     return mValue[ bufferIndex ];
863   }
864
865   /**
866    * Set the property value. This will only persist for the current frame; the property
867    * will be reset with the base value, at the beginning of the next frame.
868    * @param[in] bufferIndex The buffer to write.
869    * @param[in] value The new property value.
870    */
871   void Set(BufferIndex bufferIndex, const Vector3& value)
872   {
873     mValue[bufferIndex] = value;
874
875     OnSet();
876   }
877
878   /**
879    * Set the property value. This will only persist for the current frame; the property
880    * will be reset with the base value, at the beginning of the next frame.
881    * @param[in] bufferIndex The buffer to write.
882    * @param[in] value The new X value.
883    */
884   void SetX(BufferIndex bufferIndex, float value)
885   {
886     mValue[bufferIndex].x = value;
887
888     OnSet();
889   }
890
891   /**
892    * Set the property value. This will only persist for the current frame; the property
893    * will be reset with the base value, at the beginning of the next frame.
894    * @param[in] bufferIndex The buffer to write.
895    * @param[in] value The new Y value.
896    */
897   void SetY(BufferIndex bufferIndex, float value)
898   {
899     mValue[bufferIndex].y = value;
900
901     OnSet();
902   }
903
904   /**
905    * Set the property value. This will only persist for the current frame; the property
906    * will be reset with the base value, at the beginning of the next frame.
907    * @param[in] bufferIndex The buffer to write.
908    * @param[in] value The new Z value.
909    */
910   void SetZ(BufferIndex bufferIndex, float value)
911   {
912     mValue[bufferIndex].z = value;
913
914     OnSet();
915   }
916
917   /**
918    * Change the property value by a relative amount.
919    * @param[in] bufferIndex The buffer to write.
920    * @param[in] delta The property will change by this amount.
921    */
922   void SetRelative(BufferIndex bufferIndex, const Vector3& delta)
923   {
924     mValue[bufferIndex] += delta;
925
926     OnSet();
927   }
928
929   /**
930    * Change the X value by a relative amount.
931    * @param[in] bufferIndex The buffer to write.
932    * @param[in] delta The X value will change by this amount.
933    */
934   void SetXRelative(BufferIndex bufferIndex, float delta)
935   {
936     mValue[bufferIndex].x += delta;
937
938     OnSet();
939   }
940
941   /**
942    * Change the Y value by a relative amount.
943    * @param[in] bufferIndex The buffer to write.
944    * @param[in] delta The Y value will change by this amount.
945    */
946   void SetYRelative(BufferIndex bufferIndex, float delta)
947   {
948     mValue[bufferIndex].y += delta;
949
950     OnSet();
951   }
952
953   /**
954    * Change the Z value by a relative amount.
955    * @param[in] bufferIndex The buffer to write.
956    * @param[in] delta The Z value will change by this amount.
957    */
958   void SetZRelative(BufferIndex bufferIndex, float delta)
959   {
960     mValue[bufferIndex].z += delta;
961
962     OnSet();
963   }
964
965   /**
966    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
967    */
968   Vector3& Get(size_t bufferIndex)
969   {
970     return mValue[bufferIndex];
971   }
972
973   /**
974    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
975    */
976   const Vector3& Get(size_t bufferIndex) const
977   {
978     return mValue[bufferIndex];
979   }
980
981   /**
982    * Retrieve the property value.
983    * @param[in] bufferIndex The buffer to read.
984    * @return The property value.
985    */
986   Vector3& operator[](size_t bufferIndex)
987   {
988     return mValue[bufferIndex];
989   }
990
991   /**
992    * Retrieve the property value.
993    * @param[in] bufferIndex The buffer to read.
994    * @return The property value.
995    */
996   const Vector3& operator[](size_t bufferIndex) const
997   {
998     return mValue[bufferIndex];
999   }
1000
1001   /**
1002    * Set both the property value & base value.
1003    * @param[in] bufferIndex The buffer to write for the property value.
1004    * @param[in] value The new property value.
1005    */
1006   void Bake(BufferIndex bufferIndex, const Vector3& value)
1007   {
1008     mValue[bufferIndex] = value;
1009     mBaseValue = value;
1010
1011     OnBake();
1012   }
1013
1014   /**
1015    * Set both the X value & base X value.
1016    * @param[in] bufferIndex The buffer to write for the property value.
1017    * @param[in] value The new property value.
1018    */
1019   void BakeX(BufferIndex bufferIndex, float value)
1020   {
1021     mValue[bufferIndex].x = value;
1022     mBaseValue.x = value;
1023
1024     OnBake();
1025   }
1026
1027   /**
1028    * Set both the Y value & base Y value.
1029    * @param[in] bufferIndex The buffer to write for the property value.
1030    * @param[in] value The new property value.
1031    */
1032   void BakeY(BufferIndex bufferIndex, float value)
1033   {
1034     mValue[bufferIndex].y = value;
1035     mBaseValue.y = value;
1036
1037     OnBake();
1038   }
1039
1040   /**
1041    * Set both the Z value & base Z value.
1042    * @param[in] bufferIndex The buffer to write for the property value.
1043    * @param[in] value The new property value.
1044    */
1045   void BakeZ(BufferIndex bufferIndex, float value)
1046   {
1047     mValue[bufferIndex].z = value;
1048     mBaseValue.z = value;
1049
1050     OnBake();
1051   }
1052
1053   /**
1054    * Change the property value & base value by a relative amount.
1055    * @param[in] bufferIndex The buffer to write for the local property value.
1056    * @param[in] delta The property will change by this amount.
1057    */
1058   void BakeRelative(BufferIndex bufferIndex, const Vector3& delta)
1059   {
1060     mValue[bufferIndex] += delta;
1061     mBaseValue = mValue[bufferIndex];
1062
1063     OnBake();
1064   }
1065
1066   /**
1067    * Change the property value & base value by a relative amount.
1068    * @param[in] bufferIndex The buffer to write for the local property value.
1069    * @param[in] delta The property will change by this amount.
1070    */
1071   void BakeRelativeMultiply(BufferIndex bufferIndex, const Vector3& delta)
1072   {
1073     mValue[bufferIndex] *= delta;
1074     mBaseValue = mValue[bufferIndex];
1075
1076     OnBake();
1077   }
1078
1079   /**
1080    * Change the X value & base X value by a relative amount.
1081    * @param[in] bufferIndex The buffer to write for the local property value.
1082    * @param[in] delta The X value will change by this amount.
1083    */
1084   void BakeXRelative(BufferIndex bufferIndex, float delta)
1085   {
1086     mValue[bufferIndex].x += delta;
1087     mBaseValue.x = mValue[bufferIndex].x;
1088
1089     OnBake();
1090   }
1091
1092   /**
1093    * Change the Y value & base Y value by a relative amount.
1094    * @param[in] bufferIndex The buffer to write for the local property value.
1095    * @param[in] delta The Y value will change by this amount.
1096    */
1097   void BakeYRelative(BufferIndex bufferIndex, float delta)
1098   {
1099     mValue[bufferIndex].y += delta;
1100     mBaseValue.y = mValue[bufferIndex].y;
1101
1102     OnBake();
1103   }
1104
1105   /**
1106    * Change the Z value & base Z value by a relative amount.
1107    * @param[in] bufferIndex The buffer to write for the local property value.
1108    * @param[in] delta The Z value will change by this amount.
1109    */
1110   void BakeZRelative(BufferIndex bufferIndex, float delta)
1111   {
1112     mValue[bufferIndex].z += delta;
1113     mBaseValue.z = mValue[bufferIndex].z;
1114
1115     OnBake();
1116   }
1117
1118 private:
1119
1120   // Undefined
1121   AnimatableProperty(const AnimatableProperty& property);
1122
1123   // Undefined
1124   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1125
1126 private:
1127
1128   DoubleBuffered<Vector3> mValue; ///< The double-buffered property value
1129   Vector3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1130
1131 };
1132
1133 /**
1134  * A Vector4 animatable property of a scene-graph object.
1135  */
1136 template <>
1137 class AnimatableProperty<Vector4> : public AnimatablePropertyBase
1138 {
1139 public:
1140
1141   /**
1142    * Create an animatable property.
1143    * @param [in] initialValue The initial value of the property.
1144    */
1145   AnimatableProperty( const Vector4& initialValue )
1146   : mValue( initialValue ),
1147     mBaseValue( initialValue )
1148   {
1149   }
1150
1151   /**
1152    * Virtual destructor.
1153    */
1154   virtual ~AnimatableProperty()
1155   {
1156   }
1157
1158   /**
1159    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1160    */
1161   virtual Dali::Property::Type GetType() const
1162   {
1163     return Dali::PropertyTypes::Get<Vector4>();
1164   }
1165
1166   /**
1167    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1168    */
1169   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1170   {
1171     if (CLEAN_FLAG != mDirtyFlags)
1172     {
1173       mValue[updateBufferIndex] = mBaseValue;
1174
1175       mDirtyFlags = ( mDirtyFlags >> 1 );
1176     }
1177   }
1178
1179   /**
1180    * @copydoc Dali::PropertyInput::GetVector4()
1181    */
1182   virtual const Vector4& GetVector4( BufferIndex bufferIndex ) const
1183   {
1184     return mValue[ bufferIndex ];
1185   }
1186
1187   /**
1188    * Set the property value. This will only persist for the current frame; the property
1189    * will be reset with the base value, at the beginning of the next frame.
1190    * @param[in] bufferIndex The buffer to write.
1191    * @param[in] value The new property value.
1192    */
1193   void Set(BufferIndex bufferIndex, const Vector4& value)
1194   {
1195     mValue[bufferIndex] = value;
1196
1197     OnSet();
1198   }
1199
1200   /**
1201    * Set the X value. This will only persist for the current frame; the property
1202    * will be reset with the base value, at the beginning of the next frame.
1203    * @param[in] bufferIndex The buffer to write.
1204    * @param[in] value The new X value.
1205    */
1206   void SetX(BufferIndex bufferIndex, float value)
1207   {
1208     mValue[bufferIndex].x = value;
1209
1210     OnSet();
1211   }
1212
1213   /**
1214    * Set the Y value. This will only persist for the current frame; the property
1215    * will be reset with the base value, at the beginning of the next frame.
1216    * @param[in] bufferIndex The buffer to write.
1217    * @param[in] value The new Y value.
1218    */
1219   void SetY(BufferIndex bufferIndex, float value)
1220   {
1221     mValue[bufferIndex].y = value;
1222
1223     OnSet();
1224   }
1225
1226   /**
1227    * Set the Z value. This will only persist for the current frame; the property
1228    * will be reset with the base value, at the beginning of the next frame.
1229    * @param[in] bufferIndex The buffer to write.
1230    * @param[in] value The new Z value.
1231    */
1232   void SetZ(BufferIndex bufferIndex, float value)
1233   {
1234     mValue[bufferIndex].z = value;
1235
1236     OnSet();
1237   }
1238
1239   /**
1240    * Set the W value. This will only persist for the current frame; the property
1241    * will be reset with the base value, at the beginning of the next frame.
1242    * @param[in] bufferIndex The buffer to write.
1243    * @param[in] value The new W value.
1244    */
1245   void SetW(BufferIndex bufferIndex, float value)
1246   {
1247     mValue[bufferIndex].w = value;
1248
1249     OnSet();
1250   }
1251
1252   /**
1253    * Change the property value by a relative amount.
1254    * @param[in] bufferIndex The buffer to write.
1255    * @param[in] delta The property will change by this amount.
1256    */
1257   void SetRelative(BufferIndex bufferIndex, const Vector4& delta)
1258   {
1259     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1260
1261     OnSet();
1262   }
1263
1264   /**
1265    * Change the X value by a relative amount.
1266    * @param[in] bufferIndex The buffer to write.
1267    * @param[in] delta The X value will change by this amount.
1268    */
1269   void SetXRelative(BufferIndex bufferIndex, float delta)
1270   {
1271     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1272
1273     OnSet();
1274   }
1275
1276   /**
1277    * Change the Y value by a relative amount.
1278    * @param[in] bufferIndex The buffer to write.
1279    * @param[in] delta The Y value will change by this amount.
1280    */
1281   void SetYRelative(BufferIndex bufferIndex, float delta)
1282   {
1283     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1284
1285     OnSet();
1286   }
1287
1288   /**
1289    * Change the Z value by a relative amount.
1290    * @param[in] bufferIndex The buffer to write.
1291    * @param[in] delta The Z value will change by this amount.
1292    */
1293   void SetZRelative(BufferIndex bufferIndex, float delta)
1294   {
1295     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1296
1297     OnSet();
1298   }
1299
1300   /**
1301    * Change the W value by a relative amount.
1302    * @param[in] bufferIndex The buffer to write.
1303    * @param[in] delta The W value will change by this amount.
1304    */
1305   void SetWRelative(BufferIndex bufferIndex, float delta)
1306   {
1307     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1308
1309     OnSet();
1310   }
1311
1312   /**
1313    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1314    */
1315   Vector4& Get(size_t bufferIndex)
1316   {
1317     return mValue[bufferIndex];
1318   }
1319
1320   /**
1321    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1322    */
1323   const Vector4& Get(size_t bufferIndex) const
1324   {
1325     return mValue[bufferIndex];
1326   }
1327
1328   /**
1329    * Retrieve the property value.
1330    * @param[in] bufferIndex The buffer to read.
1331    * @return The property value.
1332    */
1333   Vector4& operator[](size_t bufferIndex)
1334   {
1335     return mValue[bufferIndex];
1336   }
1337
1338   /**
1339    * Retrieve the property value.
1340    * @param[in] bufferIndex The buffer to read.
1341    * @return The property value.
1342    */
1343   const Vector4& operator[](size_t bufferIndex) const
1344   {
1345     return mValue[bufferIndex];
1346   }
1347
1348   /**
1349    * Set both the property value & base value.
1350    * @param[in] bufferIndex The buffer to write for the property value.
1351    * @param[in] value The new property value.
1352    */
1353   void Bake(BufferIndex bufferIndex, const Vector4& value)
1354   {
1355     mValue[bufferIndex] = value;
1356     mBaseValue = mValue[bufferIndex];
1357
1358     OnBake();
1359   }
1360
1361   /**
1362    * Set both the X value & base X value.
1363    * @param[in] bufferIndex The buffer to write for the property value.
1364    * @param[in] value The new property value.
1365    */
1366   void BakeX(BufferIndex bufferIndex, float value)
1367   {
1368     mValue[bufferIndex].x = value;
1369     mBaseValue.x = mValue[bufferIndex].x;
1370
1371     OnBake();
1372   }
1373
1374   /**
1375    * Set both the Y value & base Y value.
1376    * @param[in] bufferIndex The buffer to write for the property value.
1377    * @param[in] value The new property value.
1378    */
1379   void BakeY(BufferIndex bufferIndex, float value)
1380   {
1381     mValue[bufferIndex].y = value;
1382     mBaseValue.y = mValue[bufferIndex].y;
1383
1384     OnBake();
1385   }
1386
1387   /**
1388    * Set both the Z value & base Z value.
1389    * @param[in] bufferIndex The buffer to write for the property value.
1390    * @param[in] value The new property value.
1391    */
1392   void BakeZ(BufferIndex bufferIndex, float value)
1393   {
1394     mValue[bufferIndex].z = value;
1395     mBaseValue.z = mValue[bufferIndex].z;
1396
1397     OnBake();
1398   }
1399
1400   /**
1401    * Set both the W value & base W value.
1402    * @param[in] bufferIndex The buffer to write for the property value.
1403    * @param[in] value The new property value.
1404    */
1405   void BakeW(BufferIndex bufferIndex, float value)
1406   {
1407     mValue[bufferIndex].w = value;
1408     mBaseValue.w = mValue[bufferIndex].w;
1409
1410     OnBake();
1411   }
1412
1413   /**
1414    * Change the property value & base value by a relative amount.
1415    * @param[in] bufferIndex The buffer to write for the local property value.
1416    * @param[in] delta The property will change by this amount.
1417    */
1418   void BakeRelative(BufferIndex bufferIndex, const Vector4& delta)
1419   {
1420     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1421     mBaseValue = mValue[bufferIndex];
1422
1423     OnBake();
1424   }
1425
1426   /**
1427    * Change the X value & base X value by a relative amount.
1428    * @param[in] bufferIndex The buffer to write for the local property value.
1429    * @param[in] delta The X value will change by this amount.
1430    */
1431   void BakeXRelative(BufferIndex bufferIndex, float delta)
1432   {
1433     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1434     mBaseValue.x = mValue[bufferIndex].x;
1435
1436     OnBake();
1437   }
1438
1439   /**
1440    * Change the Y value & base Y value by a relative amount.
1441    * @param[in] bufferIndex The buffer to write for the local property value.
1442    * @param[in] delta The Y value will change by this amount.
1443    */
1444   void BakeYRelative(BufferIndex bufferIndex, float delta)
1445   {
1446     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1447     mBaseValue.y = mValue[bufferIndex].y;
1448
1449     OnBake();
1450   }
1451
1452   /**
1453    * Change the Z value & base Z value by a relative amount.
1454    * @param[in] bufferIndex The buffer to write for the local property value.
1455    * @param[in] delta The Z value will change by this amount.
1456    */
1457   void BakeZRelative(BufferIndex bufferIndex, float delta)
1458   {
1459     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1460     mBaseValue.z = mValue[bufferIndex].z;
1461
1462     OnBake();
1463   }
1464
1465   /**
1466    * Change the W value & base W value by a relative amount.
1467    * @param[in] bufferIndex The buffer to write for the local property value.
1468    * @param[in] delta The W value will change by this amount.
1469    */
1470   void BakeWRelative(BufferIndex bufferIndex, float delta)
1471   {
1472     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1473     mBaseValue.w = mValue[bufferIndex].w;
1474
1475     OnBake();
1476   }
1477
1478   /**
1479    * Sets both double-buffered W values & the base W value.
1480    * This should only be used when the owning object has not been connected to the scene-graph.
1481    * @param[in] value The new W value.
1482    */
1483   void SetWInitial(float value)
1484   {
1485     mValue[0].w  = value;
1486     mValue[1].w  = mValue[0].w;
1487     mBaseValue.w = mValue[0].w;
1488   }
1489
1490 private:
1491
1492   // Undefined
1493   AnimatableProperty(const AnimatableProperty& property);
1494
1495   // Undefined
1496   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1497
1498 private:
1499
1500   DoubleBuffered<Vector4> mValue; ///< The double-buffered property value
1501   Vector4 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1502
1503 };
1504 /**
1505  * An Quaternion animatable property of a scene-graph object.
1506  */
1507 template <>
1508 class AnimatableProperty<Quaternion> : public AnimatablePropertyBase
1509 {
1510 public:
1511
1512   /**
1513    * Create an animatable property.
1514    * @param [in] initialValue The initial value of the property.
1515    */
1516   AnimatableProperty( const Quaternion& initialValue )
1517   : mValue( initialValue ),
1518     mBaseValue( initialValue )
1519   {
1520   }
1521
1522   /**
1523    * Virtual destructor.
1524    */
1525   virtual ~AnimatableProperty()
1526   {
1527   }
1528
1529   /**
1530    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1531    */
1532   virtual Dali::Property::Type GetType() const
1533   {
1534     return Dali::PropertyTypes::Get<Quaternion>();
1535   }
1536
1537   /**
1538    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1539    */
1540   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1541   {
1542     if (CLEAN_FLAG != mDirtyFlags)
1543     {
1544       mValue[updateBufferIndex] = mBaseValue;
1545
1546       mDirtyFlags = ( mDirtyFlags >> 1 );
1547     }
1548   }
1549
1550   /**
1551    * @copydoc Dali::PropertyInput::GetQuaternion()
1552    */
1553   virtual const Quaternion& GetQuaternion( BufferIndex bufferIndex ) const
1554   {
1555     return mValue[ bufferIndex ];
1556   }
1557
1558   /**
1559    * Set the property value. This will only persist for the current frame; the property
1560    * will be reset with the base value, at the beginning of the next frame.
1561    * @param[in] bufferIndex The buffer to write.
1562    * @param[in] value The new property value.
1563    */
1564   void Set(BufferIndex bufferIndex, const Quaternion& value)
1565   {
1566     mValue[bufferIndex] = value;
1567
1568     OnSet();
1569   }
1570
1571   /**
1572    * Change the property value by a relative amount.
1573    * @param[in] bufferIndex The buffer to write.
1574    * @param[in] delta The property will change by this amount.
1575    */
1576   void SetRelative(BufferIndex bufferIndex, const Quaternion& delta)
1577   {
1578     mValue[bufferIndex] *= delta;
1579
1580     OnSet();
1581   }
1582
1583   /**
1584    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1585    */
1586   Quaternion& Get(size_t bufferIndex)
1587   {
1588     return mValue[bufferIndex];
1589   }
1590
1591   /**
1592    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1593    */
1594   const Quaternion& Get(size_t bufferIndex) const
1595   {
1596     return mValue[bufferIndex];
1597   }
1598
1599   /**
1600    * Retrieve the property value.
1601    * @param[in] bufferIndex The buffer to read.
1602    * @return The property value.
1603    */
1604   Quaternion& operator[](size_t bufferIndex)
1605   {
1606     return mValue[bufferIndex];
1607   }
1608
1609   /**
1610    * Retrieve the property value.
1611    * @param[in] bufferIndex The buffer to read.
1612    * @return The property value.
1613    */
1614   const Quaternion& operator[](size_t bufferIndex) const
1615   {
1616     return mValue[bufferIndex];
1617   }
1618
1619   /**
1620    * Set both the property value & base value.
1621    * @param[in] bufferIndex The buffer to write for the property value.
1622    * @param[in] value The new property value.
1623    */
1624   void Bake(BufferIndex bufferIndex, const Quaternion& value)
1625   {
1626     mValue[bufferIndex] = value;
1627     mBaseValue = value;
1628
1629     OnBake();
1630   }
1631
1632   /**
1633    * Change the property value & base value by a relative amount.
1634    * @param[in] bufferIndex The buffer to write for the local property value.
1635    * @param[in] delta The property will change by this amount.
1636    */
1637   void BakeRelative(BufferIndex bufferIndex, const Quaternion& delta)
1638   {
1639     mValue[bufferIndex] *= delta;
1640     mBaseValue = mValue[bufferIndex];
1641
1642     OnBake();
1643   }
1644
1645 private:
1646
1647   // Undefined
1648   AnimatableProperty(const AnimatableProperty& property);
1649
1650   // Undefined
1651   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1652
1653 private:
1654
1655   DoubleBuffered<Quaternion> mValue; ///< The double-buffered property value
1656   Quaternion mBaseValue;             ///< Reset to this base value at the beginning of each frame
1657
1658 };
1659
1660 /**
1661  * A Matrix animatable property of a scene-graph object.
1662  */
1663 template <>
1664 class AnimatableProperty<Matrix> : public AnimatablePropertyBase
1665 {
1666 public:
1667
1668   /**
1669    * Create an animatable property.
1670    * @param [in] initialValue The initial value of the property.
1671    */
1672   AnimatableProperty( const Matrix& initialValue )
1673   : mValue( initialValue ),
1674     mBaseValue( initialValue )
1675   {
1676   }
1677
1678   /**
1679    * Virtual destructor.
1680    */
1681   virtual ~AnimatableProperty()
1682   {
1683   }
1684
1685   /**
1686    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1687    */
1688   virtual Dali::Property::Type GetType() const
1689   {
1690     return Dali::PropertyTypes::Get<Matrix>();
1691   }
1692
1693   /**
1694    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1695    */
1696   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1697   {
1698     if (CLEAN_FLAG != mDirtyFlags)
1699     {
1700       mValue[updateBufferIndex] = mBaseValue;
1701
1702       mDirtyFlags = ( mDirtyFlags >> 1 );
1703     }
1704   }
1705
1706   /**
1707    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix()
1708    */
1709   virtual const Matrix& GetMatrix( BufferIndex bufferIndex ) const
1710   {
1711     return mValue[ bufferIndex ];
1712   }
1713
1714   /**
1715    * Set the property value. This will only persist for the current frame; the property
1716    * will be reset with the base value, at the beginning of the next frame.
1717    * @param[in] bufferIndex The buffer to write.
1718    * @param[in] value The new property value.
1719    */
1720   void Set(BufferIndex bufferIndex, const Matrix& value)
1721   {
1722     mValue[bufferIndex] = value;
1723     OnSet();
1724   }
1725
1726
1727   /**
1728    * Change the property value by a relative amount.
1729    * @param[in] bufferIndex The buffer to write.
1730    * @param[in] delta The property will change by this amount.
1731    */
1732   void SetRelative(BufferIndex bufferIndex, const Matrix& delta)
1733   {
1734     Matrix temp;
1735     Matrix::Multiply(temp, mValue[bufferIndex], delta);
1736     mValue[bufferIndex] = temp;
1737
1738     OnSet();
1739   }
1740
1741   /**
1742    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1743    */
1744   Matrix& Get(size_t bufferIndex)
1745   {
1746     return mValue[bufferIndex];
1747   }
1748
1749   /**
1750    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1751    */
1752   const Matrix& Get(size_t bufferIndex) const
1753   {
1754     return mValue[bufferIndex];
1755   }
1756
1757   /**
1758    * Retrieve the property value.
1759    * @param[in] bufferIndex The buffer to read.
1760    * @return The property value.
1761    */
1762   Matrix& operator[](size_t bufferIndex)
1763   {
1764     return mValue[bufferIndex];
1765   }
1766
1767   /**
1768    * Retrieve the property value.
1769    * @param[in] bufferIndex The buffer to read.
1770    * @return The property value.
1771    */
1772   const Matrix& operator[](size_t bufferIndex) const
1773   {
1774     return mValue[bufferIndex];
1775   }
1776
1777   /**
1778    * Set both the property value & base value.
1779    * @param[in] bufferIndex The buffer to write for the property value.
1780    * @param[in] value The new property value.
1781    */
1782   void Bake(BufferIndex bufferIndex, const Matrix& value)
1783   {
1784     mValue[bufferIndex] = value;
1785     mBaseValue = mValue[bufferIndex];
1786
1787     OnBake();
1788   }
1789
1790   /**
1791    * Change the property value & base value by a relative amount.
1792    * @param[in] bufferIndex The buffer to write for the local property value.
1793    * @param[in] delta The property will change by this amount.
1794    */
1795   void BakeRelative(BufferIndex bufferIndex, const Matrix& delta)
1796   {
1797     Matrix temp;
1798     Matrix::Multiply(temp, mValue[bufferIndex], delta);
1799     mValue[bufferIndex] = temp;
1800     mBaseValue = temp;
1801
1802     OnBake();
1803   }
1804
1805 private:
1806
1807   // Undefined
1808   AnimatableProperty(const AnimatableProperty& property);
1809
1810   // Undefined
1811   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1812
1813 private:
1814
1815   DoubleBuffered<Matrix> mValue; ///< The double-buffered property value
1816   Matrix mBaseValue;             ///< Reset to this base value at the beginning of each frame
1817
1818 };
1819
1820 /**
1821  * A Matrix3 animatable property of a scene-graph object.
1822  */
1823 template <>
1824 class AnimatableProperty<Matrix3> : public AnimatablePropertyBase
1825 {
1826 public:
1827
1828   /**
1829    * Create an animatable property.
1830    * @param [in] initialValue The initial value of the property.
1831    */
1832   AnimatableProperty( const Matrix3& initialValue )
1833   : mValue( initialValue ),
1834     mBaseValue( initialValue )
1835   {
1836   }
1837
1838   /**
1839    * Virtual destructor.
1840    */
1841   virtual ~AnimatableProperty()
1842   {
1843   }
1844
1845   /**
1846    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1847    */
1848   virtual Dali::Property::Type GetType() const
1849   {
1850     return Dali::PropertyTypes::Get<Matrix3>();
1851   }
1852
1853   /**
1854    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1855    */
1856   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1857   {
1858     if (CLEAN_FLAG != mDirtyFlags)
1859     {
1860       mValue[updateBufferIndex] = mBaseValue;
1861
1862       mDirtyFlags = ( mDirtyFlags >> 1 );
1863     }
1864   }
1865
1866   /**
1867    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix3()
1868    */
1869   virtual const Matrix3& GetMatrix3( BufferIndex bufferIndex ) const
1870   {
1871     return mValue[ bufferIndex ];
1872   }
1873
1874   /**
1875    * Set the property value. This will only persist for the current frame; the property
1876    * will be reset with the base value, at the beginning of the next frame.
1877    * @param[in] bufferIndex The buffer to write.
1878    * @param[in] value The new property value.
1879    */
1880   void Set(BufferIndex bufferIndex, const Matrix3& value)
1881   {
1882     mValue[bufferIndex] = value;
1883     OnSet();
1884   }
1885
1886   /**
1887    * Change the property value by a relative amount.
1888    * @param[in] bufferIndex The buffer to write.
1889    * @param[in] delta The property will change by this amount.
1890    */
1891   void SetRelative(BufferIndex bufferIndex, const Matrix3& delta)
1892   {
1893     Matrix3 temp;
1894     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
1895     mValue[bufferIndex] = temp;
1896     OnSet();
1897   }
1898
1899   /**
1900    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1901    */
1902   Matrix3& Get(size_t bufferIndex)
1903   {
1904     return mValue[bufferIndex];
1905   }
1906
1907   /**
1908    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1909    */
1910   const Matrix3& Get(size_t bufferIndex) const
1911   {
1912     return mValue[bufferIndex];
1913   }
1914
1915   /**
1916    * Retrieve the property value.
1917    * @param[in] bufferIndex The buffer to read.
1918    * @return The property value.
1919    */
1920   Matrix3& operator[](size_t bufferIndex)
1921   {
1922     return mValue[bufferIndex];
1923   }
1924
1925   /**
1926    * Retrieve the property value.
1927    * @param[in] bufferIndex The buffer to read.
1928    * @return The property value.
1929    */
1930   const Matrix3& operator[](size_t bufferIndex) const
1931   {
1932     return mValue[bufferIndex];
1933   }
1934
1935   /**
1936    * Set both the property value & base value.
1937    * @param[in] bufferIndex The buffer to write for the property value.
1938    * @param[in] value The new property value.
1939    */
1940   void Bake(BufferIndex bufferIndex, const Matrix3& value)
1941   {
1942     mValue[bufferIndex] = value;
1943     mBaseValue = mValue[bufferIndex];
1944
1945     OnBake();
1946   }
1947
1948   /**
1949    * Change the property value & base value by a relative amount.
1950    * @param[in] bufferIndex The buffer to write for the local property value.
1951    * @param[in] delta The property will change by this amount.
1952    */
1953   void BakeRelative(BufferIndex bufferIndex, const Matrix3& delta)
1954   {
1955     Matrix3 temp;
1956     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
1957     mValue[bufferIndex] = temp;
1958     mBaseValue = temp;
1959
1960     OnBake();
1961   }
1962
1963 private:
1964
1965   // Undefined
1966   AnimatableProperty(const AnimatableProperty& property);
1967
1968   // Undefined
1969   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1970
1971 private:
1972
1973   DoubleBuffered<Matrix3> mValue; ///< The double-buffered property value
1974   Matrix3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1975
1976 };
1977
1978 } // namespace SceneGraph
1979
1980 // Messages for AnimatableProperty<T>
1981
1982 template <class T>
1983 void BakeMessage( EventToUpdate& eventToUpdate,
1984                   const SceneGraph::AnimatableProperty<T>& property,
1985                   typename ParameterType< T >::PassingType newValue )
1986 {
1987   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, T > LocalType;
1988
1989   // Reserve some memory inside the message queue
1990   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1991
1992   // Construct message in the message queue memory; note that delete should not be called on the return value
1993   new (slot) LocalType( &property,
1994                         &SceneGraph::AnimatableProperty<T>::Bake,
1995                         newValue );
1996 }
1997
1998 template <class T>
1999 void BakeRelativeMessage( EventToUpdate& eventToUpdate,
2000                           const SceneGraph::AnimatableProperty<T>& property,
2001                           const T& delta )
2002 {
2003   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, const T& > LocalType;
2004
2005   // Reserve some memory inside the message queue
2006   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
2007
2008   // Construct message in the message queue memory; note that delete should not be called on the return value
2009   new (slot) LocalType( &property,
2010                         &SceneGraph::AnimatableProperty<T>::BakeRelative,
2011                          delta );
2012 }
2013
2014 template <class T>
2015 void SetXComponentMessage( EventToUpdate& eventToUpdate,
2016                            const SceneGraph::AnimatableProperty<T>& property,
2017                            typename ParameterType< float >::PassingType newValue )
2018 {
2019   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2020
2021   // Reserve some memory inside the message queue
2022   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
2023
2024   // Construct message in the message queue memory; note that delete should not be called on the return value
2025   new (slot) LocalType( &property,
2026                         &SceneGraph::AnimatableProperty<T>::BakeX,
2027                         newValue );
2028 }
2029
2030 template <class T>
2031 void SetYComponentMessage( EventToUpdate& eventToUpdate,
2032                            const SceneGraph::AnimatableProperty<T>& property,
2033                            typename ParameterType< float >::PassingType newValue )
2034 {
2035   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2036
2037   // Reserve some memory inside the message queue
2038   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
2039
2040   // Construct message in the message queue memory; note that delete should not be called on the return value
2041   new (slot) LocalType( &property,
2042                         &SceneGraph::AnimatableProperty<T>::BakeY,
2043                         newValue );
2044 }
2045
2046 template <class T>
2047 void SetZComponentMessage( EventToUpdate& eventToUpdate,
2048                            const SceneGraph::AnimatableProperty<T>& property,
2049                            typename ParameterType< float >::PassingType newValue )
2050 {
2051   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2052
2053   // Reserve some memory inside the message queue
2054   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
2055
2056   // Construct message in the message queue memory; note that delete should not be called on the return value
2057   new (slot) LocalType( &property,
2058                         &SceneGraph::AnimatableProperty<T>::BakeZ,
2059                         newValue );
2060 }
2061
2062 template <class T>
2063 void SetWComponentMessage( EventToUpdate& eventToUpdate,
2064                            const SceneGraph::AnimatableProperty<T>& property,
2065                            typename ParameterType< float >::PassingType newValue )
2066 {
2067   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
2068
2069   // Reserve some memory inside the message queue
2070   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
2071
2072   // Construct message in the message queue memory; note that delete should not be called on the return value
2073   new (slot) LocalType( &property,
2074                         &SceneGraph::AnimatableProperty<T>::BakeW,
2075                         newValue );
2076 }
2077
2078 } // namespace Internal
2079
2080 } // namespace Dali
2081
2082 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__