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