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