18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci#ifndef META_SRC_ANIMATION_H
168bf80f4bSopenharmony_ci#define META_SRC_ANIMATION_H
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <meta/api/make_callback.h>
198bf80f4bSopenharmony_ci#include <meta/interface/animation/builtin_animations.h>
208bf80f4bSopenharmony_ci#include <meta/interface/animation/intf_animation.h>
218bf80f4bSopenharmony_ci#include <meta/interface/intf_containable.h>
228bf80f4bSopenharmony_ci#include <meta/interface/serialization/intf_serializable.h>
238bf80f4bSopenharmony_ci
248bf80f4bSopenharmony_ci#include "../object.h"
258bf80f4bSopenharmony_ci#include "animation_state.h"
268bf80f4bSopenharmony_ci#include "staggered_animation_state.h"
278bf80f4bSopenharmony_ci
288bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
298bf80f4bSopenharmony_ci
308bf80f4bSopenharmony_cinamespace Internal {
318bf80f4bSopenharmony_ci
328bf80f4bSopenharmony_ci/**
338bf80f4bSopenharmony_ci * @brief A base class which can be used by generic animation implementations.
348bf80f4bSopenharmony_ci */
358bf80f4bSopenharmony_citemplate<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
368bf80f4bSopenharmony_ciclass BaseAnimationFwd : public Internal::ObjectFwd<FinalClass, ClassInfo, BaseAnimationInterface, INotifyOnChange,
378bf80f4bSopenharmony_ci                             IAttachment, IContainable, IMutableContainable, IAnimationInternal, Interfaces...> {
388bf80f4bSopenharmony_ci    static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, IAnimation*>,
398bf80f4bSopenharmony_ci        "BaseAnimationInterface of BaseAnimationFwd must inherit from IAnimation");
408bf80f4bSopenharmony_ci    using Super = Internal::ObjectFwd<FinalClass, ClassInfo, BaseAnimationInterface, INotifyOnChange, IAttachment,
418bf80f4bSopenharmony_ci        IContainable, IMutableContainable, IAnimationInternal, Interfaces...>;
428bf80f4bSopenharmony_ci
438bf80f4bSopenharmony_ciprotected:
448bf80f4bSopenharmony_ci    BaseAnimationFwd() = default;
458bf80f4bSopenharmony_ci    ~BaseAnimationFwd() override = default;
468bf80f4bSopenharmony_ci
478bf80f4bSopenharmony_ciprotected: // IObject
488bf80f4bSopenharmony_ci    BASE_NS::string GetName() const override
498bf80f4bSopenharmony_ci    {
508bf80f4bSopenharmony_ci        return META_ACCESS_PROPERTY_VALUE(Name);
518bf80f4bSopenharmony_ci    }
528bf80f4bSopenharmony_ci
538bf80f4bSopenharmony_ciprotected: // ILifecycle
548bf80f4bSopenharmony_ci    bool Build(const IMetadata::Ptr& data) override
558bf80f4bSopenharmony_ci    {
568bf80f4bSopenharmony_ci        if (Super::Build(data)) {
578bf80f4bSopenharmony_ci            META_ACCESS_PROPERTY(Name)->SetDefaultValue(Super::GetName());
588bf80f4bSopenharmony_ci            return GetState().Initialize(BASE_NS::move(GetParams()));
598bf80f4bSopenharmony_ci        }
608bf80f4bSopenharmony_ci        return false;
618bf80f4bSopenharmony_ci    }
628bf80f4bSopenharmony_ci    void Destroy() override
638bf80f4bSopenharmony_ci    {
648bf80f4bSopenharmony_ci        GetState().Uninitialize();
658bf80f4bSopenharmony_ci        Super::Destroy();
668bf80f4bSopenharmony_ci    }
678bf80f4bSopenharmony_ci
688bf80f4bSopenharmony_ci    virtual AnimationState::AnimationStateParams GetParams() = 0;
698bf80f4bSopenharmony_ci
708bf80f4bSopenharmony_ciprotected: // IContainable
718bf80f4bSopenharmony_ci    IObject::Ptr GetParent() const override
728bf80f4bSopenharmony_ci    {
738bf80f4bSopenharmony_ci        return parent_.lock();
748bf80f4bSopenharmony_ci    }
758bf80f4bSopenharmony_ci
768bf80f4bSopenharmony_ciprotected: // IMutableContainable
778bf80f4bSopenharmony_ci    void SetParent(const IObject::Ptr& parent) override
788bf80f4bSopenharmony_ci    {
798bf80f4bSopenharmony_ci        parent_ = parent;
808bf80f4bSopenharmony_ci    }
818bf80f4bSopenharmony_ci
828bf80f4bSopenharmony_ciprotected: // INamed
838bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(INamed, BASE_NS::string, Name)
848bf80f4bSopenharmony_ci
858bf80f4bSopenharmony_ciprotected: // IAttach
868bf80f4bSopenharmony_ci    bool Attach(const IObject::Ptr& attachment, const IObject::Ptr& dataContext) override
878bf80f4bSopenharmony_ci    {
888bf80f4bSopenharmony_ci        return GetState().Attach(attachment, dataContext);
898bf80f4bSopenharmony_ci    }
908bf80f4bSopenharmony_ci    bool Detach(const IObject::Ptr& attachment) override
918bf80f4bSopenharmony_ci    {
928bf80f4bSopenharmony_ci        return GetState().Detach(attachment);
938bf80f4bSopenharmony_ci    }
948bf80f4bSopenharmony_ci
958bf80f4bSopenharmony_ciprotected: // IAnimationInternal
968bf80f4bSopenharmony_ci    void ResetClock() override
978bf80f4bSopenharmony_ci    {
988bf80f4bSopenharmony_ci        GetState().ResetClock();
998bf80f4bSopenharmony_ci    }
1008bf80f4bSopenharmony_ci
1018bf80f4bSopenharmony_ci    bool Move(const IAnimationInternal::MoveParams& move) override
1028bf80f4bSopenharmony_ci    {
1038bf80f4bSopenharmony_ci        return GetState().Move(move).changed;
1048bf80f4bSopenharmony_ci    }
1058bf80f4bSopenharmony_ci
1068bf80f4bSopenharmony_ci    void OnAnimationStateChanged(const IAnimationInternal::AnimationStateChangedInfo& info) override
1078bf80f4bSopenharmony_ci    {
1088bf80f4bSopenharmony_ci        Evaluate();
1098bf80f4bSopenharmony_ci    }
1108bf80f4bSopenharmony_ci    void OnEvaluationNeeded() override
1118bf80f4bSopenharmony_ci    {
1128bf80f4bSopenharmony_ci        Evaluate();
1138bf80f4bSopenharmony_ci    }
1148bf80f4bSopenharmony_ci
1158bf80f4bSopenharmony_ciprotected: // IAttachment
1168bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IObject::WeakPtr, DataContext)
1178bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAttachment, IAttach::WeakPtr, AttachedTo)
1188bf80f4bSopenharmony_ci    bool Attaching(const IAttach::Ptr& target, const IObject::Ptr& dataContext) override
1198bf80f4bSopenharmony_ci    {
1208bf80f4bSopenharmony_ci        SetValue(META_ACCESS_PROPERTY(AttachedTo), target);
1218bf80f4bSopenharmony_ci        SetValue(META_ACCESS_PROPERTY(DataContext), dataContext);
1228bf80f4bSopenharmony_ci        return true;
1238bf80f4bSopenharmony_ci    }
1248bf80f4bSopenharmony_ci    bool Detaching(const IAttach::Ptr& target) override
1258bf80f4bSopenharmony_ci    {
1268bf80f4bSopenharmony_ci        SetValue(META_ACCESS_PROPERTY(AttachedTo), {});
1278bf80f4bSopenharmony_ci        SetValue(META_ACCESS_PROPERTY(DataContext), {});
1288bf80f4bSopenharmony_ci        return true;
1298bf80f4bSopenharmony_ci    }
1308bf80f4bSopenharmony_ci
1318bf80f4bSopenharmony_ciprotected: // IAnimation
1328bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, bool, Enabled, true)
1338bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Valid, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
1348bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, TimeSpan, TotalDuration, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
1358bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, bool, Running, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
1368bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(IAnimation, float, Progress, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
1378bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(
1388bf80f4bSopenharmony_ci        IAnimation, IAnimationController::WeakPtr, Controller, {}, DEFAULT_PROPERTY_FLAGS_NO_SER)
1398bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IAnimation, ICurve1D::Ptr, Curve)
1408bf80f4bSopenharmony_ci    void Step(const IClock::ConstPtr& clock) override
1418bf80f4bSopenharmony_ci    {
1428bf80f4bSopenharmony_ci        GetState().Step(clock);
1438bf80f4bSopenharmony_ci    }
1448bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_EVENT(IAnimation, IOnChanged, OnFinished)
1458bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_EVENT(IAnimation, IOnChanged, OnStarted)
1468bf80f4bSopenharmony_ci
1478bf80f4bSopenharmony_ciprotected: // INotifyOnChange
1488bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_EVENT(INotifyOnChange, IOnChanged, OnChanged)
1498bf80f4bSopenharmony_ci
1508bf80f4bSopenharmony_ci    void NotifyChanged()
1518bf80f4bSopenharmony_ci    {
1528bf80f4bSopenharmony_ci        META_ACCESS_EVENT(OnChanged)->Invoke();
1538bf80f4bSopenharmony_ci    }
1548bf80f4bSopenharmony_ci
1558bf80f4bSopenharmony_ciprotected:
1568bf80f4bSopenharmony_ci    virtual void Evaluate() = 0;
1578bf80f4bSopenharmony_ci    virtual Internal::AnimationState& GetState() noexcept = 0;
1588bf80f4bSopenharmony_ci
1598bf80f4bSopenharmony_ciprivate:
1608bf80f4bSopenharmony_ci    IObject::WeakPtr parent_;
1618bf80f4bSopenharmony_ci};
1628bf80f4bSopenharmony_ci
1638bf80f4bSopenharmony_citemplate<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
1648bf80f4bSopenharmony_ciclass BaseStartableAnimationFwd
1658bf80f4bSopenharmony_ci    : public BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IStartableAnimation, Interfaces...> {
1668bf80f4bSopenharmony_ci    using Super = BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IStartableAnimation, Interfaces...>;
1678bf80f4bSopenharmony_ci    using Super::GetState;
1688bf80f4bSopenharmony_ci
1698bf80f4bSopenharmony_ciprotected: // IStartableAnimation
1708bf80f4bSopenharmony_ci    void Pause() override
1718bf80f4bSopenharmony_ci    {
1728bf80f4bSopenharmony_ci        GetState().Pause();
1738bf80f4bSopenharmony_ci    }
1748bf80f4bSopenharmony_ci    void Restart() override
1758bf80f4bSopenharmony_ci    {
1768bf80f4bSopenharmony_ci        GetState().Restart();
1778bf80f4bSopenharmony_ci    }
1788bf80f4bSopenharmony_ci    void Seek(float position) override
1798bf80f4bSopenharmony_ci    {
1808bf80f4bSopenharmony_ci        GetState().Seek(position);
1818bf80f4bSopenharmony_ci    }
1828bf80f4bSopenharmony_ci    void Start() override
1838bf80f4bSopenharmony_ci    {
1848bf80f4bSopenharmony_ci        GetState().Start();
1858bf80f4bSopenharmony_ci    }
1868bf80f4bSopenharmony_ci    void Stop() override
1878bf80f4bSopenharmony_ci    {
1888bf80f4bSopenharmony_ci        GetState().Stop();
1898bf80f4bSopenharmony_ci    }
1908bf80f4bSopenharmony_ci    void Finish() override
1918bf80f4bSopenharmony_ci    {
1928bf80f4bSopenharmony_ci        GetState().Finish();
1938bf80f4bSopenharmony_ci    }
1948bf80f4bSopenharmony_ci};
1958bf80f4bSopenharmony_ci
1968bf80f4bSopenharmony_ci/**
1978bf80f4bSopenharmony_ci * @brief A base class which can be used by animation container implementations.
1988bf80f4bSopenharmony_ci */
1998bf80f4bSopenharmony_citemplate<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
2008bf80f4bSopenharmony_ciclass BaseAnimationContainerFwd : public BaseStartableAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface,
2018bf80f4bSopenharmony_ci                                      IContainer, ILockable, IIterable, IImportFinalize, Interfaces...> {
2028bf80f4bSopenharmony_ci    static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, IStaggeredAnimation*>,
2038bf80f4bSopenharmony_ci        "BaseAnimationInterface of BaseAnimationContainerFwd must inherit from IStaggeredAnimation");
2048bf80f4bSopenharmony_ci    using Super = BaseStartableAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IContainer, ILockable,
2058bf80f4bSopenharmony_ci        IIterable, IImportFinalize, Interfaces...>;
2068bf80f4bSopenharmony_ci    using IContainer::SizeType;
2078bf80f4bSopenharmony_ci
2088bf80f4bSopenharmony_cipublic: // ILockable
2098bf80f4bSopenharmony_ci    void Lock() const override
2108bf80f4bSopenharmony_ci    {
2118bf80f4bSopenharmony_ci        if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
2128bf80f4bSopenharmony_ci            lockable->Lock();
2138bf80f4bSopenharmony_ci        }
2148bf80f4bSopenharmony_ci    }
2158bf80f4bSopenharmony_ci    void Unlock() const override
2168bf80f4bSopenharmony_ci    {
2178bf80f4bSopenharmony_ci        if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
2188bf80f4bSopenharmony_ci            lockable->Unlock();
2198bf80f4bSopenharmony_ci        }
2208bf80f4bSopenharmony_ci    }
2218bf80f4bSopenharmony_ci    void LockShared() const override
2228bf80f4bSopenharmony_ci    {
2238bf80f4bSopenharmony_ci        if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
2248bf80f4bSopenharmony_ci            lockable->LockShared();
2258bf80f4bSopenharmony_ci        }
2268bf80f4bSopenharmony_ci    }
2278bf80f4bSopenharmony_ci    void UnlockShared() const override
2288bf80f4bSopenharmony_ci    {
2298bf80f4bSopenharmony_ci        if (auto lockable = interface_cast<ILockable>(&GetContainer())) {
2308bf80f4bSopenharmony_ci            lockable->UnlockShared();
2318bf80f4bSopenharmony_ci        }
2328bf80f4bSopenharmony_ci    }
2338bf80f4bSopenharmony_ci
2348bf80f4bSopenharmony_ciprotected:
2358bf80f4bSopenharmony_ci    Internal::StaggeredAnimationState& GetState() noexcept override = 0;
2368bf80f4bSopenharmony_ci
2378bf80f4bSopenharmony_ci    ReturnError Finalize(IImportFunctions&) override
2388bf80f4bSopenharmony_ci    {
2398bf80f4bSopenharmony_ci        GetState().ChildrenChanged();
2408bf80f4bSopenharmony_ci        return GenericError::SUCCESS;
2418bf80f4bSopenharmony_ci    }
2428bf80f4bSopenharmony_ci
2438bf80f4bSopenharmony_cipublic: // IIterable
2448bf80f4bSopenharmony_ci    IterationResult Iterate(const IterationParameters& params) override
2458bf80f4bSopenharmony_ci    {
2468bf80f4bSopenharmony_ci        auto iterable = interface_cast<IIterable>(&GetContainer());
2478bf80f4bSopenharmony_ci        return iterable ? iterable->Iterate(params) : IterationResult::FAILED;
2488bf80f4bSopenharmony_ci    }
2498bf80f4bSopenharmony_ci    IterationResult Iterate(const IterationParameters& params) const override
2508bf80f4bSopenharmony_ci    {
2518bf80f4bSopenharmony_ci        const auto iterable = interface_cast<IIterable>(&GetContainer());
2528bf80f4bSopenharmony_ci        return iterable ? iterable->Iterate(params) : IterationResult::FAILED;
2538bf80f4bSopenharmony_ci    }
2548bf80f4bSopenharmony_ci
2558bf80f4bSopenharmony_cipublic: // IContainer
2568bf80f4bSopenharmony_ci    bool Add(const IObject::Ptr& object) override
2578bf80f4bSopenharmony_ci    {
2588bf80f4bSopenharmony_ci        return GetContainer().Add(object);
2598bf80f4bSopenharmony_ci    }
2608bf80f4bSopenharmony_ci    bool Insert(SizeType index, const IObject::Ptr& object) override
2618bf80f4bSopenharmony_ci    {
2628bf80f4bSopenharmony_ci        return GetContainer().Insert(index, object);
2638bf80f4bSopenharmony_ci    }
2648bf80f4bSopenharmony_ci    bool Remove(SizeType index) override
2658bf80f4bSopenharmony_ci    {
2668bf80f4bSopenharmony_ci        return GetContainer().Remove(index);
2678bf80f4bSopenharmony_ci    }
2688bf80f4bSopenharmony_ci    bool Remove(const IObject::Ptr& child) override
2698bf80f4bSopenharmony_ci    {
2708bf80f4bSopenharmony_ci        return GetContainer().Remove(child);
2718bf80f4bSopenharmony_ci    }
2728bf80f4bSopenharmony_ci    bool Move(SizeType fromIndex, SizeType toIndex) override
2738bf80f4bSopenharmony_ci    {
2748bf80f4bSopenharmony_ci        return GetContainer().Move(fromIndex, toIndex);
2758bf80f4bSopenharmony_ci    }
2768bf80f4bSopenharmony_ci    bool Move(const IObject::Ptr& child, SizeType toIndex) override
2778bf80f4bSopenharmony_ci    {
2788bf80f4bSopenharmony_ci        return GetContainer().Move(child, toIndex);
2798bf80f4bSopenharmony_ci    }
2808bf80f4bSopenharmony_ci    bool Replace(const IObject::Ptr& child, const IObject::Ptr& replaceWith, bool addAlways) override
2818bf80f4bSopenharmony_ci    {
2828bf80f4bSopenharmony_ci        return GetContainer().Replace(child, replaceWith, addAlways);
2838bf80f4bSopenharmony_ci    }
2848bf80f4bSopenharmony_ci    BASE_NS::vector<IObject::Ptr> GetAll() const override
2858bf80f4bSopenharmony_ci    {
2868bf80f4bSopenharmony_ci        return GetContainer().GetAll();
2878bf80f4bSopenharmony_ci    }
2888bf80f4bSopenharmony_ci    void RemoveAll() override
2898bf80f4bSopenharmony_ci    {
2908bf80f4bSopenharmony_ci        GetContainer().RemoveAll();
2918bf80f4bSopenharmony_ci    }
2928bf80f4bSopenharmony_ci    IObject::Ptr GetAt(SizeType index) const override
2938bf80f4bSopenharmony_ci    {
2948bf80f4bSopenharmony_ci        return GetContainer().GetAt(index);
2958bf80f4bSopenharmony_ci    }
2968bf80f4bSopenharmony_ci    SizeType GetSize() const override
2978bf80f4bSopenharmony_ci    {
2988bf80f4bSopenharmony_ci        return GetContainer().GetSize();
2998bf80f4bSopenharmony_ci    }
3008bf80f4bSopenharmony_ci    BASE_NS::vector<IObject::Ptr> FindAll(const IContainer::FindOptions& options) const override
3018bf80f4bSopenharmony_ci    {
3028bf80f4bSopenharmony_ci        return GetContainer().FindAll(options);
3038bf80f4bSopenharmony_ci    }
3048bf80f4bSopenharmony_ci    IObject::Ptr FindAny(const IContainer::FindOptions& options) const override
3058bf80f4bSopenharmony_ci    {
3068bf80f4bSopenharmony_ci        return GetContainer().FindAny(options);
3078bf80f4bSopenharmony_ci    }
3088bf80f4bSopenharmony_ci    IObject::Ptr FindByName(BASE_NS::string_view name) const override
3098bf80f4bSopenharmony_ci    {
3108bf80f4bSopenharmony_ci        return GetContainer().FindByName(name);
3118bf80f4bSopenharmony_ci    }
3128bf80f4bSopenharmony_ci    bool IsAncestorOf(const IObject::ConstPtr& object) const override
3138bf80f4bSopenharmony_ci    {
3148bf80f4bSopenharmony_ci        return GetContainer().IsAncestorOf(object);
3158bf80f4bSopenharmony_ci    }
3168bf80f4bSopenharmony_ci
3178bf80f4bSopenharmony_ci    META_FORWARD_EVENT(IOnChanged, OnAdded, GetContainer().EventOnAdded());
3188bf80f4bSopenharmony_ci    META_FORWARD_EVENT(IOnChanged, OnRemoved, GetContainer().EventOnRemoved());
3198bf80f4bSopenharmony_ci    META_FORWARD_EVENT(IOnChanged, OnMoved, GetContainer().EventOnMoved());
3208bf80f4bSopenharmony_ci
3218bf80f4bSopenharmony_ciprotected: // IStaggeredAnimation
3228bf80f4bSopenharmony_ci    void AddAnimation(const IAnimation::Ptr& animation) override
3238bf80f4bSopenharmony_ci    {
3248bf80f4bSopenharmony_ci        GetContainer().Add(animation);
3258bf80f4bSopenharmony_ci    }
3268bf80f4bSopenharmony_ci    void RemoveAnimation(const IAnimation::Ptr& animation) override
3278bf80f4bSopenharmony_ci    {
3288bf80f4bSopenharmony_ci        GetContainer().Remove(animation);
3298bf80f4bSopenharmony_ci    }
3308bf80f4bSopenharmony_ci    BASE_NS::vector<IAnimation::Ptr> GetAnimations() const override
3318bf80f4bSopenharmony_ci    {
3328bf80f4bSopenharmony_ci        return GetContainer().template GetAll<IAnimation>();
3338bf80f4bSopenharmony_ci    }
3348bf80f4bSopenharmony_ci
3358bf80f4bSopenharmony_ciprotected:
3368bf80f4bSopenharmony_ci    virtual IContainer& GetContainer() noexcept = 0;
3378bf80f4bSopenharmony_ci    virtual const IContainer& GetContainer() const noexcept = 0;
3388bf80f4bSopenharmony_ci};
3398bf80f4bSopenharmony_ci
3408bf80f4bSopenharmony_ci/**
3418bf80f4bSopenharmony_ci * @brief A base class which can be used by property animation implementations.
3428bf80f4bSopenharmony_ci */
3438bf80f4bSopenharmony_citemplate<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
3448bf80f4bSopenharmony_ciclass BasePropertyAnimationFwd : public BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface,
3458bf80f4bSopenharmony_ci                                     IPropertyAnimation, IModifier, IImportFinalize, Interfaces...> {
3468bf80f4bSopenharmony_ci    static_assert(BASE_NS::is_convertible_v<BaseAnimationInterface*, ITimedAnimation*>,
3478bf80f4bSopenharmony_ci        "BaseAnimationInterface of BasePropertyAnimationFwd must inherit from ITimedAnimation");
3488bf80f4bSopenharmony_ci    using Super = BaseAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, IPropertyAnimation, IModifier,
3498bf80f4bSopenharmony_ci        IImportFinalize, Interfaces...>;
3508bf80f4bSopenharmony_ci
3518bf80f4bSopenharmony_ciprotected:
3528bf80f4bSopenharmony_ci    BasePropertyAnimationFwd() = default;
3538bf80f4bSopenharmony_ci    ~BasePropertyAnimationFwd() override = default;
3548bf80f4bSopenharmony_ci
3558bf80f4bSopenharmony_ciprotected: // ILifecycle
3568bf80f4bSopenharmony_ci    bool Build(const IMetadata::Ptr& data) override
3578bf80f4bSopenharmony_ci    {
3588bf80f4bSopenharmony_ci        if (Super::Build(data)) {
3598bf80f4bSopenharmony_ci            META_ACCESS_PROPERTY(Property)->OnChanged()->AddHandler(
3608bf80f4bSopenharmony_ci                MakeCallback<IOnChanged>(this, &BasePropertyAnimationFwd::PropertyChanged));
3618bf80f4bSopenharmony_ci            return true;
3628bf80f4bSopenharmony_ci        }
3638bf80f4bSopenharmony_ci        return false;
3648bf80f4bSopenharmony_ci    }
3658bf80f4bSopenharmony_ci
3668bf80f4bSopenharmony_ciprotected: // IPropertyAnimation
3678bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(IPropertyAnimation, IProperty::WeakPtr, Property);
3688bf80f4bSopenharmony_ci
3698bf80f4bSopenharmony_ciprotected: // ITimedAnimation
3708bf80f4bSopenharmony_ci    META_IMPLEMENT_INTERFACE_PROPERTY(ITimedAnimation, TimeSpan, Duration)
3718bf80f4bSopenharmony_ci
3728bf80f4bSopenharmony_ciprotected: // IModifier
3738bf80f4bSopenharmony_ci    EvaluationResult ProcessOnGet(IAny& value) override
3748bf80f4bSopenharmony_ci    {
3758bf80f4bSopenharmony_ci        return EvaluationResult::EVAL_CONTINUE;
3768bf80f4bSopenharmony_ci    }
3778bf80f4bSopenharmony_ci    EvaluationResult ProcessOnSet(IAny& value, const IAny& current) override
3788bf80f4bSopenharmony_ci    {
3798bf80f4bSopenharmony_ci        return EvaluationResult::EVAL_CONTINUE;
3808bf80f4bSopenharmony_ci    }
3818bf80f4bSopenharmony_ci    bool IsCompatible(const TypeId& id) const override
3828bf80f4bSopenharmony_ci    {
3838bf80f4bSopenharmony_ci        if (auto p = GetTargetProperty()) {
3848bf80f4bSopenharmony_ci            return META_NS::IsCompatible(p.property->GetValue(), id);
3858bf80f4bSopenharmony_ci        }
3868bf80f4bSopenharmony_ci        return false;
3878bf80f4bSopenharmony_ci    }
3888bf80f4bSopenharmony_ci    Internal::PropertyAnimationState& GetState() noexcept override = 0;
3898bf80f4bSopenharmony_ci
3908bf80f4bSopenharmony_ciprotected:
3918bf80f4bSopenharmony_ci    ReturnError Finalize(IImportFunctions&) override
3928bf80f4bSopenharmony_ci    {
3938bf80f4bSopenharmony_ci        GetState().UpdateTotalDuration();
3948bf80f4bSopenharmony_ci        auto p = GetTargetProperty();
3958bf80f4bSopenharmony_ci        GetState().SetInterpolator(p ? p.property->GetTypeId() : TypeId {});
3968bf80f4bSopenharmony_ci        SetValue(Super::META_ACCESS_PROPERTY(Valid), p);
3978bf80f4bSopenharmony_ci        return GenericError::SUCCESS;
3988bf80f4bSopenharmony_ci    }
3998bf80f4bSopenharmony_ci
4008bf80f4bSopenharmony_ciprotected:
4018bf80f4bSopenharmony_ci    struct TargetProperty {
4028bf80f4bSopenharmony_ci        IProperty::Ptr property;
4038bf80f4bSopenharmony_ci        IStackProperty::Ptr stack;
4048bf80f4bSopenharmony_ci        /* NOLINTNEXTLINE(google-explicit-constructor) */
4058bf80f4bSopenharmony_ci        operator bool() const noexcept
4068bf80f4bSopenharmony_ci        {
4078bf80f4bSopenharmony_ci            return property && stack;
4088bf80f4bSopenharmony_ci        }
4098bf80f4bSopenharmony_ci    };
4108bf80f4bSopenharmony_ci
4118bf80f4bSopenharmony_ci    void PropertyChanged()
4128bf80f4bSopenharmony_ci    {
4138bf80f4bSopenharmony_ci        auto p = GetTargetProperty();
4148bf80f4bSopenharmony_ci        this->GetState().SetInterpolator(p ? p.property->GetTypeId() : TypeId {});
4158bf80f4bSopenharmony_ci        SetValue(Super::META_ACCESS_PROPERTY(Valid), p);
4168bf80f4bSopenharmony_ci        OnPropertyChanged(p, property_.lock());
4178bf80f4bSopenharmony_ci        property_ = p.stack;
4188bf80f4bSopenharmony_ci    }
4198bf80f4bSopenharmony_ci
4208bf80f4bSopenharmony_ci    virtual void OnPropertyChanged(const TargetProperty& property, const IStackProperty::Ptr& previous) = 0;
4218bf80f4bSopenharmony_ci
4228bf80f4bSopenharmony_ci    TargetProperty GetTargetProperty() const noexcept
4238bf80f4bSopenharmony_ci    {
4248bf80f4bSopenharmony_ci        auto p = META_ACCESS_PROPERTY_VALUE(Property).lock();
4258bf80f4bSopenharmony_ci        return { p, interface_pointer_cast<IStackProperty>(p) };
4268bf80f4bSopenharmony_ci    }
4278bf80f4bSopenharmony_ci
4288bf80f4bSopenharmony_ciprivate:
4298bf80f4bSopenharmony_ci    IStackProperty::WeakPtr property_;
4308bf80f4bSopenharmony_ci};
4318bf80f4bSopenharmony_ci
4328bf80f4bSopenharmony_ci/**
4338bf80f4bSopenharmony_ci * @brief A base class which can be used by property animation implementations.
4348bf80f4bSopenharmony_ci */
4358bf80f4bSopenharmony_citemplate<class FinalClass, const META_NS::ClassInfo& ClassInfo, class BaseAnimationInterface, class... Interfaces>
4368bf80f4bSopenharmony_ciclass PropertyAnimationFwd
4378bf80f4bSopenharmony_ci    : public BasePropertyAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, Interfaces...> {
4388bf80f4bSopenharmony_ci    using Super = BasePropertyAnimationFwd<FinalClass, ClassInfo, BaseAnimationInterface, Interfaces...>;
4398bf80f4bSopenharmony_ci
4408bf80f4bSopenharmony_ciprotected:
4418bf80f4bSopenharmony_ci    PropertyAnimationFwd() = default;
4428bf80f4bSopenharmony_ci    ~PropertyAnimationFwd() override = default;
4438bf80f4bSopenharmony_ci
4448bf80f4bSopenharmony_ciprotected:
4458bf80f4bSopenharmony_ci    // Note covariance
4468bf80f4bSopenharmony_ci    Internal::PropertyAnimationState& GetState() noexcept override
4478bf80f4bSopenharmony_ci    {
4488bf80f4bSopenharmony_ci        return state_;
4498bf80f4bSopenharmony_ci    }
4508bf80f4bSopenharmony_ci
4518bf80f4bSopenharmony_ciprivate:
4528bf80f4bSopenharmony_ci    Internal::PropertyAnimationState state_;
4538bf80f4bSopenharmony_ci};
4548bf80f4bSopenharmony_ci
4558bf80f4bSopenharmony_ci} // namespace Internal
4568bf80f4bSopenharmony_ci
4578bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
4588bf80f4bSopenharmony_ci
4598bf80f4bSopenharmony_ci#endif // META_SRC_ANIMATION_H
460