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