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 #ifndef META_SRC_ANIMATION_H
16 #define META_SRC_ANIMATION_H
17
18 #include <meta/api/make_callback.h>
19 #include <meta/interface/animation/builtin_animations.h>
20 #include <meta/interface/animation/intf_animation.h>
21 #include <meta/interface/intf_containable.h>
22 #include <meta/interface/serialization/intf_serializable.h>
23
24 #include "../object.h"
25 #include "animation_state.h"
26 #include "staggered_animation_state.h"
27
META_BEGIN_NAMESPACE()28 META_BEGIN_NAMESPACE()
29
30 namespace Internal {
31
32 /**
33 * @brief A base class which can be used by generic animation implementations.
34 */
35 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
36 class BaseAnimationFwd : public Internal::ObjectFwd<FinalClass, ClassInfo, BaseAnimationInterface, INotifyOnChange,
37 IAttachment, IContainable, IMutableContainable, IAnimationInternal, Interfaces...> {
38 static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, IAnimation*>,
39 "BaseAnimationInterface of BaseAnimationFwd must inherit from IAnimation");
40 using Super = Internal::ObjectFwd<FinalClass, ClassInfo, BaseAnimationInterface, INotifyOnChange, IAttachment,
41 IContainable, IMutableContainable, IAnimationInternal, Interfaces...>;
42
43 protected:
44 BaseAnimationFwd() = default;
45 ~BaseAnimationFwd() override = default;
46
47 protected: // IObject
48 BASE_NS::string GetName() const override
49 {
50 return META_ACCESS_PROPERTY_VALUE(Name);
51 }
52
53 protected: // ILifecycle
54 bool Build(const IMetadata::Ptr& data) override
55 {
56 if (Super::Build(data)) {
57 META_ACCESS_PROPERTY(Name)->SetDefaultValue(Super::GetName());
58 return GetState().Initialize(BASE_NS::move(GetParams()));
59 }
60 return false;
61 }
62 void Destroy() override
63 {
64 GetState().Uninitialize();
65 Super::Destroy();
66 }
67
68 virtual AnimationState::AnimationStateParams GetParams() = 0;
69
70 protected: // IContainable
71 IObject::Ptr GetParent() const override
72 {
73 return parent_.lock();
74 }
75
76 protected: // IMutableContainable
77 void SetParent(const IObject::Ptr& parent) override
78 {
79 parent_ = parent;
80 }
81
82 protected: // INamed
83 META_IMPLEMENT_INTERFACE_PROPERTY(INamed, BASE_NS::string, Name)
84
85 protected: // IAttach
86 bool Attach(const IObject::Ptr& attachment, const IObject::Ptr& dataContext) override
87 {
88 return GetState().Attach(attachment, dataContext);
89 }
90 bool Detach(const IObject::Ptr& attachment) override
91 {
92 return GetState().Detach(attachment);
93 }
94
95 protected: // IAnimationInternal
96 void ResetClock() override
97 {
98 GetState().ResetClock();
99 }
100
101 bool Move(const IAnimationInternal::MoveParams& move) override
102 {
103 return GetState().Move(move).changed;
104 }
105
106 void OnAnimationStateChanged(const IAnimationInternal::AnimationStateChangedInfo& info) override
107 {
108 Evaluate();
109 }
110 void OnEvaluationNeeded() override
111 {
112 Evaluate();
113 }
114
115 protected: // IAttachment
116 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IObject::WeakPtr, DataContext)
117 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IAttach::WeakPtr, AttachedTo)
118 bool Attaching(const IAttach::Ptr& target, const IObject::Ptr& dataContext) override
119 {
120 SetValue(META_ACCESS_PROPERTY(AttachedTo), target);
121 SetValue(META_ACCESS_PROPERTY(DataContext), dataContext);
122 return true;
123 }
124 bool Detaching(const IAttach::Ptr& target) override
125 {
126 SetValue(META_ACCESS_PROPERTY(AttachedTo), {});
127 SetValue(META_ACCESS_PROPERTY(DataContext), {});
128 return true;
129 }
130
131 protected: // IAnimation
132 META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, bool, Enabled, true)
133 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Valid, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
134 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, TimeSpan, TotalDuration, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
135 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Running, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
136 META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, float, Progress, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
137 META_IMPLEMENT_INTERFACE_PROPERTY(
138 IAnimation, IAnimationController::WeakPtr, Controller, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
139 META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, ICurve1D::Ptr, Curve)
140 void Step(const IClock::ConstPtr& clock) override
141 {
142 GetState().Step(clock);
143 }
144 META_IMPLEMENT_INTERFACE_EVENT(IAnimation, IOnChanged, OnFinished)
145 META_IMPLEMENT_INTERFACE_EVENT(IAnimation, IOnChanged, OnStarted)
146
147 protected: // INotifyOnChange
148 META_IMPLEMENT_INTERFACE_EVENT(INotifyOnChange, IOnChanged, OnChanged)
149
150 void NotifyChanged()
151 {
152 META_ACCESS_EVENT(OnChanged)->Invoke();
153 }
154
155 protected:
156 virtual void Evaluate() = 0;
157 virtual Internal::AnimationState& GetState() noexcept = 0;
158
159 private:
160 IObject::WeakPtr parent_;
161 };
162
163 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
164 class BaseStartableAnimationFwd
165 : public BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IStartableAnimation, Interfaces...> {
166 using Super = BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IStartableAnimation, Interfaces...>;
167 using Super::GetState;
168
169 protected: // IStartableAnimation
170 void Pause() override
171 {
172 GetState().Pause();
173 }
174 void Restart() override
175 {
176 GetState().Restart();
177 }
178 void Seek(float position) override
179 {
180 GetState().Seek(position);
181 }
182 void Start() override
183 {
184 GetState().Start();
185 }
186 void Stop() override
187 {
188 GetState().Stop();
189 }
190 void Finish() override
191 {
192 GetState().Finish();
193 }
194 };
195
196 /**
197 * @brief A base class which can be used by animation container implementations.
198 */
199 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
200 class BaseAnimationContainerFwd : public BaseStartableAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface,
201 IContainer, ILockable, IIterable, IImportFinalize, Interfaces...> {
202 static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, IStaggeredAnimation*>,
203 "BaseAnimationInterface of BaseAnimationContainerFwd must inherit from IStaggeredAnimation");
204 using Super = BaseStartableAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IContainer, ILockable,
205 IIterable, IImportFinalize, Interfaces...>;
206 using IContainer::SizeType;
207
208 public: // ILockable
209 void Lock() const override
210 {
211 if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
212 lockable->Lock();
213 }
214 }
215 void Unlock() const override
216 {
217 if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
218 lockable->Unlock();
219 }
220 }
221 void LockShared() const override
222 {
223 if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
224 lockable->LockShared();
225 }
226 }
227 void UnlockShared() const override
228 {
229 if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
230 lockable->UnlockShared();
231 }
232 }
233
234 protected:
235 Internal::StaggeredAnimationState& GetState() noexcept override = 0;
236
237 ReturnError Finalize(IImportFunctions&) override
238 {
239 GetState().ChildrenChanged();
240 return GenericError::SUCCESS;
241 }
242
243 public: // IIterable
244 IterationResult Iterate(const IterationParameters& params) override
245 {
246 auto iterable = interface_cast<IIterable>(&GetContainer());
247 return iterable ? iterable->Iterate(params) : IterationResult::FAILED;
248 }
249 IterationResult Iterate(const IterationParameters& params) const override
250 {
251 const auto iterable = interface_cast<IIterable>(&GetContainer());
252 return iterable ? iterable->Iterate(params) : IterationResult::FAILED;
253 }
254
255 public: // IContainer
256 bool Add(const IObject::Ptr& object) override
257 {
258 return GetContainer().Add(object);
259 }
260 bool Insert(SizeType index, const IObject::Ptr& object) override
261 {
262 return GetContainer().Insert(index, object);
263 }
264 bool Remove(SizeType index) override
265 {
266 return GetContainer().Remove(index);
267 }
268 bool Remove(const IObject::Ptr& child) override
269 {
270 return GetContainer().Remove(child);
271 }
272 bool Move(SizeType fromIndex, SizeType toIndex) override
273 {
274 return GetContainer().Move(fromIndex, toIndex);
275 }
276 bool Move(const IObject::Ptr& child, SizeType toIndex) override
277 {
278 return GetContainer().Move(child, toIndex);
279 }
280 bool Replace(const IObject::Ptr& child, const IObject::Ptr& replaceWith, bool addAlways) override
281 {
282 return GetContainer().Replace(child, replaceWith, addAlways);
283 }
284 BASE_NS::vector<IObject::Ptr> GetAll() const override
285 {
286 return GetContainer().GetAll();
287 }
288 void RemoveAll() override
289 {
290 GetContainer().RemoveAll();
291 }
292 IObject::Ptr GetAt(SizeType index) const override
293 {
294 return GetContainer().GetAt(index);
295 }
296 SizeType GetSize() const override
297 {
298 return GetContainer().GetSize();
299 }
300 BASE_NS::vector<IObject::Ptr> FindAll(const IContainer::FindOptions& options) const override
301 {
302 return GetContainer().FindAll(options);
303 }
304 IObject::Ptr FindAny(const IContainer::FindOptions& options) const override
305 {
306 return GetContainer().FindAny(options);
307 }
308 IObject::Ptr FindByName(BASE_NS::string_view name) const override
309 {
310 return GetContainer().FindByName(name);
311 }
312 bool IsAncestorOf(const IObject::ConstPtr& object) const override
313 {
314 return GetContainer().IsAncestorOf(object);
315 }
316
317 META_FORWARD_EVENT(IOnChanged, OnAdded, GetContainer().EventOnAdded());
318 META_FORWARD_EVENT(IOnChanged, OnRemoved, GetContainer().EventOnRemoved());
319 META_FORWARD_EVENT(IOnChanged, OnMoved, GetContainer().EventOnMoved());
320
321 protected: // IStaggeredAnimation
322 void AddAnimation(const IAnimation::Ptr& animation) override
323 {
324 GetContainer().Add(animation);
325 }
326 void RemoveAnimation(const IAnimation::Ptr& animation) override
327 {
328 GetContainer().Remove(animation);
329 }
330 BASE_NS::vector<IAnimation::Ptr> GetAnimations() const override
331 {
332 return GetContainer().template GetAll<IAnimation>();
333 }
334
335 protected:
336 virtual IContainer& GetContainer() noexcept = 0;
337 virtual const IContainer& GetContainer() const noexcept = 0;
338 };
339
340 /**
341 * @brief A base class which can be used by property animation implementations.
342 */
343 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
344 class BasePropertyAnimationFwd : public BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface,
345 IPropertyAnimation, IModifier, IImportFinalize, Interfaces...> {
346 static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, ITimedAnimation*>,
347 "BaseAnimationInterface of BasePropertyAnimationFwd must inherit from ITimedAnimation");
348 using Super = BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IPropertyAnimation, IModifier,
349 IImportFinalize, Interfaces...>;
350
351 protected:
352 BasePropertyAnimationFwd() = default;
353 ~BasePropertyAnimationFwd() override = default;
354
355 protected: // ILifecycle
356 bool Build(const IMetadata::Ptr& data) override
357 {
358 if (Super::Build(data)) {
359 META_ACCESS_PROPERTY(Property)->OnChanged()->AddHandler(
360 MakeCallback<IOnChanged>(this, &BasePropertyAnimationFwd::PropertyChanged));
361 return true;
362 }
363 return false;
364 }
365
366 protected: // IPropertyAnimation
367 META_IMPLEMENT_INTERFACE_PROPERTY(IPropertyAnimation, IProperty::WeakPtr, Property);
368
369 protected: // ITimedAnimation
370 META_IMPLEMENT_INTERFACE_PROPERTY(ITimedAnimation, TimeSpan, Duration)
371
372 protected: // IModifier
373 EvaluationResult ProcessOnGet(IAny& value) override
374 {
375 return EvaluationResult::EVAL_CONTINUE;
376 }
377 EvaluationResult ProcessOnSet(IAny& value, const IAny& current) override
378 {
379 return EvaluationResult::EVAL_CONTINUE;
380 }
381 bool IsCompatible(const TypeId& id) const override
382 {
383 if (auto p = GetTargetProperty()) {
384 return META_NS::IsCompatible(p.property->GetValue(), id);
385 }
386 return false;
387 }
388 Internal::PropertyAnimationState& GetState() noexcept override = 0;
389
390 protected:
391 ReturnError Finalize(IImportFunctions&) override
392 {
393 GetState().UpdateTotalDuration();
394 auto p = GetTargetProperty();
395 GetState().SetInterpolator(p ? p.property->GetTypeId() : TypeId {});
396 SetValue(Super::META_ACCESS_PROPERTY(Valid), p);
397 return GenericError::SUCCESS;
398 }
399
400 protected:
401 struct TargetProperty {
402 IProperty::Ptr property;
403 IStackProperty::Ptr stack;
404 /* NOLINTNEXTLINE(google-explicit-constructor) */
405 operator bool() const noexcept
406 {
407 return property && stack;
408 }
409 };
410
411 void PropertyChanged()
412 {
413 auto p = GetTargetProperty();
414 this->GetState().SetInterpolator(p ? p.property->GetTypeId() : TypeId {});
415 SetValue(Super::META_ACCESS_PROPERTY(Valid), p);
416 OnPropertyChanged(p, property_.lock());
417 property_ = p.stack;
418 }
419
420 virtual void OnPropertyChanged(const TargetProperty& property, const IStackProperty::Ptr& previous) = 0;
421
422 TargetProperty GetTargetProperty() const noexcept
423 {
424 auto p = META_ACCESS_PROPERTY_VALUE(Property).lock();
425 return { p, interface_pointer_cast<IStackProperty>(p) };
426 }
427
428 private:
429 IStackProperty::WeakPtr property_;
430 };
431
432 /**
433 * @brief A base class which can be used by property animation implementations.
434 */
435 template<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
436 class PropertyAnimationFwd
437 : public BasePropertyAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, Interfaces...> {
438 using Super = BasePropertyAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, Interfaces...>;
439
440 protected:
441 PropertyAnimationFwd() = default;
442 ~PropertyAnimationFwd() override = default;
443
444 protected:
445 // Note covariance
446 Internal::PropertyAnimationState& GetState() noexcept override
447 {
448 return state_;
449 }
450
451 private:
452 Internal::PropertyAnimationState state_;
453 };
454
455 } // namespace Internal
456
457 META_END_NAMESPACE()
458
459 #endif // META_SRC_ANIMATION_H
460