License conversion from Flora to Apache 2.0
[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) 2014 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-functions.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 private:
99   Dali::Property::Type mType; // Type of the specialization
100   IntrusivePtr<KeyFrameSpec> mKeyFrames;   // Pointer to the specialized key frame object
101 };
102
103
104 /**
105  * This is the base class for the individual template specializations, allowing a ptr to be
106  * stored in the handle object above. It inherits from RefObject to allow smart pointers
107  * to be used for the specializations. Note that the derived template class below
108  * allows for a copy constructor so that the specialization object can be cloned before
109  * being passed to the scene-graph for animation.
110  */
111 class KeyFrameSpec : public RefObject
112 {
113 public:
114
115   KeyFrameSpec() {}
116
117   virtual unsigned int GetNumberOfKeyFrames() const = 0;
118
119 protected:
120
121   /**
122    * A reference counted object may only be deleted by calling Unreference()
123    */
124   virtual ~KeyFrameSpec() {}
125 };
126
127
128 /**
129  * The base template class for each key frame specialization. It stores a vector of
130  * ProgressValue pairs in mPVs, and uses the existing interface for KeyFrameChannel
131  * to point at this vector.
132  * TODO: Incorporate KeyFrameChannel into this base template
133  */
134 template<typename V>
135 class KeyFrameBaseSpec : public KeyFrameSpec
136 {
137 private:
138   typedef ProgressValue<V> PV;
139   typedef std::vector<PV> PVContainer;
140
141   PVContainer                    mPVs;       // The ProgressValue pairs
142   KeyFrameChannel<V>*            mKeyFrames; // The key frame interpolator
143
144 public:
145   static KeyFrameBaseSpec<V>* New()
146   {
147     return new KeyFrameBaseSpec<V>();
148   }
149
150   static KeyFrameBaseSpec<V>* Clone(const KeyFrameBaseSpec<V>& keyFrames)
151   {
152     return new KeyFrameBaseSpec<V>(keyFrames);
153   }
154
155   /**
156    * Constructor
157    */
158   KeyFrameBaseSpec<V>()
159   {
160     mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
161   }
162
163 protected:
164   /**
165    * Copy Constructor
166    * Allow cloning of this object
167    */
168   KeyFrameBaseSpec<V>(const KeyFrameBaseSpec<V>& keyFrames)
169   : mPVs(keyFrames.mPVs)
170   {
171     mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
172   }
173
174   /**
175    * Destructor. Ensure progress value pairs are cleared down
176    */
177   virtual ~KeyFrameBaseSpec<V>()
178   {
179     delete mKeyFrames;
180     mPVs.clear();
181   }
182
183 public:
184   /**
185    * Add a key frame to the progress value vector. Key frames should be added
186    * in time order (this method does not sort the vector by time)
187    * @param[in] t - progress
188    * @param[in] v - value
189    * @param[in] alpha - Alpha function for blending to the next keyframe
190    */
191   void AddKeyFrame(float t, V v, AlphaFunction alpha)
192   {
193     // TODO:: Support alpha
194     mPVs.push_back(PV(t, v));
195   }
196
197   /**
198    * Get the number of key frames
199    * @return The size of the progress value vector
200    */
201   virtual unsigned int GetNumberOfKeyFrames() const
202   {
203     return mPVs.size();
204   }
205
206   /**
207    * Get a key frame.
208    * @param[in] index The index of the key frame to fetch
209    * @param[out] time The progress of the given key frame
210    * @param[out] value The value of the given key frame
211    */
212   virtual void GetKeyFrame(unsigned int index, float& time, V& value) const
213   {
214     DALI_ASSERT_ALWAYS( index < mPVs.size() && "KeyFrame index is out of bounds" );
215     time  = mPVs[index].mProgress;
216     value = mPVs[index].mValue;
217   }
218
219   /**
220    * Return whether the progress is valid for the range of keyframes. (The first
221    * keyframe doesn't have to start at 0, and the last doesn't have to end at 1.0)
222    * @param[in] progress The progress to test
223    * @return True if the progress is valid for this object
224    */
225   bool IsActive(float progress) const
226   {
227     return mKeyFrames->IsActive(progress);
228   }
229
230   /**
231    * Return an interpolated value for the given progress.
232    * @param[in] progress The progress to test
233    * @return The interpolated value
234    */
235   V GetValue(float progress) const
236   {
237     return mKeyFrames->GetValue(progress);
238   }
239 };
240
241 typedef KeyFrameBaseSpec<float>      KeyFrameNumber;
242 typedef KeyFrameBaseSpec<bool>       KeyFrameBoolean;
243 typedef KeyFrameBaseSpec<Vector2>    KeyFrameVector2;
244 typedef KeyFrameBaseSpec<Vector3>    KeyFrameVector3;
245 typedef KeyFrameBaseSpec<Vector4>    KeyFrameVector4;
246 typedef KeyFrameBaseSpec<Quaternion> KeyFrameQuaternion;
247
248 typedef IntrusivePtr<KeyFrameBoolean>    KeyFrameBooleanPtr;
249 typedef IntrusivePtr<KeyFrameNumber>     KeyFrameNumberPtr;
250 typedef IntrusivePtr<KeyFrameVector2>    KeyFrameVector2Ptr;
251 typedef IntrusivePtr<KeyFrameVector3>    KeyFrameVector3Ptr;
252 typedef IntrusivePtr<KeyFrameVector4>    KeyFrameVector4Ptr;
253 typedef IntrusivePtr<KeyFrameQuaternion> KeyFrameQuaternionPtr;
254
255
256 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameBoolean*& keyFrameSpec)
257 {
258   keyFrameSpec = static_cast<Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
259 }
260
261 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameBoolean*& keyFrameSpec)
262 {
263   keyFrameSpec = static_cast<const Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
264 }
265
266
267 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameNumber*& keyFrameSpec)
268 {
269   keyFrameSpec = static_cast<Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
270 }
271
272 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameNumber*& keyFrameSpec)
273 {
274   keyFrameSpec = static_cast<const Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
275 }
276
277 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector2*& keyFrameSpec)
278 {
279   keyFrameSpec = static_cast<Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
280 }
281
282 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector2*& keyFrameSpec)
283 {
284   keyFrameSpec = static_cast<const Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
285 }
286
287 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector3*& keyFrameSpec)
288 {
289   keyFrameSpec = static_cast<Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
290 }
291
292 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector3*& keyFrameSpec)
293 {
294   keyFrameSpec = static_cast<const Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
295 }
296
297 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector4*& keyFrameSpec)
298 {
299   keyFrameSpec = static_cast<Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
300 }
301
302 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector4*& keyFrameSpec)
303 {
304   keyFrameSpec = static_cast<const Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
305 }
306
307 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameQuaternion*& keyFrameSpec)
308 {
309   keyFrameSpec = static_cast<Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
310 }
311
312 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameQuaternion*& keyFrameSpec)
313 {
314   keyFrameSpec = static_cast<const Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
315 }
316
317 } // Internal
318
319
320 // Get impl of handle
321 inline Internal::KeyFrames& GetImplementation(Dali::KeyFrames& keyFrames)
322 {
323   DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
324   Dali::RefObject& object = keyFrames.GetBaseObject();
325   return static_cast<Internal::KeyFrames&>(object);
326 }
327
328 inline const Internal::KeyFrames& GetImplementation(const Dali::KeyFrames& keyFrames)
329 {
330   DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
331   const Dali::RefObject& object = keyFrames.GetBaseObject();
332   return static_cast<const Internal::KeyFrames&>(object);
333 }
334
335
336 } // Dali
337
338 #endif //__DALI_INTERNAL_KEY_FRAMES_H__