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