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