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