-#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-function.h>
-#include <dali/internal/event/animation/progress-value.h>
-#include <dali/internal/event/animation/key-frame-channel.h>
namespace Dali
{
{
class KeyFrameSpec;
class KeyFrames;
-typedef IntrusivePtr<KeyFrames> KeyFramesPtr;
-
/**
* KeyFrames class is responsible for creating and building a specialized KeyFrame class
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
*/
* @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
*/
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
-
-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();
- }
+ KeyFrameChannel<V> mChannel; // The key frame channel
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
*/
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();
}
/**
* @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 < 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
{
- DALI_ASSERT_ALWAYS( index < mPVs.size() && "KeyFrame index is out of bounds" );
- time = mPVs[index].mProgress;
- value = mPVs[index].mValue;
+ const auto& element = mChannel.mValues[index];
+ time = element.mProgress;
+ value = element.mValue;
}
/**
*/
bool IsActive(float progress) const
{
- return mKeyFrames->IsActive(progress);
+ return mChannel.IsActive(progress);
}
/**
*/
V GetValue(float progress, Dali::Animation::Interpolation interpolation) const
{
- return mKeyFrames->GetValue(progress, interpolation);
+ return mChannel.GetValue(progress, interpolation);
}
};
-typedef KeyFrameBaseSpec<float> KeyFrameNumber;
-typedef KeyFrameBaseSpec<bool> KeyFrameBoolean;
-typedef KeyFrameBaseSpec<int> KeyFrameInteger;
-typedef KeyFrameBaseSpec<unsigned int> KeyFrameUnsignedInteger;
-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<KeyFrameInteger> KeyFrameIntegerPtr;
-typedef IntrusivePtr<KeyFrameUnsignedInteger> KeyFrameUnsignedIntegerPtr;
-typedef IntrusivePtr<KeyFrameVector2> KeyFrameVector2Ptr;
-typedef IntrusivePtr<KeyFrameVector3> KeyFrameVector3Ptr;
-typedef IntrusivePtr<KeyFrameVector4> KeyFrameVector4Ptr;
-typedef IntrusivePtr<KeyFrameQuaternion> KeyFrameQuaternionPtr;
-
-
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameBoolean*& keyFrameSpec)
-{
- keyFrameSpec = static_cast<Internal::KeyFrameBoolean*>(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::KeyFrameInteger*& keyFrameSpec)
-{
- keyFrameSpec = static_cast<Internal::KeyFrameInteger*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameInteger*& keyFrameSpec)
-{
- keyFrameSpec = static_cast<const Internal::KeyFrameInteger*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameUnsignedInteger*& keyFrameSpec)
-{
- keyFrameSpec = static_cast<Internal::KeyFrameUnsignedInteger*>(keyFrames.GetKeyFramesBase());
-}
-
-inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameUnsignedInteger*& keyFrameSpec)
-{
- keyFrameSpec = static_cast<const Internal::KeyFrameUnsignedInteger*>(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());
-}
+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(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector3*& keyFrameSpec)
+template<typename DeriveClass>
+auto GetSpecialization(const Internal::KeyFrames& keyFrames)
{
- keyFrameSpec = static_cast<const Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
+ return static_cast<DeriveClass>(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