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