License conversion from Flora to Apache 2.0
[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 Vector2 animatable property of a scene-graph object.
477  */
478 template <>
479 class AnimatableProperty<Vector2> : 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( const Vector2& 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<Vector2>();
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::PropertyInput::GetVector2()
523    */
524   virtual const Vector2& GetVector2( 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, const Vector2& 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, const Vector2& delta)
548   {
549     mValue[bufferIndex] += delta;
550
551     OnSet();
552   }
553
554   /**
555    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
556    */
557   Vector2& Get(size_t bufferIndex)
558   {
559     return mValue[bufferIndex];
560   }
561
562   /**
563    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
564    */
565   const Vector2& 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   Vector2& 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 Vector2& 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, const Vector2& value)
596   {
597     mValue[bufferIndex] = value;
598     mBaseValue = value;
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, const Vector2& delta)
609   {
610     mValue[bufferIndex] += delta;
611     mBaseValue = mValue[bufferIndex];
612
613     OnBake();
614   }
615
616 private:
617
618   // Undefined
619   AnimatableProperty(const AnimatableProperty& property);
620
621   // Undefined
622   AnimatableProperty& operator=(const AnimatableProperty& rhs);
623
624 private:
625
626   DoubleBuffered<Vector2> mValue; ///< The double-buffered property value
627   Vector2 mBaseValue;             ///< Reset to this base value at the beginning of each frame
628
629 };
630
631 /**
632  * A Vector3 animatable property of a scene-graph object.
633  */
634 template <>
635 class AnimatableProperty<Vector3> : public AnimatablePropertyBase
636 {
637 public:
638
639   /**
640    * Create an animatable property.
641    * @param [in] initialValue The initial value of the property.
642    */
643   AnimatableProperty( const Vector3& initialValue )
644   : mValue( initialValue ),
645     mBaseValue( initialValue )
646   {
647   }
648
649   /**
650    * Virtual destructor.
651    */
652   virtual ~AnimatableProperty()
653   {
654   }
655
656   /**
657    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
658    */
659   virtual Dali::Property::Type GetType() const
660   {
661     return Dali::PropertyTypes::Get<Vector3>();
662   }
663
664   /**
665    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
666    */
667   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
668   {
669     if (CLEAN_FLAG != mDirtyFlags)
670     {
671       mValue[updateBufferIndex] = mBaseValue;
672
673       mDirtyFlags = ( mDirtyFlags >> 1 );
674     }
675   }
676
677   /**
678    * @copydoc Dali::PropertyInput::GetVector3()
679    */
680   virtual const Vector3& GetVector3( BufferIndex bufferIndex ) const
681   {
682     return mValue[ bufferIndex ];
683   }
684
685   /**
686    * Set the property value. This will only persist for the current frame; the property
687    * will be reset with the base value, at the beginning of the next frame.
688    * @param[in] bufferIndex The buffer to write.
689    * @param[in] value The new property value.
690    */
691   void Set(BufferIndex bufferIndex, const Vector3& value)
692   {
693     mValue[bufferIndex] = value;
694
695     OnSet();
696   }
697
698   /**
699    * Set the property value. This will only persist for the current frame; the property
700    * will be reset with the base value, at the beginning of the next frame.
701    * @param[in] bufferIndex The buffer to write.
702    * @param[in] value The new X value.
703    */
704   void SetX(BufferIndex bufferIndex, float value)
705   {
706     mValue[bufferIndex].x = value;
707
708     OnSet();
709   }
710
711   /**
712    * Set the property value. This will only persist for the current frame; the property
713    * will be reset with the base value, at the beginning of the next frame.
714    * @param[in] bufferIndex The buffer to write.
715    * @param[in] value The new Y value.
716    */
717   void SetY(BufferIndex bufferIndex, float value)
718   {
719     mValue[bufferIndex].y = value;
720
721     OnSet();
722   }
723
724   /**
725    * Set the property value. This will only persist for the current frame; the property
726    * will be reset with the base value, at the beginning of the next frame.
727    * @param[in] bufferIndex The buffer to write.
728    * @param[in] value The new Z value.
729    */
730   void SetZ(BufferIndex bufferIndex, float value)
731   {
732     mValue[bufferIndex].z = value;
733
734     OnSet();
735   }
736
737   /**
738    * Change the property value by a relative amount.
739    * @param[in] bufferIndex The buffer to write.
740    * @param[in] delta The property will change by this amount.
741    */
742   void SetRelative(BufferIndex bufferIndex, const Vector3& delta)
743   {
744     mValue[bufferIndex] += delta;
745
746     OnSet();
747   }
748
749   /**
750    * Change the X value by a relative amount.
751    * @param[in] bufferIndex The buffer to write.
752    * @param[in] delta The X value will change by this amount.
753    */
754   void SetXRelative(BufferIndex bufferIndex, float delta)
755   {
756     mValue[bufferIndex].x += delta;
757
758     OnSet();
759   }
760
761   /**
762    * Change the Y value by a relative amount.
763    * @param[in] bufferIndex The buffer to write.
764    * @param[in] delta The Y value will change by this amount.
765    */
766   void SetYRelative(BufferIndex bufferIndex, float delta)
767   {
768     mValue[bufferIndex].y += delta;
769
770     OnSet();
771   }
772
773   /**
774    * Change the Z value by a relative amount.
775    * @param[in] bufferIndex The buffer to write.
776    * @param[in] delta The Z value will change by this amount.
777    */
778   void SetZRelative(BufferIndex bufferIndex, float delta)
779   {
780     mValue[bufferIndex].z += delta;
781
782     OnSet();
783   }
784
785   /**
786    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
787    */
788   Vector3& Get(size_t bufferIndex)
789   {
790     return mValue[bufferIndex];
791   }
792
793   /**
794    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
795    */
796   const Vector3& Get(size_t bufferIndex) const
797   {
798     return mValue[bufferIndex];
799   }
800
801   /**
802    * Retrieve the property value.
803    * @param[in] bufferIndex The buffer to read.
804    * @return The property value.
805    */
806   Vector3& operator[](size_t bufferIndex)
807   {
808     return mValue[bufferIndex];
809   }
810
811   /**
812    * Retrieve the property value.
813    * @param[in] bufferIndex The buffer to read.
814    * @return The property value.
815    */
816   const Vector3& operator[](size_t bufferIndex) const
817   {
818     return mValue[bufferIndex];
819   }
820
821   /**
822    * Set both the property value & base value.
823    * @param[in] bufferIndex The buffer to write for the property value.
824    * @param[in] value The new property value.
825    */
826   void Bake(BufferIndex bufferIndex, const Vector3& value)
827   {
828     mValue[bufferIndex] = value;
829     mBaseValue = value;
830
831     OnBake();
832   }
833
834   /**
835    * Set both the X value & base X value.
836    * @param[in] bufferIndex The buffer to write for the property value.
837    * @param[in] value The new property value.
838    */
839   void BakeX(BufferIndex bufferIndex, float value)
840   {
841     mValue[bufferIndex].x = value;
842     mBaseValue.x = value;
843
844     OnBake();
845   }
846
847   /**
848    * Set both the Y value & base Y value.
849    * @param[in] bufferIndex The buffer to write for the property value.
850    * @param[in] value The new property value.
851    */
852   void BakeY(BufferIndex bufferIndex, float value)
853   {
854     mValue[bufferIndex].y = value;
855     mBaseValue.y = value;
856
857     OnBake();
858   }
859
860   /**
861    * Set both the Z value & base Z value.
862    * @param[in] bufferIndex The buffer to write for the property value.
863    * @param[in] value The new property value.
864    */
865   void BakeZ(BufferIndex bufferIndex, float value)
866   {
867     mValue[bufferIndex].z = value;
868     mBaseValue.z = value;
869
870     OnBake();
871   }
872
873   /**
874    * Change the property value & base value by a relative amount.
875    * @param[in] bufferIndex The buffer to write for the local property value.
876    * @param[in] delta The property will change by this amount.
877    */
878   void BakeRelative(BufferIndex bufferIndex, const Vector3& delta)
879   {
880     mValue[bufferIndex] += delta;
881     mBaseValue = mValue[bufferIndex];
882
883     OnBake();
884   }
885
886   /**
887    * Change the property value & base value by a relative amount.
888    * @param[in] bufferIndex The buffer to write for the local property value.
889    * @param[in] delta The property will change by this amount.
890    */
891   void BakeRelativeMultiply(BufferIndex bufferIndex, const Vector3& delta)
892   {
893     mValue[bufferIndex] *= delta;
894     mBaseValue = mValue[bufferIndex];
895
896     OnBake();
897   }
898
899   /**
900    * Change the X value & base X value by a relative amount.
901    * @param[in] bufferIndex The buffer to write for the local property value.
902    * @param[in] delta The X value will change by this amount.
903    */
904   void BakeXRelative(BufferIndex bufferIndex, float delta)
905   {
906     mValue[bufferIndex].x += delta;
907     mBaseValue.x = mValue[bufferIndex].x;
908
909     OnBake();
910   }
911
912   /**
913    * Change the Y value & base Y value by a relative amount.
914    * @param[in] bufferIndex The buffer to write for the local property value.
915    * @param[in] delta The Y value will change by this amount.
916    */
917   void BakeYRelative(BufferIndex bufferIndex, float delta)
918   {
919     mValue[bufferIndex].y += delta;
920     mBaseValue.y = mValue[bufferIndex].y;
921
922     OnBake();
923   }
924
925   /**
926    * Change the Z value & base Z value by a relative amount.
927    * @param[in] bufferIndex The buffer to write for the local property value.
928    * @param[in] delta The Z value will change by this amount.
929    */
930   void BakeZRelative(BufferIndex bufferIndex, float delta)
931   {
932     mValue[bufferIndex].z += delta;
933     mBaseValue.z = mValue[bufferIndex].z;
934
935     OnBake();
936   }
937
938 private:
939
940   // Undefined
941   AnimatableProperty(const AnimatableProperty& property);
942
943   // Undefined
944   AnimatableProperty& operator=(const AnimatableProperty& rhs);
945
946 private:
947
948   DoubleBuffered<Vector3> mValue; ///< The double-buffered property value
949   Vector3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
950
951 };
952
953 /**
954  * A Vector4 animatable property of a scene-graph object.
955  */
956 template <>
957 class AnimatableProperty<Vector4> : public AnimatablePropertyBase
958 {
959 public:
960
961   /**
962    * Create an animatable property.
963    * @param [in] initialValue The initial value of the property.
964    */
965   AnimatableProperty( const Vector4& initialValue )
966   : mValue( initialValue ),
967     mBaseValue( initialValue )
968   {
969   }
970
971   /**
972    * Virtual destructor.
973    */
974   virtual ~AnimatableProperty()
975   {
976   }
977
978   /**
979    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
980    */
981   virtual Dali::Property::Type GetType() const
982   {
983     return Dali::PropertyTypes::Get<Vector4>();
984   }
985
986   /**
987    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
988    */
989   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
990   {
991     if (CLEAN_FLAG != mDirtyFlags)
992     {
993       mValue[updateBufferIndex] = mBaseValue;
994
995       mDirtyFlags = ( mDirtyFlags >> 1 );
996     }
997   }
998
999   /**
1000    * @copydoc Dali::PropertyInput::GetVector4()
1001    */
1002   virtual const Vector4& GetVector4( BufferIndex bufferIndex ) const
1003   {
1004     return mValue[ bufferIndex ];
1005   }
1006
1007   /**
1008    * Set the property value. This will only persist for the current frame; the property
1009    * will be reset with the base value, at the beginning of the next frame.
1010    * @param[in] bufferIndex The buffer to write.
1011    * @param[in] value The new property value.
1012    */
1013   void Set(BufferIndex bufferIndex, const Vector4& value)
1014   {
1015     mValue[bufferIndex] = value;
1016
1017     OnSet();
1018   }
1019
1020   /**
1021    * Set the X value. This will only persist for the current frame; the property
1022    * will be reset with the base value, at the beginning of the next frame.
1023    * @param[in] bufferIndex The buffer to write.
1024    * @param[in] value The new X value.
1025    */
1026   void SetX(BufferIndex bufferIndex, float value)
1027   {
1028     mValue[bufferIndex].x = value;
1029
1030     OnSet();
1031   }
1032
1033   /**
1034    * Set the Y value. This will only persist for the current frame; the property
1035    * will be reset with the base value, at the beginning of the next frame.
1036    * @param[in] bufferIndex The buffer to write.
1037    * @param[in] value The new Y value.
1038    */
1039   void SetY(BufferIndex bufferIndex, float value)
1040   {
1041     mValue[bufferIndex].y = value;
1042
1043     OnSet();
1044   }
1045
1046   /**
1047    * Set the Z value. This will only persist for the current frame; the property
1048    * will be reset with the base value, at the beginning of the next frame.
1049    * @param[in] bufferIndex The buffer to write.
1050    * @param[in] value The new Z value.
1051    */
1052   void SetZ(BufferIndex bufferIndex, float value)
1053   {
1054     mValue[bufferIndex].z = value;
1055
1056     OnSet();
1057   }
1058
1059   /**
1060    * Set the W value. This will only persist for the current frame; the property
1061    * will be reset with the base value, at the beginning of the next frame.
1062    * @param[in] bufferIndex The buffer to write.
1063    * @param[in] value The new W value.
1064    */
1065   void SetW(BufferIndex bufferIndex, float value)
1066   {
1067     mValue[bufferIndex].w = value;
1068
1069     OnSet();
1070   }
1071
1072   /**
1073    * Change the property value by a relative amount.
1074    * @param[in] bufferIndex The buffer to write.
1075    * @param[in] delta The property will change by this amount.
1076    */
1077   void SetRelative(BufferIndex bufferIndex, const Vector4& delta)
1078   {
1079     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1080
1081     OnSet();
1082   }
1083
1084   /**
1085    * Change the X value by a relative amount.
1086    * @param[in] bufferIndex The buffer to write.
1087    * @param[in] delta The X value will change by this amount.
1088    */
1089   void SetXRelative(BufferIndex bufferIndex, float delta)
1090   {
1091     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1092
1093     OnSet();
1094   }
1095
1096   /**
1097    * Change the Y value by a relative amount.
1098    * @param[in] bufferIndex The buffer to write.
1099    * @param[in] delta The Y value will change by this amount.
1100    */
1101   void SetYRelative(BufferIndex bufferIndex, float delta)
1102   {
1103     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1104
1105     OnSet();
1106   }
1107
1108   /**
1109    * Change the Z value by a relative amount.
1110    * @param[in] bufferIndex The buffer to write.
1111    * @param[in] delta The Z value will change by this amount.
1112    */
1113   void SetZRelative(BufferIndex bufferIndex, float delta)
1114   {
1115     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1116
1117     OnSet();
1118   }
1119
1120   /**
1121    * Change the W value by a relative amount.
1122    * @param[in] bufferIndex The buffer to write.
1123    * @param[in] delta The W value will change by this amount.
1124    */
1125   void SetWRelative(BufferIndex bufferIndex, float delta)
1126   {
1127     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1128
1129     OnSet();
1130   }
1131
1132   /**
1133    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1134    */
1135   Vector4& Get(size_t bufferIndex)
1136   {
1137     return mValue[bufferIndex];
1138   }
1139
1140   /**
1141    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1142    */
1143   const Vector4& Get(size_t bufferIndex) const
1144   {
1145     return mValue[bufferIndex];
1146   }
1147
1148   /**
1149    * Retrieve the property value.
1150    * @param[in] bufferIndex The buffer to read.
1151    * @return The property value.
1152    */
1153   Vector4& operator[](size_t bufferIndex)
1154   {
1155     return mValue[bufferIndex];
1156   }
1157
1158   /**
1159    * Retrieve the property value.
1160    * @param[in] bufferIndex The buffer to read.
1161    * @return The property value.
1162    */
1163   const Vector4& operator[](size_t bufferIndex) const
1164   {
1165     return mValue[bufferIndex];
1166   }
1167
1168   /**
1169    * Set both the property value & base value.
1170    * @param[in] bufferIndex The buffer to write for the property value.
1171    * @param[in] value The new property value.
1172    */
1173   void Bake(BufferIndex bufferIndex, const Vector4& value)
1174   {
1175     mValue[bufferIndex] = value;
1176     mBaseValue = mValue[bufferIndex];
1177
1178     OnBake();
1179   }
1180
1181   /**
1182    * Set both the X value & base X value.
1183    * @param[in] bufferIndex The buffer to write for the property value.
1184    * @param[in] value The new property value.
1185    */
1186   void BakeX(BufferIndex bufferIndex, float value)
1187   {
1188     mValue[bufferIndex].x = value;
1189     mBaseValue.x = mValue[bufferIndex].x;
1190
1191     OnBake();
1192   }
1193
1194   /**
1195    * Set both the Y value & base Y value.
1196    * @param[in] bufferIndex The buffer to write for the property value.
1197    * @param[in] value The new property value.
1198    */
1199   void BakeY(BufferIndex bufferIndex, float value)
1200   {
1201     mValue[bufferIndex].y = value;
1202     mBaseValue.y = mValue[bufferIndex].y;
1203
1204     OnBake();
1205   }
1206
1207   /**
1208    * Set both the Z value & base Z value.
1209    * @param[in] bufferIndex The buffer to write for the property value.
1210    * @param[in] value The new property value.
1211    */
1212   void BakeZ(BufferIndex bufferIndex, float value)
1213   {
1214     mValue[bufferIndex].z = value;
1215     mBaseValue.z = mValue[bufferIndex].z;
1216
1217     OnBake();
1218   }
1219
1220   /**
1221    * Set both the W value & base W value.
1222    * @param[in] bufferIndex The buffer to write for the property value.
1223    * @param[in] value The new property value.
1224    */
1225   void BakeW(BufferIndex bufferIndex, float value)
1226   {
1227     mValue[bufferIndex].w = value;
1228     mBaseValue.w = mValue[bufferIndex].w;
1229
1230     OnBake();
1231   }
1232
1233   /**
1234    * Change the property value & base value by a relative amount.
1235    * @param[in] bufferIndex The buffer to write for the local property value.
1236    * @param[in] delta The property will change by this amount.
1237    */
1238   void BakeRelative(BufferIndex bufferIndex, const Vector4& delta)
1239   {
1240     mValue[bufferIndex] = mValue[bufferIndex] + delta;
1241     mBaseValue = mValue[bufferIndex];
1242
1243     OnBake();
1244   }
1245
1246   /**
1247    * Change the X value & base X value by a relative amount.
1248    * @param[in] bufferIndex The buffer to write for the local property value.
1249    * @param[in] delta The X value will change by this amount.
1250    */
1251   void BakeXRelative(BufferIndex bufferIndex, float delta)
1252   {
1253     mValue[bufferIndex].x = mValue[bufferIndex].x + delta;
1254     mBaseValue.x = mValue[bufferIndex].x;
1255
1256     OnBake();
1257   }
1258
1259   /**
1260    * Change the Y value & base Y value by a relative amount.
1261    * @param[in] bufferIndex The buffer to write for the local property value.
1262    * @param[in] delta The Y value will change by this amount.
1263    */
1264   void BakeYRelative(BufferIndex bufferIndex, float delta)
1265   {
1266     mValue[bufferIndex].y = mValue[bufferIndex].y + delta;
1267     mBaseValue.y = mValue[bufferIndex].y;
1268
1269     OnBake();
1270   }
1271
1272   /**
1273    * Change the Z value & base Z value by a relative amount.
1274    * @param[in] bufferIndex The buffer to write for the local property value.
1275    * @param[in] delta The Z value will change by this amount.
1276    */
1277   void BakeZRelative(BufferIndex bufferIndex, float delta)
1278   {
1279     mValue[bufferIndex].z = mValue[bufferIndex].z + delta;
1280     mBaseValue.z = mValue[bufferIndex].z;
1281
1282     OnBake();
1283   }
1284
1285   /**
1286    * Change the W value & base W value by a relative amount.
1287    * @param[in] bufferIndex The buffer to write for the local property value.
1288    * @param[in] delta The W value will change by this amount.
1289    */
1290   void BakeWRelative(BufferIndex bufferIndex, float delta)
1291   {
1292     mValue[bufferIndex].w = mValue[bufferIndex].w + delta;
1293     mBaseValue.w = mValue[bufferIndex].w;
1294
1295     OnBake();
1296   }
1297
1298   /**
1299    * Sets both double-buffered W values & the base W value.
1300    * This should only be used when the owning object has not been connected to the scene-graph.
1301    * @param[in] value The new W value.
1302    */
1303   void SetWInitial(float value)
1304   {
1305     mValue[0].w  = value;
1306     mValue[1].w  = mValue[0].w;
1307     mBaseValue.w = mValue[0].w;
1308   }
1309
1310 private:
1311
1312   // Undefined
1313   AnimatableProperty(const AnimatableProperty& property);
1314
1315   // Undefined
1316   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1317
1318 private:
1319
1320   DoubleBuffered<Vector4> mValue; ///< The double-buffered property value
1321   Vector4 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1322
1323 };
1324 /**
1325  * An Quaternion animatable property of a scene-graph object.
1326  */
1327 template <>
1328 class AnimatableProperty<Quaternion> : public AnimatablePropertyBase
1329 {
1330 public:
1331
1332   /**
1333    * Create an animatable property.
1334    * @param [in] initialValue The initial value of the property.
1335    */
1336   AnimatableProperty( const Quaternion& initialValue )
1337   : mValue( initialValue ),
1338     mBaseValue( initialValue )
1339   {
1340   }
1341
1342   /**
1343    * Virtual destructor.
1344    */
1345   virtual ~AnimatableProperty()
1346   {
1347   }
1348
1349   /**
1350    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1351    */
1352   virtual Dali::Property::Type GetType() const
1353   {
1354     return Dali::PropertyTypes::Get<Quaternion>();
1355   }
1356
1357   /**
1358    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1359    */
1360   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1361   {
1362     if (CLEAN_FLAG != mDirtyFlags)
1363     {
1364       mValue[updateBufferIndex] = mBaseValue;
1365
1366       mDirtyFlags = ( mDirtyFlags >> 1 );
1367     }
1368   }
1369
1370   /**
1371    * @copydoc Dali::PropertyInput::GetQuaternion()
1372    */
1373   virtual const Quaternion& GetQuaternion( BufferIndex bufferIndex ) const
1374   {
1375     return mValue[ bufferIndex ];
1376   }
1377
1378   /**
1379    * Set the property value. This will only persist for the current frame; the property
1380    * will be reset with the base value, at the beginning of the next frame.
1381    * @param[in] bufferIndex The buffer to write.
1382    * @param[in] value The new property value.
1383    */
1384   void Set(BufferIndex bufferIndex, const Quaternion& value)
1385   {
1386     mValue[bufferIndex] = value;
1387
1388     OnSet();
1389   }
1390
1391   /**
1392    * Change the property value by a relative amount.
1393    * @param[in] bufferIndex The buffer to write.
1394    * @param[in] delta The property will change by this amount.
1395    */
1396   void SetRelative(BufferIndex bufferIndex, const Quaternion& delta)
1397   {
1398     mValue[bufferIndex] *= delta;
1399
1400     OnSet();
1401   }
1402
1403   /**
1404    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1405    */
1406   Quaternion& Get(size_t bufferIndex)
1407   {
1408     return mValue[bufferIndex];
1409   }
1410
1411   /**
1412    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1413    */
1414   const Quaternion& Get(size_t bufferIndex) const
1415   {
1416     return mValue[bufferIndex];
1417   }
1418
1419   /**
1420    * Retrieve the property value.
1421    * @param[in] bufferIndex The buffer to read.
1422    * @return The property value.
1423    */
1424   Quaternion& operator[](size_t bufferIndex)
1425   {
1426     return mValue[bufferIndex];
1427   }
1428
1429   /**
1430    * Retrieve the property value.
1431    * @param[in] bufferIndex The buffer to read.
1432    * @return The property value.
1433    */
1434   const Quaternion& operator[](size_t bufferIndex) const
1435   {
1436     return mValue[bufferIndex];
1437   }
1438
1439   /**
1440    * Set both the property value & base value.
1441    * @param[in] bufferIndex The buffer to write for the property value.
1442    * @param[in] value The new property value.
1443    */
1444   void Bake(BufferIndex bufferIndex, const Quaternion& value)
1445   {
1446     mValue[bufferIndex] = value;
1447     mBaseValue = value;
1448
1449     OnBake();
1450   }
1451
1452   /**
1453    * Change the property value & base value by a relative amount.
1454    * @param[in] bufferIndex The buffer to write for the local property value.
1455    * @param[in] delta The property will change by this amount.
1456    */
1457   void BakeRelative(BufferIndex bufferIndex, const Quaternion& delta)
1458   {
1459     mValue[bufferIndex] *= delta;
1460     mBaseValue = mValue[bufferIndex];
1461
1462     OnBake();
1463   }
1464
1465 private:
1466
1467   // Undefined
1468   AnimatableProperty(const AnimatableProperty& property);
1469
1470   // Undefined
1471   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1472
1473 private:
1474
1475   DoubleBuffered<Quaternion> mValue; ///< The double-buffered property value
1476   Quaternion mBaseValue;             ///< Reset to this base value at the beginning of each frame
1477
1478 };
1479
1480 /**
1481  * A Matrix animatable property of a scene-graph object.
1482  */
1483 template <>
1484 class AnimatableProperty<Matrix> : public AnimatablePropertyBase
1485 {
1486 public:
1487
1488   /**
1489    * Create an animatable property.
1490    * @param [in] initialValue The initial value of the property.
1491    */
1492   AnimatableProperty( const Matrix& initialValue )
1493   : mValue( initialValue ),
1494     mBaseValue( initialValue )
1495   {
1496   }
1497
1498   /**
1499    * Virtual destructor.
1500    */
1501   virtual ~AnimatableProperty()
1502   {
1503   }
1504
1505   /**
1506    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1507    */
1508   virtual Dali::Property::Type GetType() const
1509   {
1510     return Dali::PropertyTypes::Get<Matrix>();
1511   }
1512
1513   /**
1514    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1515    */
1516   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1517   {
1518     if (CLEAN_FLAG != mDirtyFlags)
1519     {
1520       mValue[updateBufferIndex] = mBaseValue;
1521
1522       mDirtyFlags = ( mDirtyFlags >> 1 );
1523     }
1524   }
1525
1526   /**
1527    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix()
1528    */
1529   virtual const Matrix& GetMatrix( BufferIndex bufferIndex ) const
1530   {
1531     return mValue[ bufferIndex ];
1532   }
1533
1534   /**
1535    * Set the property value. This will only persist for the current frame; the property
1536    * will be reset with the base value, at the beginning of the next frame.
1537    * @param[in] bufferIndex The buffer to write.
1538    * @param[in] value The new property value.
1539    */
1540   void Set(BufferIndex bufferIndex, const Matrix& value)
1541   {
1542     mValue[bufferIndex] = value;
1543     OnSet();
1544   }
1545
1546
1547   /**
1548    * Change the property value by a relative amount.
1549    * @param[in] bufferIndex The buffer to write.
1550    * @param[in] delta The property will change by this amount.
1551    */
1552   void SetRelative(BufferIndex bufferIndex, const Matrix& delta)
1553   {
1554     Matrix temp;
1555     Matrix::Multiply(temp, mValue[bufferIndex], delta);
1556     mValue[bufferIndex] = temp;
1557
1558     OnSet();
1559   }
1560
1561   /**
1562    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1563    */
1564   Matrix& Get(size_t bufferIndex)
1565   {
1566     return mValue[bufferIndex];
1567   }
1568
1569   /**
1570    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1571    */
1572   const Matrix& Get(size_t bufferIndex) const
1573   {
1574     return mValue[bufferIndex];
1575   }
1576
1577   /**
1578    * Retrieve the property value.
1579    * @param[in] bufferIndex The buffer to read.
1580    * @return The property value.
1581    */
1582   Matrix& operator[](size_t bufferIndex)
1583   {
1584     return mValue[bufferIndex];
1585   }
1586
1587   /**
1588    * Retrieve the property value.
1589    * @param[in] bufferIndex The buffer to read.
1590    * @return The property value.
1591    */
1592   const Matrix& operator[](size_t bufferIndex) const
1593   {
1594     return mValue[bufferIndex];
1595   }
1596
1597   /**
1598    * Set both the property value & base value.
1599    * @param[in] bufferIndex The buffer to write for the property value.
1600    * @param[in] value The new property value.
1601    */
1602   void Bake(BufferIndex bufferIndex, const Matrix& value)
1603   {
1604     mValue[bufferIndex] = value;
1605     mBaseValue = mValue[bufferIndex];
1606
1607     OnBake();
1608   }
1609
1610   /**
1611    * Change the property value & base value by a relative amount.
1612    * @param[in] bufferIndex The buffer to write for the local property value.
1613    * @param[in] delta The property will change by this amount.
1614    */
1615   void BakeRelative(BufferIndex bufferIndex, const Matrix& delta)
1616   {
1617     Matrix temp;
1618     Matrix::Multiply(temp, mValue[bufferIndex], delta);
1619     mValue[bufferIndex] = temp;
1620     mBaseValue = temp;
1621
1622     OnBake();
1623   }
1624
1625 private:
1626
1627   // Undefined
1628   AnimatableProperty(const AnimatableProperty& property);
1629
1630   // Undefined
1631   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1632
1633 private:
1634
1635   DoubleBuffered<Matrix> mValue; ///< The double-buffered property value
1636   Matrix mBaseValue;             ///< Reset to this base value at the beginning of each frame
1637
1638 };
1639
1640 /**
1641  * A Matrix3 animatable property of a scene-graph object.
1642  */
1643 template <>
1644 class AnimatableProperty<Matrix3> : public AnimatablePropertyBase
1645 {
1646 public:
1647
1648   /**
1649    * Create an animatable property.
1650    * @param [in] initialValue The initial value of the property.
1651    */
1652   AnimatableProperty( const Matrix3& initialValue )
1653   : mValue( initialValue ),
1654     mBaseValue( initialValue )
1655   {
1656   }
1657
1658   /**
1659    * Virtual destructor.
1660    */
1661   virtual ~AnimatableProperty()
1662   {
1663   }
1664
1665   /**
1666    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
1667    */
1668   virtual Dali::Property::Type GetType() const
1669   {
1670     return Dali::PropertyTypes::Get<Matrix3>();
1671   }
1672
1673   /**
1674    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
1675    */
1676   virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
1677   {
1678     if (CLEAN_FLAG != mDirtyFlags)
1679     {
1680       mValue[updateBufferIndex] = mBaseValue;
1681
1682       mDirtyFlags = ( mDirtyFlags >> 1 );
1683     }
1684   }
1685
1686   /**
1687    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix3()
1688    */
1689   virtual const Matrix3& GetMatrix3( BufferIndex bufferIndex ) const
1690   {
1691     return mValue[ bufferIndex ];
1692   }
1693
1694   /**
1695    * Set the property value. This will only persist for the current frame; the property
1696    * will be reset with the base value, at the beginning of the next frame.
1697    * @param[in] bufferIndex The buffer to write.
1698    * @param[in] value The new property value.
1699    */
1700   void Set(BufferIndex bufferIndex, const Matrix3& value)
1701   {
1702     mValue[bufferIndex] = value;
1703     OnSet();
1704   }
1705
1706   /**
1707    * Change the property value by a relative amount.
1708    * @param[in] bufferIndex The buffer to write.
1709    * @param[in] delta The property will change by this amount.
1710    */
1711   void SetRelative(BufferIndex bufferIndex, const Matrix3& delta)
1712   {
1713     Matrix3 temp;
1714     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
1715     mValue[bufferIndex] = temp;
1716     OnSet();
1717   }
1718
1719   /**
1720    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1721    */
1722   Matrix3& Get(size_t bufferIndex)
1723   {
1724     return mValue[bufferIndex];
1725   }
1726
1727   /**
1728    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
1729    */
1730   const Matrix3& Get(size_t bufferIndex) const
1731   {
1732     return mValue[bufferIndex];
1733   }
1734
1735   /**
1736    * Retrieve the property value.
1737    * @param[in] bufferIndex The buffer to read.
1738    * @return The property value.
1739    */
1740   Matrix3& operator[](size_t bufferIndex)
1741   {
1742     return mValue[bufferIndex];
1743   }
1744
1745   /**
1746    * Retrieve the property value.
1747    * @param[in] bufferIndex The buffer to read.
1748    * @return The property value.
1749    */
1750   const Matrix3& operator[](size_t bufferIndex) const
1751   {
1752     return mValue[bufferIndex];
1753   }
1754
1755   /**
1756    * Set both the property value & base value.
1757    * @param[in] bufferIndex The buffer to write for the property value.
1758    * @param[in] value The new property value.
1759    */
1760   void Bake(BufferIndex bufferIndex, const Matrix3& value)
1761   {
1762     mValue[bufferIndex] = value;
1763     mBaseValue = mValue[bufferIndex];
1764
1765     OnBake();
1766   }
1767
1768   /**
1769    * Change the property value & base value by a relative amount.
1770    * @param[in] bufferIndex The buffer to write for the local property value.
1771    * @param[in] delta The property will change by this amount.
1772    */
1773   void BakeRelative(BufferIndex bufferIndex, const Matrix3& delta)
1774   {
1775     Matrix3 temp;
1776     Matrix3::Multiply(temp, mValue[bufferIndex], delta);
1777     mValue[bufferIndex] = temp;
1778     mBaseValue = temp;
1779
1780     OnBake();
1781   }
1782
1783 private:
1784
1785   // Undefined
1786   AnimatableProperty(const AnimatableProperty& property);
1787
1788   // Undefined
1789   AnimatableProperty& operator=(const AnimatableProperty& rhs);
1790
1791 private:
1792
1793   DoubleBuffered<Matrix3> mValue; ///< The double-buffered property value
1794   Matrix3 mBaseValue;             ///< Reset to this base value at the beginning of each frame
1795
1796 };
1797
1798 } // namespace SceneGraph
1799
1800 // Messages for AnimatableProperty<T>
1801
1802 template <class T>
1803 void BakeMessage( EventToUpdate& eventToUpdate,
1804                   const SceneGraph::AnimatableProperty<T>& property,
1805                   typename ParameterType< T >::PassingType newValue )
1806 {
1807   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, T > LocalType;
1808
1809   // Reserve some memory inside the message queue
1810   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1811
1812   // Construct message in the message queue memory; note that delete should not be called on the return value
1813   new (slot) LocalType( &property,
1814                         &SceneGraph::AnimatableProperty<T>::Bake,
1815                         newValue );
1816 }
1817
1818 template <class T>
1819 void BakeRelativeMessage( EventToUpdate& eventToUpdate,
1820                           const SceneGraph::AnimatableProperty<T>& property,
1821                           const T& delta )
1822 {
1823   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, const T& > LocalType;
1824
1825   // Reserve some memory inside the message queue
1826   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1827
1828   // Construct message in the message queue memory; note that delete should not be called on the return value
1829   new (slot) LocalType( &property,
1830                         &SceneGraph::AnimatableProperty<T>::BakeRelative,
1831                          delta );
1832 }
1833
1834 template <class T>
1835 void SetXComponentMessage( EventToUpdate& eventToUpdate,
1836                            const SceneGraph::AnimatableProperty<T>& property,
1837                            typename ParameterType< float >::PassingType newValue )
1838 {
1839   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
1840
1841   // Reserve some memory inside the message queue
1842   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1843
1844   // Construct message in the message queue memory; note that delete should not be called on the return value
1845   new (slot) LocalType( &property,
1846                         &SceneGraph::AnimatableProperty<T>::BakeX,
1847                         newValue );
1848 }
1849
1850 template <class T>
1851 void SetYComponentMessage( EventToUpdate& eventToUpdate,
1852                            const SceneGraph::AnimatableProperty<T>& property,
1853                            typename ParameterType< float >::PassingType newValue )
1854 {
1855   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
1856
1857   // Reserve some memory inside the message queue
1858   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1859
1860   // Construct message in the message queue memory; note that delete should not be called on the return value
1861   new (slot) LocalType( &property,
1862                         &SceneGraph::AnimatableProperty<T>::BakeY,
1863                         newValue );
1864 }
1865
1866 template <class T>
1867 void SetZComponentMessage( EventToUpdate& eventToUpdate,
1868                            const SceneGraph::AnimatableProperty<T>& property,
1869                            typename ParameterType< float >::PassingType newValue )
1870 {
1871   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
1872
1873   // Reserve some memory inside the message queue
1874   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1875
1876   // Construct message in the message queue memory; note that delete should not be called on the return value
1877   new (slot) LocalType( &property,
1878                         &SceneGraph::AnimatableProperty<T>::BakeZ,
1879                         newValue );
1880 }
1881
1882 template <class T>
1883 void SetWComponentMessage( EventToUpdate& eventToUpdate,
1884                            const SceneGraph::AnimatableProperty<T>& property,
1885                            typename ParameterType< float >::PassingType newValue )
1886 {
1887   typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
1888
1889   // Reserve some memory inside the message queue
1890   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
1891
1892   // Construct message in the message queue memory; note that delete should not be called on the return value
1893   new (slot) LocalType( &property,
1894                         &SceneGraph::AnimatableProperty<T>::BakeW,
1895                         newValue );
1896 }
1897
1898 } // namespace Internal
1899
1900 } // namespace Dali
1901
1902 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__