1 #ifndef DALI_INTERNAL_KEY_FRAMES_H
2 #define DALI_INTERNAL_KEY_FRAMES_H
5 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 #include <dali/public-api/common/vector-wrapper.h>
26 #include <dali/public-api/animation/key-frames.h>
27 #include <dali/public-api/object/base-object.h>
28 #include <dali/public-api/animation/alpha-function.h>
29 #include <dali/internal/event/animation/key-frame-channel.h>
39 * KeyFrames class is responsible for creating and building a specialized KeyFrame class
40 * from the Property::Value type used in Add.
42 class KeyFrames : public BaseObject
45 static KeyFrames* New();
50 * Create a specialization from the given type, and store it to the mSpec
53 void CreateKeyFramesSpec(Property::Type type);
57 * Get the type of this key frame.
58 * An empty key frame will return Property::NONE, wheras an initialised
59 * key frame object will return the type of it's first element.
60 * @return the Property::Type of the key frame values
62 Property::Type GetType() const;
65 * Add a key frame. The first key frame to be added denotes the type
66 * of all subsequent key frames. If a value with a different type is
67 * added, it will throw a run time assert.
68 * @param[in] time The time (between 0 and 1)
69 * @param[in] value The value of the keyframe at the given time
70 * @param[in] alpha An alpha function to blend between this key frame and the
73 void Add(float time, const Property::Value& value, AlphaFunction alpha);
76 * Return the key frames without specialization. The GetSpecialization methods
77 * below will convert to the specialized objects.
79 KeyFrameSpec* GetKeyFramesBase() const;
82 * Return the value of the last key frame.
84 Dali::Property::Value GetLastKeyFrameValue() const;
87 Dali::Property::Type mType{Property::NONE}; // Type of the specialization
88 std::unique_ptr<KeyFrameSpec> mKeyFrames; // Pointer to the specialized key frame object
92 * This is the base class for the individual template specializations, allowing a ptr to be
93 * stored in the handle object above.
98 virtual ~KeyFrameSpec() = default;
100 virtual std::size_t GetNumberOfKeyFrames() const = 0;
103 * Get the key frame value as a Property::Value.
104 * @param[in] index The index of the key frame to fetch
105 * @param[out] value The value of the given key frame
107 virtual void GetKeyFrameAsValue( std::size_t index, Property::Value& value ) = 0;
111 * The base template class for each key frame specialization.
114 class KeyFrameBaseSpec : public KeyFrameSpec
116 KeyFrameChannel<V> mChannel; // The key frame channel
120 * Add a key frame to the channel. Key frames should be added
121 * in time order (this method does not sort the vector by time)
122 * @param[in] t - progress
123 * @param[in] v - value
124 * @param[in] alpha - Alpha function for blending to the next keyframe
126 void AddKeyFrame(float t, V v, AlphaFunction alpha)
128 mChannel.mValues.push_back({t, v});
132 * Get the number of key frames
133 * @return Channel size
135 std::size_t GetNumberOfKeyFrames() const override
137 return mChannel.mValues.size();
142 * @param[in] index The index of the key frame to fetch
143 * @param[out] time The progress of the given key frame
144 * @param[out] value The value of the given key frame
146 void GetKeyFrame(unsigned int index, float& time, V& value) const
148 DALI_ASSERT_ALWAYS(index < mChannel.mValues.size() && "KeyFrame index is out of bounds");
149 const auto& element = mChannel.mValues[index];
150 time = element.mProgress;
151 value = element.mValue;
155 * @copydoc KeyFrameSpec::GetKeyFrameAsValue()
157 void GetKeyFrameAsValue( std::size_t index, Property::Value& value ) override
159 value = mChannel.mValues[index].mValue;
163 * Return whether the progress is valid for the range of keyframes. (The first
164 * keyframe doesn't have to start at 0, and the last doesn't have to end at 1.0)
165 * @param[in] progress The progress to test
166 * @return True if the progress is valid for this object
168 bool IsActive(float progress) const
170 return mChannel.IsActive(progress);
174 * Return an interpolated value for the given progress.
175 * @param[in] progress The progress to test
176 * @return The interpolated value
178 V GetValue(float progress, Dali::Animation::Interpolation interpolation) const
180 return mChannel.GetValue(progress, interpolation);
184 using KeyFrameNumber = KeyFrameBaseSpec<float>;
185 using KeyFrameBoolean = KeyFrameBaseSpec<bool>;
186 using KeyFrameInteger = KeyFrameBaseSpec<int>;
187 using KeyFrameVector2 = KeyFrameBaseSpec<Vector2>;
188 using KeyFrameVector3 = KeyFrameBaseSpec<Vector3>;
189 using KeyFrameVector4 = KeyFrameBaseSpec<Vector4>;
190 using KeyFrameQuaternion = KeyFrameBaseSpec<Quaternion>;
192 template<typename DeriveClass>
193 auto GetSpecialization(const Internal::KeyFrames& keyFrames)
195 return static_cast<DeriveClass>(keyFrames.GetKeyFramesBase());
201 // Get impl of handle
202 inline Internal::KeyFrames& GetImplementation(Dali::KeyFrames& keyFrames)
204 DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
205 Dali::RefObject& object = keyFrames.GetBaseObject();
206 return static_cast<Internal::KeyFrames&>(object);
209 inline const Internal::KeyFrames& GetImplementation(const Dali::KeyFrames& keyFrames)
211 DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
212 const Dali::RefObject& object = keyFrames.GetBaseObject();
213 return static_cast<const Internal::KeyFrames&>(object);
219 #endif // DALI_INTERNAL_KEY_FRAMES_H