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