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