Add KeyFrames APIs
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / key-frames-impl.h
index 768375d..919fedf 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_KEY_FRAMES_H__
-#define __DALI_INTERNAL_KEY_FRAMES_H__
+#ifndef DALI_INTERNAL_KEY_FRAMES_H
+#define DALI_INTERNAL_KEY_FRAMES_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 
+// EXTERNAL INCLUDES
+#include <memory>
+
 // INTERNAL INCLUDES
-#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/internal/event/animation/key-frame-channel.h>
+#include <dali/public-api/animation/alpha-function.h>
 #include <dali/public-api/animation/key-frames.h>
+#include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/base-object.h>
-#include <dali/public-api/animation/alpha-functions.h>
-#include <dali/internal/event/animation/progress-value.h>
-#include <dali/internal/event/animation/key-frame-channel.h>
 
 namespace Dali
 {
@@ -32,8 +34,6 @@ namespace Internal
 {
 class KeyFrameSpec;
 class KeyFrames;
-typedef IntrusivePtr<KeyFrames> KeyFramesPtr;
-
 
 /**
  * KeyFrames class is responsible for creating and building a specialized KeyFrame class
@@ -44,26 +44,8 @@ class KeyFrames : public BaseObject
 public:
   static KeyFrames* New();
 
-  /**
-   * Instantiate an empty KeyFrames object
-   */
-  KeyFrames();
-
-protected:
-  virtual ~KeyFrames();
-
 private:
   /**
-   * Don't allow copy constructor
-   */
-  KeyFrames(const KeyFrames& rhs);
-
-  /**
-   * Don't allow copy operator
-   */
-  KeyFrames& operator=(const KeyFrames& rhs);
-
-  /**
    * Create a specialization from the given type, and store it to the mSpec
    * member variable
    */
@@ -87,7 +69,7 @@ public:
    * @param[in] alpha An alpha function to blend between this key frame and the
    * next key frame.
    */
-  void Add(float time, Property::Value value, AlphaFunction alpha);
+  void Add(float time, const Property::Value& value, AlphaFunction alpha);
 
   /**
    * Return the key frames without specialization. The GetSpecialization methods
@@ -95,94 +77,57 @@ public:
    */
   KeyFrameSpec* GetKeyFramesBase() const;
 
+  /**
+   * Return the value of the last key frame.
+   */
+  Dali::Property::Value GetLastKeyFrameValue() const;
+
+  /**
+   * @copydoc Dali::DevelKeyFrames::GetKeyFrameCount()
+   */
+  std::size_t GetKeyFrameCount() const;
+
+  /**
+   * @copydoc Dali::DevelKeyFrames::GetKeyFrame()
+   */
+  void GetKeyFrame(std::size_t index, float& time, Property::Value& value) const;
+
 private:
-  Dali::Property::Type mType; // Type of the specialization
-  IntrusivePtr<KeyFrameSpec> mKeyFrames;   // Pointer to the specialized key frame object
+  Dali::Property::Type          mType{Property::NONE}; // Type of the specialization
+  std::unique_ptr<KeyFrameSpec> mKeyFrames;            // Pointer to the specialized key frame object
 };
 
-
 /**
  * This is the base class for the individual template specializations, allowing a ptr to be
- * stored in the handle object above. It inherits from RefObject to allow smart pointers
- * to be used for the specializations. Note that the derived template class below
- * allows for a copy constructor so that the specialization object can be cloned before
- * being passed to the scene-graph for animation.
+ * stored in the handle object above.
  */
-class KeyFrameSpec : public RefObject
+class KeyFrameSpec
 {
 public:
+  virtual ~KeyFrameSpec() = default;
 
-  KeyFrameSpec() {}
-
-  virtual unsigned int GetNumberOfKeyFrames() const = 0;
-
-protected:
+  virtual std::size_t GetNumberOfKeyFrames() const = 0;
 
   /**
-   * A reference counted object may only be deleted by calling Unreference()
+   * Get the key frame value as a Property::Value.
+   * @param[in] index The index of the key frame to fetch
+   * @param[out] time The progress of the given key frame
+   * @param[out] value The value of the given key frame
    */
-  virtual ~KeyFrameSpec() {}
+  virtual void GetKeyFrameAsValue(std::size_t index, float& time, Property::Value& value) const = 0;
 };
 
-
 /**
- * The base template class for each key frame specialization. It stores a vector of
- * ProgressValue pairs in mPVs, and uses the existing interface for KeyFrameChannel
- * to point at this vector.
- * TODO: Incorporate KeyFrameChannel into this base template
+ * The base template class for each key frame specialization.
  */
 template<typename V>
 class KeyFrameBaseSpec : public KeyFrameSpec
 {
-private:
-  typedef ProgressValue<V> PV;
-  typedef std::vector<PV> PVContainer;
-
-  PVContainer                    mPVs;       // The ProgressValue pairs
-  KeyFrameChannel<V>*            mKeyFrames; // The key frame interpolator
+  KeyFrameChannel<V> mChannel; // The key frame channel
 
 public:
-  static KeyFrameBaseSpec<V>* New()
-  {
-    return new KeyFrameBaseSpec<V>();
-  }
-
-  static KeyFrameBaseSpec<V>* Clone(const KeyFrameBaseSpec<V>& keyFrames)
-  {
-    return new KeyFrameBaseSpec<V>(keyFrames);
-  }
-
-  /**
-   * Constructor
-   */
-  KeyFrameBaseSpec<V>()
-  {
-    mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
-  }
-
-protected:
-  /**
-   * Copy Constructor
-   * Allow cloning of this object
-   */
-  KeyFrameBaseSpec<V>(const KeyFrameBaseSpec<V>& keyFrames)
-  : mPVs(keyFrames.mPVs)
-  {
-    mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
-  }
-
   /**
-   * Destructor. Ensure progress value pairs are cleared down
-   */
-  virtual ~KeyFrameBaseSpec<V>()
-  {
-    delete mKeyFrames;
-    mPVs.clear();
-  }
-
-public:
-  /**
-   * Add a key frame to the progress value vector. Key frames should be added
+   * Add a key frame to the channel. Key frames should be added
    * in time order (this method does not sort the vector by time)
    * @param[in] t - progress
    * @param[in] v - value
@@ -190,17 +135,16 @@ public:
    */
   void AddKeyFrame(float t, V v, AlphaFunction alpha)
   {
-    // TODO:: Support alpha
-    mPVs.push_back(PV(t, v));
+    mChannel.mValues.push_back({t, v});
   }
 
   /**
    * Get the number of key frames
-   * @return The size of the progress value vector
+   * @return Channel size
    */
-  virtual unsigned int GetNumberOfKeyFrames() const
+  std::size_t GetNumberOfKeyFrames() const override
   {
-    return mPVs.size();
+    return mChannel.mValues.size();
   }
 
   /**
@@ -209,11 +153,22 @@ public:
    * @param[out] time The progress of the given key frame
    * @param[out] value The value of the given key frame
    */
-  virtual void GetKeyFrame(unsigned int index, float& time, V& value) const
+  void GetKeyFrame(unsigned int index, float& time, V& value) const
   {
-    DALI_ASSERT_ALWAYS( index < mPVs.size() && "KeyFrame index is out of bounds" );
-    time  = mPVs[index].mProgress;
-    value = mPVs[index].mValue;
+    DALI_ASSERT_ALWAYS(index < mChannel.mValues.size() && "KeyFrame index is out of bounds");
+    const auto& element = mChannel.mValues[index];
+    time                = element.mProgress;
+    value               = element.mValue;
+  }
+
+  /**
+   * @copydoc KeyFrameSpec::GetKeyFrameAsValue()
+   */
+  void GetKeyFrameAsValue(std::size_t index, float& time, Property::Value& value) const override
+  {
+    const auto& element = mChannel.mValues[index];
+    time                = element.mProgress;
+    value               = element.mValue;
   }
 
   /**
@@ -224,7 +179,7 @@ public:
    */
   bool IsActive(float progress) const
   {
-    return mKeyFrames->IsActive(progress);
+    return mChannel.IsActive(progress);
   }
 
   /**
@@ -232,107 +187,43 @@ public:
    * @param[in] progress The progress to test
    * @return The interpolated value
    */
-  V GetValue(float progress) const
+  V GetValue(float progress, Dali::Animation::Interpolation interpolation) const
   {
-    return mKeyFrames->GetValue(progress);
+    return mChannel.GetValue(progress, interpolation);
   }
 };
 
-typedef KeyFrameBaseSpec<float>      KeyFrameNumber;
-typedef KeyFrameBaseSpec<bool>       KeyFrameBoolean;
-typedef KeyFrameBaseSpec<Vector2>    KeyFrameVector2;
-typedef KeyFrameBaseSpec<Vector3>    KeyFrameVector3;
-typedef KeyFrameBaseSpec<Vector4>    KeyFrameVector4;
-typedef KeyFrameBaseSpec<Quaternion> KeyFrameQuaternion;
-
-typedef IntrusivePtr<KeyFrameBoolean>    KeyFrameBooleanPtr;
-typedef IntrusivePtr<KeyFrameNumber>     KeyFrameNumberPtr;
-typedef IntrusivePtr<KeyFrameVector2>    KeyFrameVector2Ptr;
-typedef IntrusivePtr<KeyFrameVector3>    KeyFrameVector3Ptr;
-typedef IntrusivePtr<KeyFrameVector4>    KeyFrameVector4Ptr;
-typedef IntrusivePtr<KeyFrameQuaternion> KeyFrameQuaternionPtr;
-
+using KeyFrameNumber     = KeyFrameBaseSpec<float>;
+using KeyFrameBoolean    = KeyFrameBaseSpec<bool>;
+using KeyFrameInteger    = KeyFrameBaseSpec<int>;
+using KeyFrameVector2    = KeyFrameBaseSpec<Vector2>;
+using KeyFrameVector3    = KeyFrameBaseSpec<Vector3>;
+using KeyFrameVector4    = KeyFrameBaseSpec<Vector4>;
+using KeyFrameQuaternion = KeyFrameBaseSpec<Quaternion>;
 
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameBoolean*& keyFrameSpec)
+template<typename DeriveClass>
+auto GetSpecialization(const Internal::KeyFrames& keyFrames)
 {
-  keyFrameSpec = static_cast<Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
+  return static_cast<DeriveClass>(keyFrames.GetKeyFramesBase());
 }
 
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameBoolean*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<const Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
-}
-
-
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameNumber*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameNumber*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<const Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector2*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector2*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<const Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector3*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector3*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<const Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector4*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector4*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<const Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameQuaternion*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameQuaternion*& keyFrameSpec)
-{
-  keyFrameSpec = static_cast<const Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
-}
-
-} // Internal
-
+} // namespace Internal
 
 // Get impl of handle
 inline Internal::KeyFrames& GetImplementation(Dali::KeyFrames& keyFrames)
 {
-  DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
+  DALI_ASSERT_ALWAYS(keyFrames && "KeyFrames handle is empty");
   Dali::RefObject& object = keyFrames.GetBaseObject();
   return static_cast<Internal::KeyFrames&>(object);
 }
 
 inline const Internal::KeyFrames& GetImplementation(const Dali::KeyFrames& keyFrames)
 {
-  DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
+  DALI_ASSERT_ALWAYS(keyFrames && "KeyFrames handle is empty");
   const Dali::RefObject& object = keyFrames.GetBaseObject();
   return static_cast<const Internal::KeyFrames&>(object);
 }
 
+} // namespace Dali
 
-} // Dali
-
-#endif //__DALI_INTERNAL_KEY_FRAMES_H__
+#endif // DALI_INTERNAL_KEY_FRAMES_H