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