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