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_API_ANIMATION_H
17 #define META_API_ANIMATION_H
18
19 #include <meta/api/curves.h>
20 #include <meta/api/object.h>
21 #include <meta/interface/animation/builtin_animations.h>
22 #include <meta/interface/animation/intf_animation.h>
23 #include <meta/interface/animation/intf_animation_modifier.h>
24 #include <meta/interface/animation/modifiers/intf_loop.h>
25 #include <meta/interface/animation/modifiers/intf_speed.h>
26
META_BEGIN_NAMESPACE()27 META_BEGIN_NAMESPACE()
28
29 /**
30 * @brief Wrapper class for for objects which implement IAnimation.
31 */
32 class Animation : public Object {
33 public:
34 META_INTERFACE_OBJECT(Animation, Object, IAnimation)
35
36 /// @see IAnimation::Enabled
37 META_INTERFACE_OBJECT_PROPERTY(bool, Enabled)
38 /// @see IAnimation::Valid
39 META_INTERFACE_OBJECT_READONLY_PROPERTY(bool, Valid)
40 /// @see IAnimation::TotalDuration
41 META_INTERFACE_OBJECT_READONLY_PROPERTY(TimeSpan, TotalDuration)
42 /// @see IAnimation::Running
43 META_INTERFACE_OBJECT_READONLY_PROPERTY(bool, Running)
44 /// @see IAnimation::Progress
45 META_INTERFACE_OBJECT_READONLY_PROPERTY(float, Progress)
46 /// @see IAnimation::Curve
47 META_INTERFACE_OBJECT_PROPERTY(ICurve1D::Ptr, Curve)
48 /// @see IAnimation::Controller
49 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::weak_ptr<IAnimationController>, Controller)
50 /**
51 * @see IStartableAnimation::Pause
52 * @note Does nothing if the underlying animation does not implement IStartableAnimation
53 */
54 void Pause()
55 {
56 CallPtr<IStartableAnimation>([](auto& p) { p.Pause(); });
57 }
58 /**
59 * @see IStartableAnimation::Restart
60 * @note Does nothing if the underlying animation does not implement IStartableAnimation
61 */
62 void Restart()
63 {
64 CallPtr<IStartableAnimation>([](auto& p) { p.Restart(); });
65 }
66 /**
67 * @see IStartableAnimation::Seek
68 * @note Does nothing if the underlying animation does not implement IStartableAnimation
69 */
70 void Seek(float position)
71 {
72 CallPtr<IStartableAnimation>([position](auto& p) { p.Seek(position); });
73 }
74 /**
75 * @see IStartableAnimation::Start
76 * @note Does nothing if the underlying animation does not implement IStartableAnimation
77 */
78 void Start()
79 {
80 CallPtr<IStartableAnimation>([](auto& p) { p.Start(); });
81 }
82 /**
83 * @see IStartableAnimation::Stop
84 * @note Does nothing if the underlying animation does not implement IStartableAnimation
85 */
86 void Stop()
87 {
88 CallPtr<IStartableAnimation>([](auto& p) { p.Stop(); });
89 }
90 /**
91 * @see IStartableAnimation::Finish
92 * @note Does nothing if the underlying animation does not implement IStartableAnimation
93 */
94 void Finish()
95 {
96 CallPtr<IStartableAnimation>([](auto& p) { p.Finish(); });
97 }
98 /// @see IAnimation::Step
99 void Step(const IClock::ConstPtr& clock)
100 {
101 META_INTERFACE_OBJECT_CALL_PTR(Step(clock));
102 }
103 /// @see IAnimation::OnFinished
104 auto OnFinished()
105 {
106 return META_INTERFACE_OBJECT_CALL_PTR(OnFinished());
107 }
108 /// @see IAnimation::OnStarted
109 auto OnStarted()
110 {
111 return META_INTERFACE_OBJECT_CALL_PTR(OnStarted());
112 }
113 /**
114 * @brief Add a modifier to the animation
115 * @param modifier The modifier to add
116 * @return True if the modifier was successfully applied, false otherwise.
117 */
118 bool AddModifier(const IAnimationModifier::Ptr& modifier)
119 {
120 return CallPtr<IAttach>([&](auto& p) { return p.Attach(modifier); });
121 }
122 };
123
124 /**
125 * @brief Wrapper class for ITimedAnimation.
126 */
127 class TimedAnimation : public Animation {
128 public:
129 META_INTERFACE_OBJECT(TimedAnimation, Animation, ITimedAnimation)
130 META_INTERFACE_OBJECT_PROPERTY(TimeSpan, Duration)
131 };
132
133 /**
134 * @brief Wrapper class for IPropertyAnimation.
135 */
136 class PropertyAnimation : public TimedAnimation {
137 public:
138 META_INTERFACE_OBJECT(PropertyAnimation, TimedAnimation, IPropertyAnimation)
139 META_INTERFACE_OBJECT_INSTANTIATE(PropertyAnimation, ClassId::PropertyAnimation)
140
141 /// @see IPropertyAnimation::Property
142 META_INTERFACE_OBJECT_PROPERTY(IProperty::WeakPtr, Property)
143 };
144
145 /**
146 * @brief Typed wrapper class for objects which implement IKeyframeAnimation.
147 */
148 template<typename Type>
149 class KeyframeAnimation : public PropertyAnimation {
150 public:
META_INTERFACE_OBJECT(KeyframeAnimation<Type>,PropertyAnimation,IKeyframeAnimation)151 META_INTERFACE_OBJECT(KeyframeAnimation<Type>, PropertyAnimation, IKeyframeAnimation)
152 META_INTERFACE_OBJECT_INSTANTIATE(KeyframeAnimation<Type>, ClassId::KeyframeAnimation)
153 /// @see IKeyframeAnimation::From
154 auto GetFrom()
155 {
156 Type value;
157 Any<Type>(GetValue(META_INTERFACE_OBJECT_CALL_PTR(From()))).GetValue(value);
158 return value;
159 }
160 /// @see IKeyframeAnimation::To
GetTo()161 auto GetTo()
162 {
163 Type value;
164 Any<Type>(GetValue(META_INTERFACE_OBJECT_CALL_PTR(To()))).GetValue(value);
165 return value;
166 }
SetFrom(const Type & value)167 auto& SetFrom(const Type& value)
168 {
169 SetAnyPtrProperty(META_INTERFACE_OBJECT_CALL_PTR(From()), value);
170 return *this;
171 }
SetTo(const Type & value)172 auto& SetTo(const Type& value)
173 {
174 SetAnyPtrProperty(META_INTERFACE_OBJECT_CALL_PTR(To()), value);
175 return *this;
176 }
177
178 private:
179 template<typename PropertyType>
SetAnyPtrProperty(const PropertyType & p,const Type & value)180 void SetAnyPtrProperty(const PropertyType& p, const Type& value)
181 {
182 if (p) {
183 if (auto pv = p->GetValue()) { // IAny::Ptr
184 pv->SetValue(value);
185 } else {
186 p->SetValue(ConstructAny<Type>(value));
187 }
188 }
189 }
190 };
191
192 /**
193 * @brief Typed wrapper class for objects which implement ITrackAnimation.
194 */
195 template<typename T>
196 class TrackAnimation : public PropertyAnimation {
197 public:
META_INTERFACE_OBJECT(TrackAnimation<T>,PropertyAnimation,ITrackAnimation)198 META_INTERFACE_OBJECT(TrackAnimation<T>, PropertyAnimation, ITrackAnimation)
199 META_INTERFACE_OBJECT_INSTANTIATE(TrackAnimation<T>, ClassId::TrackAnimation)
200
201 /// @see ITrackAnimation::Timestamps
202 META_INTERFACE_OBJECT_ARRAY_PROPERTY(float, Timestamps, Timestamp)
203 /// Typed access to ITrackAnimation::Keyframes property.
204 auto Keyframes() const
205 {
206 auto kf = GetKeyframesProperty();
207 return kf ? kf->GetValue() : decltype(kf->GetValue()) {};
208 }
209 /// Set ITrackAnimation::Keyframes property from a typed array.
SetKeyframes(const BASE_NS::array_view<const T> keyframes)210 auto& SetKeyframes(const BASE_NS::array_view<const T> keyframes)
211 {
212 if (auto kf = GetKeyframesProperty()) {
213 kf->SetValue(keyframes);
214 }
215 return *this;
216 }
SetKeyframe(size_t index,const T & keyframe)217 auto& SetKeyframe(size_t index, const T& keyframe)
218 {
219 if (auto kf = GetKeyframesProperty()) {
220 kf->SetValueAt(index, keyframe);
221 }
222 return *this;
223 }
GetKeyframe(size_t index)224 T GetKeyframe(size_t index) const
225 {
226 auto kf = GetKeyframesProperty();
227 return kf ? kf->GetValueAt(index) : T {};
228 }
229 /// @see ITrackAnimation::KeyframeCurves
META_INTERFACE_OBJECT_ARRAY_PROPERTY(ICurve1D::Ptr,KeyframeCurves,KeyframeCurve)230 META_INTERFACE_OBJECT_ARRAY_PROPERTY(ICurve1D::Ptr, KeyframeCurves, KeyframeCurve)
231 /// @see ITrackAnimation::KeyframeHandlers
232 META_INTERFACE_OBJECT_ARRAY_PROPERTY(IFunction::Ptr, KeyframeHandlers, KeyframeHandler)
233 /// @see ITrackAnimation::CurrentKeyframeIndex
234 META_INTERFACE_OBJECT_READONLY_PROPERTY(uint32_t, CurrentKeyframeIndex)
235 /// @see ITrackAnimation::AddKeyframe
236 auto AddKeyframe(float timestamp, const IAny::ConstPtr& value)
237 {
238 return META_INTERFACE_OBJECT_CALL_PTR(AddKeyframe(timestamp, value));
239 }
240 /// @see ITrackAnimation::RemoveKeyframe
RemoveKeyframe(size_t index)241 auto RemoveKeyframe(size_t index)
242 {
243 return META_INTERFACE_OBJECT_CALL_PTR(RemoveKeyframe(index));
244 }
245 /// @see ITrackAnimation::RemoveAllKeyframes
RemoveAllKeyframes()246 void RemoveAllKeyframes()
247 {
248 META_INTERFACE_OBJECT_CALL_PTR(RemoveAllKeyframes());
249 }
250
251 private:
GetKeyframesProperty()252 auto GetKeyframesProperty() const
253 {
254 auto kf = META_INTERFACE_OBJECT_CALL_PTR(Keyframes());
255 if (auto internal = interface_cast<META_NS::IPropertyInternalAny>(kf)) {
256 if (!internal->GetInternalAny()) {
257 internal->SetInternalAny(ConstructArrayAny<T>());
258 }
259 }
260 return ArrayProperty<T>(kf);
261 }
262 };
263
264 /**
265 * @brief Wrapper class for animation containers.
266 */
267 class StaggeredAnimation : public Animation {
268 public:
META_INTERFACE_OBJECT(StaggeredAnimation,Animation,IStaggeredAnimation)269 META_INTERFACE_OBJECT(StaggeredAnimation, Animation, IStaggeredAnimation)
270 auto& Add(const IAnimation::Ptr& animation)
271 {
272 META_INTERFACE_OBJECT_CALL_PTR(AddAnimation(animation));
273 return *this;
274 }
Remove(const IAnimation::Ptr & animation)275 auto& Remove(const IAnimation::Ptr& animation)
276 {
277 META_INTERFACE_OBJECT_CALL_PTR(RemoveAnimation(animation));
278 return *this;
279 }
GetAnimations()280 BASE_NS::vector<IAnimation::Ptr> GetAnimations() const
281 {
282 return META_INTERFACE_OBJECT_CALL_PTR(GetAnimations());
283 }
284 };
285
286 /**
287 * @brief Wrapper class for objects which implement ISequentialAnimation.
288 */
289 class SequentialAnimation : public StaggeredAnimation {
290 public:
291 META_INTERFACE_OBJECT(SequentialAnimation, StaggeredAnimation, ISequentialAnimation)
292 META_INTERFACE_OBJECT_INSTANTIATE(SequentialAnimation, ClassId::SequentialAnimation)
293 };
294
295 /**
296 * @brief Wrapper class for objects which implement IParallelAnimation.
297 */
298 class ParallelAnimation : public StaggeredAnimation {
299 public:
300 META_INTERFACE_OBJECT(ParallelAnimation, StaggeredAnimation, IParallelAnimation)
301 META_INTERFACE_OBJECT_INSTANTIATE(ParallelAnimation, ClassId::ParallelAnimation)
302 };
303
304 /**
305 * @brief Wrapper class for objects which implement IAnimationModifier.
306 */
307 class AnimationModifier : public InterfaceObject<IAnimationModifier> {
308 public:
309 META_INTERFACE_OBJECT(AnimationModifier, InterfaceObject<IAnimationModifier>, IAnimationModifier)
310 };
311
312 namespace AnimationModifiers {
313
314 /**
315 * @brief Wrapper class for objects which implement ILoop.
316 */
317 class Loop : public AnimationModifier {
318 public:
META_INTERFACE_OBJECT(Loop,AnimationModifier,ILoop)319 META_INTERFACE_OBJECT(Loop, AnimationModifier, ILoop)
320 META_INTERFACE_OBJECT_INSTANTIATE(Loop, ClassId::LoopAnimationModifier)
321 /// @see ILoop::LoopCount
322 META_INTERFACE_OBJECT_PROPERTY(int32_t, LoopCount)
323 /// Set the modifier to loop indefinitely.
324 auto& LoopIndefinitely()
325 {
326 SetLoopCount(-1);
327 return *this;
328 }
329 };
330
331 /**
332 * @brief Wrapper class for objects which implement ISpeed.
333 */
334 class Speed : public AnimationModifier {
335 public:
336 META_INTERFACE_OBJECT(Speed, AnimationModifier, ISpeed)
337 META_INTERFACE_OBJECT_INSTANTIATE(Speed, ClassId::SpeedAnimationModifier)
338 /// @see ISpeed::SpeedFactor
339 META_INTERFACE_OBJECT_PROPERTY(float, SpeedFactor)
340 };
341
342 /**
343 * @brief Wrapper class for reverse animations.
344 */
345 class Reverse : public InterfaceObject<IAnimationModifier> {
346 public:
347 META_INTERFACE_OBJECT(Reverse, InterfaceObject<IAnimationModifier>, IAnimationModifier)
348 META_INTERFACE_OBJECT_INSTANTIATE(Reverse, ClassId::ReverseAnimationModifier)
349 };
350 } // namespace AnimationModifiers
351
352 /// Returns a default object which implements IPropertyAnimation
353 template<>
354 inline auto CreateObjectInstance<IPropertyAnimation>()
355 {
356 return PropertyAnimation(CreateNew);
357 }
358
359 /**
360 * @brief Returns a default typed animation object for given interface and type.
361 * @note Supported interfaces are IKeyframeAnimation and ITrackAnimation
362 */
363 template<typename Interface, typename Type>
CreateObjectInstance()364 inline auto CreateObjectInstance()
365 {
366 constexpr auto isKeyframeAnimation = BASE_NS::is_same_v<Interface, IKeyframeAnimation>;
367 constexpr auto isTrackAnimation = BASE_NS::is_same_v<Interface, ITrackAnimation>;
368 static_assert(isKeyframeAnimation || isTrackAnimation, "Invalid interface type for typed animation instantiation.");
369 if constexpr (isKeyframeAnimation) {
370 return KeyframeAnimation<Type>(CreateNew);
371 }
372 if constexpr (isTrackAnimation) {
373 return TrackAnimation<Type>(CreateNew);
374 }
375 }
376
377 /// Returns a default object which implements IKeyframeAnimation
378 template<>
379 inline auto CreateObjectInstance<IParallelAnimation>()
380 {
381 return ParallelAnimation(CreateNew);
382 }
383 /// Returns a default object which implements IKeyframeAnimation
384 template<>
385 inline auto CreateObjectInstance<ISequentialAnimation>()
386 {
387 return SequentialAnimation(CreateNew);
388 }
389
390 META_END_NAMESPACE()
391
392 #endif // META_API_ANIMATION_H
393