1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef META_INTERFACE_INTF_ANIMATION_H
17 #define META_INTERFACE_INTF_ANIMATION_H
18 
19 #include <base/containers/vector.h>
20 #include <base/math/vector.h>
21 #include <core/plugin/intf_interface.h>
22 
23 #include <meta/base/ids.h>
24 #include <meta/base/namespace.h>
25 #include <meta/interface/animation/intf_animation_controller.h>
26 #include <meta/interface/animation/intf_animation_modifier.h>
27 #include <meta/interface/animation/intf_interpolator.h>
28 #include <meta/interface/curves/intf_curve_1d.h>
29 #include <meta/interface/intf_named.h>
30 #include <meta/interface/intf_object.h>
31 #include <meta/interface/property/intf_property.h>
32 #include <meta/interface/simple_event.h>
33 
34 #include "meta/interface/property/property_events.h"
35 
36 META_BEGIN_NAMESPACE()
37 
38 META_REGISTER_INTERFACE(IAnimation, "37649f24-9ddd-4f8f-975b-9105db83cad0")
39 META_REGISTER_INTERFACE(IStartableAnimation, "1d1c7cac-0f13-421a-bbe8-f1aec751db6a")
40 META_REGISTER_INTERFACE(IPropertyAnimation, "501d9079-166e-4a59-a8f8-dfbae588bf80")
41 META_REGISTER_INTERFACE(IKeyframeAnimation, "75446215-498a-460f-8958-42f681c8becb")
42 META_REGISTER_INTERFACE(IStaggeredAnimation, "566ac43f-0408-403c-ab37-724687252ecd")
43 META_REGISTER_INTERFACE(ISequentialAnimation, "1c776172-f3d0-446c-8840-d487b916fbdd")
44 META_REGISTER_INTERFACE(IParallelAnimation, "5e9c463d-a442-46fe-8ee2-fb7396b1a90a")
45 META_REGISTER_INTERFACE(ITrackAnimation, "fdb5ee37-cd69-4591-8bc2-c13332baae18")
46 META_REGISTER_INTERFACE(ITimedAnimation, "4dacfc3d-747a-4bbb-88e7-505586d12c3f")
47 
48 class IStaggeredAnimation;
49 
50 /**
51  * @brief IAnimation is the base interface for all animations.
52  */
53 class IAnimation : public INamed {
54     META_INTERFACE(INamed, IAnimation)
55 public:
56     /**
57      * @brief If true, the animation is enabled. If false, the animation
58      *        remains stopped in the initial state.
59      *        The default value is true.
60      */
61     META_PROPERTY(bool, Enabled)
62 
63     /**
64      * @brief True when the animation is in a valid state to be run.
65      *        For a PropertyAnimation this means that the animation points
66      *        to a valid property. For a StaggeredAnimation this means
67      *        that the animation has valid child animations.
68      */
69     META_READONLY_PROPERTY(bool, Valid)
70 
71     /**
72      * @brief Duration of the animation after all animation modifiers have been applied.
73      */
74     META_READONLY_PROPERTY(TimeSpan, TotalDuration)
75 
76     /**
77      * @brief True when the animation is running, false otherwise.
78      */
79     META_READONLY_PROPERTY(bool, Running)
80 
81     /**
82      * @brief Animation state from [0,1] while the animation is running. When the animation
83      *        has finished, the value will be 1.
84      */
85     META_READONLY_PROPERTY(float, Progress)
86 
87     /**
88      * @brief Animation follows this curve.
89      */
90     META_PROPERTY(ICurve1D::Ptr, Curve)
91 
92     /**
93      * @brief Controller which handles this animation.
94      *        The default value is the controller returned by META_NS::GetAnimationController().
95      * @note  To completely detach the animation from any controller, set the property to nullptr.
96      *        In such a case the user is responsible for manually stepping the animation
97      *        whenever needed.
98      */
99     META_PROPERTY(BASE_NS::weak_ptr<IAnimationController>, Controller)
100 
101     /**
102      * @brief Steps the animation. Called by the framework, usually there is no
103      *        need to call this manually.
104      */
105     virtual void Step(const IClock::ConstPtr& clock) = 0;
106 
107     /**
108      * @brief Invoked when the animation has reached the end.
109      */
110     META_EVENT(IOnChanged, OnFinished)
111     /**
112      * @brief Invoked when the animation has started from the beginning.
113      */
114     META_EVENT(IOnChanged, OnStarted)
115 };
116 
117 class IStartableAnimation : public CORE_NS::IInterface {
118     META_INTERFACE2(CORE_NS::IInterface, IStartableAnimation)
119 public:
120     /**
121      * @brief Pauses the animation.
122      */
123     virtual void Pause() = 0;
124     /**
125      * @brief Stops the animation and starts it from the beginning.
126      */
127     virtual void Restart() = 0;
128     /**
129      * @brief Seeks animation to a specified position.
130      *
131      * @param position New Position of the animation. The value should be in
132      *                 [0, 1] range, otherwise it will be clamped.
133      */
134     virtual void Seek(float position) = 0;
135     /**
136      * @brief Starts the animation.
137      */
138     virtual void Start() = 0;
139     /**
140      * @brief Stops the animation. It resets animation progress.
141      */
142     virtual void Stop() = 0;
143     /**
144      * @brief Jumps to the end of the animation.
145      */
146     virtual void Finish() = 0;
147 };
148 
149 /**
150  * @brief The IStaggeredAnimation defines an interface for an animation container which
151  *        takes control of how it's child animations are run.
152  */
153 class IStaggeredAnimation : public IAnimation {
154     META_INTERFACE(IAnimation, IStaggeredAnimation)
155 public:
156     /**
157      * @brief Add a new animation to the container.
158      */
159     virtual void AddAnimation(const IAnimation::Ptr&) = 0;
160     /**
161      * @brief Remove an animation from the container.
162      */
163     virtual void RemoveAnimation(const IAnimation::Ptr&) = 0;
164     /**
165      * @brief Returns all direct child animations of this animation.
166      */
167     virtual BASE_NS::vector<IAnimation::Ptr> GetAnimations() const = 0;
168 };
169 
170 /**
171  * @brief The ISequentialAnimation interface defines an interface for an animation container
172  *        which runs its child animations in sequence one after another.
173  *
174  *        Duration property is set by the container to reflect the total running time of all
175  *        the animations added to the container. Setting the value has no effect.
176  */
177 class ISequentialAnimation : public IStaggeredAnimation {
178     META_INTERFACE(IStaggeredAnimation, ISequentialAnimation)
179 public:
180 };
181 
182 /**
183  * @brief The IParallelAnimation interface defines an interface for an animation container
184  *        which runs its child animations parallelly.
185  *
186  *        Duration property is set by the container to reflect the running time of the longest
187  *        running animation added to the container. Setting the value has no effect.
188  */
189 class IParallelAnimation : public IStaggeredAnimation {
190     META_INTERFACE(IStaggeredAnimation, IParallelAnimation)
191 public:
192 };
193 
194 class ITimedAnimation : public IAnimation {
195     META_INTERFACE(IAnimation, ITimedAnimation)
196 public:
197     /**
198      * @brief Duration of the animation before any modifiers are applied.
199      */
200     META_PROPERTY(TimeSpan, Duration)
201 };
202 
203 /**
204  * @brief IPropertyAnimation defines an interface for animations which can animate a property.
205  */
206 class IPropertyAnimation : public CORE_NS::IInterface {
207     META_INTERFACE(CORE_NS::IInterface, IPropertyAnimation, META_NS::InterfaceId::IPropertyAnimation)
208 public:
209     /**
210      * @brief Target property for this animation.
211      *        Once target property is set, the type of the animation will be automatically
212      *        set to match the type of the target property.
213      */
214     META_PROPERTY(IProperty::WeakPtr, Property)
215 };
216 
217 /**
218  * @brief IPropertyAnimation can be used to define an explicit keyframe animation on a property between two values.
219  */
220 class IKeyframeAnimation : public ITimedAnimation {
221     META_INTERFACE(ITimedAnimation, IKeyframeAnimation, META_NS::InterfaceId::IKeyframeAnimation)
222 public:
223     /**
224      * @brief A property containing the start value of the animation.
225      *        Animation implementation will create a property of suitable type for the animation target property.
226      * @note The property is null until target property is set or IPropertyAnimation::SetType is called explicitly.
227      */
228     META_PROPERTY(IAny::Ptr, From)
229     /**
230      * @brief A property containing the end value of the animation.
231      *        Animation implementation will create a property of suitable type for the animation target property.
232      * @note  The property is null until target property is set or IPropertyAnimation::SetType is called explicitly.
233      */
234     META_PROPERTY(IAny::Ptr, To)
235 };
236 
237 /**
238  * @brief ITrackAnimation defines the interface for an animation track, which can have multiple keyframes associated
239  *        with a set of timestamps.
240  *
241  *        Functionality-wise a track animation is identical to a sequential animation with several keyframe animations
242  *        all targetting the same property as it children. In such a case track animation is simpler to use and can
243  *        also be implemented more efficiently by the framework.
244  */
245 class ITrackAnimation : public CORE_NS::IInterface {
246     META_INTERFACE(CORE_NS::IInterface, ITrackAnimation, META_NS::InterfaceId::ITrackAnimation)
247 public:
248     /**
249      * @brief Value of CurrentKeyframeIndex when the animation is not in valid timestamp range.
250      */
251     constexpr static uint32_t INVALID_INDEX = uint32_t(-1);
252     /**
253      * @brief TimeStamps for the animation. Timestamps are positions of the keyframes on the track, relative
254      *        to the Duration of the animation.
255      * @note Number of timestamps must match the number of keyframes.
256      */
257     META_ARRAY_PROPERTY(float, Timestamps)
258     /**
259      * @brief Keyframes for the animation.
260      * @note Number of keyframes must match the number of timestamps.
261      * @note KeyFrames property is invalid until target Property has been set, or IPropertyAnimation::SetType()
262      *       has been called.
263      */
264     virtual IProperty::Ptr Keyframes() const = 0;
265     /**
266      * @brief Array of curves used for interpolating between each keyframe.
267      * @note  As the curves are used to interpolate between keyframes, the number of curves needed to cover
268      *        the entire animation is the number of keyframes - 1.
269      * @note  The array can contain nullptrs, in which case the keyframe is interpolated linearly.
270      * @note  The array size does not need to match keyframe count. Any keyframes for whom a matching curve
271      *        is not found in the array are interpolated linearly.
272      * @note  IAnimation::Curve can be used for controlling the progress over the full animation duration.
273      */
274     META_ARRAY_PROPERTY(ICurve1D::Ptr, KeyframeCurves)
275     /**
276      * @brief Array of functions that the track animation will call when the keyframe whose index corresponds
277      *        to the index in the handler function array is reached.
278      * @note  The array can also contain nullptrs if there is no handler for all frames.
279      */
280     META_ARRAY_PROPERTY(IFunction::Ptr, KeyframeHandlers)
281     /**
282      * @brief Index of the current keyframe.
283      */
284     META_READONLY_PROPERTY(uint32_t, CurrentKeyframeIndex)
285     /**
286      * @brief Adds a keyframe to the track animation.
287      * @param timestamp Timestamp of the new keyframe. The keyframe will be added to such an index which maintains
288      *                  ascending order of timestamps.
289      * @param from A property containing the value to be added.
290      * @return Index of the added keyframe or IMetaArrayProperty::N_POS in case of error.
291      */
292     virtual size_t AddKeyframe(float timestamp, const IAny::ConstPtr& value) = 0;
293     /**
294      * @brief Removes a keyframe and its associated timestamp from the track animation.
295      * @param index Index to remove from.
296      * @return True if a keyframe was removed, false otherwise.
297      */
298     virtual bool RemoveKeyframe(size_t index) = 0;
299     /**
300      * @brief Removes all keyframes and corresponding timestamps from the track animation.
301      */
302     virtual void RemoveAllKeyframes() = 0;
303 };
304 
305 META_END_NAMESPACE()
306 
307 META_INTERFACE_TYPE(META_NS::IAnimation)
308 META_INTERFACE_TYPE(META_NS::IPropertyAnimation)
309 META_INTERFACE_TYPE(META_NS::IKeyframeAnimation)
310 META_INTERFACE_TYPE(META_NS::IParallelAnimation)
311 META_INTERFACE_TYPE(META_NS::IStaggeredAnimation)
312 
313 #endif
314