Merge "use modern construct '= default' for special functions." into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / key-frames-impl.h
1 #ifndef DALI_INTERNAL_KEY_FRAMES_H
2 #define DALI_INTERNAL_KEY_FRAMES_H
3
4 /*
5  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/vector-wrapper.h>
23 #include <dali/public-api/animation/key-frames.h>
24 #include <dali/public-api/object/base-object.h>
25 #include <dali/public-api/animation/alpha-function.h>
26 #include <dali/internal/event/animation/progress-value.h>
27 #include <dali/internal/event/animation/key-frame-channel.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 class KeyFrameSpec;
34 class KeyFrames;
35 using KeyFramesPtr = IntrusivePtr<KeyFrames>;
36
37 /**
38  * KeyFrames class is responsible for creating and building a specialized KeyFrame class
39  * from the Property::Value type used in Add.
40  */
41 class KeyFrames : public BaseObject
42 {
43 public:
44   static KeyFrames* New();
45
46   /**
47    * Instantiate an empty KeyFrames object
48    */
49   KeyFrames();
50
51 protected:
52   ~KeyFrames() override;
53
54 private:
55   /**
56    * Don't allow copy constructor
57    */
58   KeyFrames(const KeyFrames& rhs);
59
60   /**
61    * Don't allow copy operator
62    */
63   KeyFrames& operator=(const KeyFrames& rhs);
64
65   /**
66    * Create a specialization from the given type, and store it to the mSpec
67    * member variable
68    */
69   void CreateKeyFramesSpec(Property::Type type);
70
71 public:
72   /**
73    * Get the type of this key frame.
74    * An empty key frame will return Property::NONE, wheras an initialised
75    * key frame object will return the type of it's first element.
76    * @return the Property::Type of the key frame values
77    */
78   Property::Type GetType() const;
79
80   /**
81    * Add a key frame. The first key frame to be added denotes the type
82    * of all subsequent key frames. If a value with a different type is
83    * added, it will throw a run time assert.
84    * @param[in] time The time (between 0 and 1)
85    * @param[in] value The value of the keyframe at the given time
86    * @param[in] alpha An alpha function to blend between this key frame and the
87    * next key frame.
88    */
89   void Add(float time, Property::Value value, AlphaFunction alpha);
90
91   /**
92    * Return the key frames without specialization. The GetSpecialization methods
93    * below will convert to the specialized objects.
94    */
95   KeyFrameSpec* GetKeyFramesBase() const;
96
97   /**
98    * Return the value of the last key frame.
99    */
100   Dali::Property::Value GetLastKeyFrameValue() const;
101
102 private:
103   Dali::Property::Type mType; // Type of the specialization
104   IntrusivePtr<KeyFrameSpec> mKeyFrames;   // Pointer to the specialized key frame object
105 };
106
107
108 /**
109  * This is the base class for the individual template specializations, allowing a ptr to be
110  * stored in the handle object above. It inherits from RefObject to allow smart pointers
111  * to be used for the specializations. Note that the derived template class below
112  * allows for a copy constructor so that the specialization object can be cloned before
113  * being passed to the scene-graph for animation.
114  */
115 class KeyFrameSpec : public RefObject
116 {
117 public:
118   KeyFrameSpec() = default;
119
120   virtual std::size_t GetNumberOfKeyFrames() const = 0;
121
122   /**
123    * Get the key frame value as a Property::Value.
124    * @param[in] index The index of the key frame to fetch
125    * @param[out] value The value of the given key frame
126    */
127   virtual void GetKeyFrameAsValue( std::size_t index, Property::Value& value ) = 0;
128
129 protected:
130
131   /**
132    * A reference counted object may only be deleted by calling Unreference()
133    */
134   ~KeyFrameSpec() override = default;
135 };
136
137
138 /**
139  * The base template class for each key frame specialization. It stores a vector of
140  * ProgressValue pairs in mPVs, and uses the existing interface for KeyFrameChannel
141  * to point at this vector.
142  */
143 template<typename V>
144 class KeyFrameBaseSpec : public KeyFrameSpec
145 {
146 private:
147   using PV          = ProgressValue<V>;
148   using PVContainer = std::vector<PV>;
149
150   PVContainer                    mPVs;       // The ProgressValue pairs
151   KeyFrameChannel<V>*            mKeyFrames; // The key frame interpolator
152
153 public:
154   static KeyFrameBaseSpec<V>* New()
155   {
156     return new KeyFrameBaseSpec<V>();
157   }
158
159   static KeyFrameBaseSpec<V>* Clone(const KeyFrameBaseSpec<V>& keyFrames)
160   {
161     return new KeyFrameBaseSpec<V>(keyFrames);
162   }
163
164   /**
165    * Constructor
166    */
167   KeyFrameBaseSpec<V>()
168   {
169     mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
170   }
171
172 protected:
173   /**
174    * Copy Constructor
175    * Allow cloning of this object
176    */
177   KeyFrameBaseSpec<V>(const KeyFrameBaseSpec<V>& keyFrames)
178   : mPVs(keyFrames.mPVs)
179   {
180     mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
181   }
182
183   KeyFrameBaseSpec<V>& operator=( const KeyFrameBaseSpec<V>& keyFrames )
184   {
185     if( this != &keyFrames )
186     {
187       mPVs.clear();
188       mPVs = keyFrames.mPVs;
189       delete mKeyFrames;
190       mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
191     }
192     return *this;
193   }
194
195   /**
196    * Destructor. Ensure progress value pairs are cleared down
197    */
198   ~KeyFrameBaseSpec<V>() override
199   {
200     delete mKeyFrames;
201     mPVs.clear();
202   }
203
204 public:
205   /**
206    * Add a key frame to the progress value vector. Key frames should be added
207    * in time order (this method does not sort the vector by time)
208    * @param[in] t - progress
209    * @param[in] v - value
210    * @param[in] alpha - Alpha function for blending to the next keyframe
211    */
212   void AddKeyFrame(float t, V v, AlphaFunction alpha)
213   {
214     mPVs.push_back(PV(t, v));
215   }
216
217   /**
218    * Get the number of key frames
219    * @return The size of the progress value vector
220    */
221   std::size_t GetNumberOfKeyFrames() const override
222   {
223     return mPVs.size();
224   }
225
226   /**
227    * Get a key frame.
228    * @param[in] index The index of the key frame to fetch
229    * @param[out] time The progress of the given key frame
230    * @param[out] value The value of the given key frame
231    */
232   virtual void GetKeyFrame(unsigned int index, float& time, V& value) const
233   {
234     DALI_ASSERT_ALWAYS( index < mPVs.size() && "KeyFrame index is out of bounds" );
235     time  = mPVs[index].mProgress;
236     value = mPVs[index].mValue;
237   }
238
239   /**
240    * @copydoc KeyFrameSpec::GetKeyFrameAsValue()
241    */
242   void GetKeyFrameAsValue( std::size_t index, Property::Value& value ) override
243   {
244     value = mPVs[index].mValue;
245   }
246
247   /**
248    * Return whether the progress is valid for the range of keyframes. (The first
249    * keyframe doesn't have to start at 0, and the last doesn't have to end at 1.0)
250    * @param[in] progress The progress to test
251    * @return True if the progress is valid for this object
252    */
253   bool IsActive(float progress) const
254   {
255     return mKeyFrames->IsActive(progress);
256   }
257
258   /**
259    * Return an interpolated value for the given progress.
260    * @param[in] progress The progress to test
261    * @return The interpolated value
262    */
263   V GetValue(float progress, Dali::Animation::Interpolation interpolation) const
264   {
265     return mKeyFrames->GetValue(progress, interpolation);
266   }
267 };
268
269 using KeyFrameNumber     = KeyFrameBaseSpec<float>;
270 using KeyFrameBoolean    = KeyFrameBaseSpec<bool>;
271 using KeyFrameInteger    = KeyFrameBaseSpec<int>;
272 using KeyFrameVector2    = KeyFrameBaseSpec<Vector2>;
273 using KeyFrameVector3    = KeyFrameBaseSpec<Vector3>;
274 using KeyFrameVector4    = KeyFrameBaseSpec<Vector4>;
275 using KeyFrameQuaternion = KeyFrameBaseSpec<Quaternion>;
276
277 using KeyFrameBooleanPtr    = IntrusivePtr<KeyFrameBoolean>;
278 using KeyFrameNumberPtr     = IntrusivePtr<KeyFrameNumber>;
279 using KeyFrameIntegerPtr    = IntrusivePtr<KeyFrameInteger>;
280 using KeyFrameVector2Ptr    = IntrusivePtr<KeyFrameVector2>;
281 using KeyFrameVector3Ptr    = IntrusivePtr<KeyFrameVector3>;
282 using KeyFrameVector4Ptr    = IntrusivePtr<KeyFrameVector4>;
283 using KeyFrameQuaternionPtr = IntrusivePtr<KeyFrameQuaternion>;
284
285 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameBoolean*& keyFrameSpec)
286 {
287   keyFrameSpec = static_cast<Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
288 }
289
290 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameBoolean*& keyFrameSpec)
291 {
292   keyFrameSpec = static_cast<const Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
293 }
294
295 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameNumber*& keyFrameSpec)
296 {
297   keyFrameSpec = static_cast<Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
298 }
299
300 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameNumber*& keyFrameSpec)
301 {
302   keyFrameSpec = static_cast<const Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
303 }
304
305 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameInteger*& keyFrameSpec)
306 {
307   keyFrameSpec = static_cast<Internal::KeyFrameInteger*>(keyFrames.GetKeyFramesBase());
308 }
309
310 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameInteger*& keyFrameSpec)
311 {
312   keyFrameSpec = static_cast<const Internal::KeyFrameInteger*>(keyFrames.GetKeyFramesBase());
313 }
314
315 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector2*& keyFrameSpec)
316 {
317   keyFrameSpec = static_cast<Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
318 }
319
320 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector2*& keyFrameSpec)
321 {
322   keyFrameSpec = static_cast<const Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
323 }
324
325 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector3*& keyFrameSpec)
326 {
327   keyFrameSpec = static_cast<Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
328 }
329
330 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector3*& keyFrameSpec)
331 {
332   keyFrameSpec = static_cast<const Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
333 }
334
335 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector4*& keyFrameSpec)
336 {
337   keyFrameSpec = static_cast<Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
338 }
339
340 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector4*& keyFrameSpec)
341 {
342   keyFrameSpec = static_cast<const Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
343 }
344
345 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameQuaternion*& keyFrameSpec)
346 {
347   keyFrameSpec = static_cast<Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
348 }
349
350 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameQuaternion*& keyFrameSpec)
351 {
352   keyFrameSpec = static_cast<const Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
353 }
354
355 } // Internal
356
357
358 // Get impl of handle
359 inline Internal::KeyFrames& GetImplementation(Dali::KeyFrames& keyFrames)
360 {
361   DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
362   Dali::RefObject& object = keyFrames.GetBaseObject();
363   return static_cast<Internal::KeyFrames&>(object);
364 }
365
366 inline const Internal::KeyFrames& GetImplementation(const Dali::KeyFrames& keyFrames)
367 {
368   DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
369   const Dali::RefObject& object = keyFrames.GetBaseObject();
370   return static_cast<const Internal::KeyFrames&>(object);
371 }
372
373
374 } // Dali
375
376 #endif // DALI_INTERNAL_KEY_FRAMES_H