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