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 168bf80f4bSopenharmony_ci#ifndef META_SRC_ANIMATION_STATE_H 178bf80f4bSopenharmony_ci#define META_SRC_ANIMATION_STATE_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <optional> 208bf80f4bSopenharmony_ci 218bf80f4bSopenharmony_ci#include <meta/api/container/find_cache.h> 228bf80f4bSopenharmony_ci#include <meta/ext/implementation_macros.h> 238bf80f4bSopenharmony_ci#include <meta/interface/animation/intf_animation.h> 248bf80f4bSopenharmony_ci#include <meta/interface/animation/intf_animation_modifier.h> 258bf80f4bSopenharmony_ci#include <meta/interface/intf_any.h> 268bf80f4bSopenharmony_ci#include <meta/interface/intf_attachment.h> 278bf80f4bSopenharmony_ci#include <meta/interface/intf_container.h> 288bf80f4bSopenharmony_ci#include <meta/interface/intf_manual_clock.h> 298bf80f4bSopenharmony_ci#include <meta/interface/property/property_events.h> 308bf80f4bSopenharmony_ci 318bf80f4bSopenharmony_ci#include "intf_animation_internal.h" 328bf80f4bSopenharmony_ci 338bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE() 348bf80f4bSopenharmony_ci 358bf80f4bSopenharmony_cinamespace Internal { 368bf80f4bSopenharmony_ci 378bf80f4bSopenharmony_ci/** 388bf80f4bSopenharmony_ci * @brief Base animation state implementation, handles animation state, evaluation. 398bf80f4bSopenharmony_ci */ 408bf80f4bSopenharmony_ciclass AnimationState { 418bf80f4bSopenharmony_cipublic: 428bf80f4bSopenharmony_ci AnimationState() = default; 438bf80f4bSopenharmony_ci ~AnimationState() = default; 448bf80f4bSopenharmony_ci META_NO_COPY_MOVE(AnimationState) 458bf80f4bSopenharmony_ci 468bf80f4bSopenharmony_cipublic: 478bf80f4bSopenharmony_ci struct AnimationStateParams { 488bf80f4bSopenharmony_ci /** Owning animation */ 498bf80f4bSopenharmony_ci IAnimation::WeakPtr owner; 508bf80f4bSopenharmony_ci /** Writeable IAnimation::Running property */ 518bf80f4bSopenharmony_ci Property<bool> runningProperty; 528bf80f4bSopenharmony_ci /** Writeable IAnimation::Progress property */ 538bf80f4bSopenharmony_ci Property<float> progressProperty; 548bf80f4bSopenharmony_ci /** Writeable IAnimation::TotalDuration property */ 558bf80f4bSopenharmony_ci Property<TimeSpan> totalDuration; 568bf80f4bSopenharmony_ci }; 578bf80f4bSopenharmony_ci 588bf80f4bSopenharmony_ci /** 598bf80f4bSopenharmony_ci * @brief Initialize AnimationState. 608bf80f4bSopenharmony_ci * @param owner Owning animation for AnimationState. 618bf80f4bSopenharmony_ci */ 628bf80f4bSopenharmony_ci virtual bool Initialize(AnimationStateParams&& params); 638bf80f4bSopenharmony_ci /** 648bf80f4bSopenharmony_ci * @brief Uninitializes the state object. 658bf80f4bSopenharmony_ci */ 668bf80f4bSopenharmony_ci virtual void Uninitialize(); 678bf80f4bSopenharmony_ci /** Result of a step operation */ 688bf80f4bSopenharmony_ci struct StepStatus { 698bf80f4bSopenharmony_ci IAnimationInternal::AnimationTargetState state { IAnimationInternal::AnimationTargetState::UNDEFINED }; 708bf80f4bSopenharmony_ci float progress {}; 718bf80f4bSopenharmony_ci bool changed {}; 728bf80f4bSopenharmony_ci 738bf80f4bSopenharmony_ci constexpr bool StatusChanged() const noexcept 748bf80f4bSopenharmony_ci { 758bf80f4bSopenharmony_ci return changed; 768bf80f4bSopenharmony_ci } 778bf80f4bSopenharmony_ci }; 788bf80f4bSopenharmony_ci /** 798bf80f4bSopenharmony_ci * @brief Step the state based on clock. 808bf80f4bSopenharmony_ci * @param clock Clock containing the step time. 818bf80f4bSopenharmony_ci */ 828bf80f4bSopenharmony_ci virtual StepStatus Step(const IClock::ConstPtr& clock); 838bf80f4bSopenharmony_ci /** 848bf80f4bSopenharmony_ci * @brief Seeks the animation state to given position [0,1] 858bf80f4bSopenharmony_ci */ 868bf80f4bSopenharmony_ci virtual void Seek(float position); 878bf80f4bSopenharmony_ci /** 888bf80f4bSopenharmony_ci * @brief Pauses the animation. Returns true if state changed. 898bf80f4bSopenharmony_ci */ 908bf80f4bSopenharmony_ci virtual bool Pause(); 918bf80f4bSopenharmony_ci /** 928bf80f4bSopenharmony_ci * @brief Starts the animation. Returns true if state changed. 938bf80f4bSopenharmony_ci */ 948bf80f4bSopenharmony_ci virtual bool Start(); 958bf80f4bSopenharmony_ci /** 968bf80f4bSopenharmony_ci * @brief Stops the animation. Returns true if state changed. 978bf80f4bSopenharmony_ci */ 988bf80f4bSopenharmony_ci virtual bool Stop(); 998bf80f4bSopenharmony_ci /** 1008bf80f4bSopenharmony_ci * @brief Restarts the animation. Returns true if state changed. 1018bf80f4bSopenharmony_ci */ 1028bf80f4bSopenharmony_ci virtual bool Restart(); 1038bf80f4bSopenharmony_ci /** 1048bf80f4bSopenharmony_ci * @brief Finishes the animation. Returns true if state changed. 1058bf80f4bSopenharmony_ci */ 1068bf80f4bSopenharmony_ci virtual bool Finish(); 1078bf80f4bSopenharmony_ci /** 1088bf80f4bSopenharmony_ci * @brief Returns true if the animation is running. 1098bf80f4bSopenharmony_ci */ 1108bf80f4bSopenharmony_ci bool IsRunning() const noexcept; 1118bf80f4bSopenharmony_ci /** 1128bf80f4bSopenharmony_ci * @brief REturns true if the animation is paused. 1138bf80f4bSopenharmony_ci */ 1148bf80f4bSopenharmony_ci bool IsPaused() const noexcept; 1158bf80f4bSopenharmony_ci /** 1168bf80f4bSopenharmony_ci * @brief Returns the current progress of the animation. 1178bf80f4bSopenharmony_ci */ 1188bf80f4bSopenharmony_ci float GetProgress() const noexcept; 1198bf80f4bSopenharmony_ci /** 1208bf80f4bSopenharmony_ci * @brief Move the animation to a requested step position 1218bf80f4bSopenharmony_ci * @param step 1228bf80f4bSopenharmony_ci * @param state 1238bf80f4bSopenharmony_ci * @return 1248bf80f4bSopenharmony_ci */ 1258bf80f4bSopenharmony_ci StepStatus Move(const IAnimationInternal::MoveParams& move); 1268bf80f4bSopenharmony_ci /** 1278bf80f4bSopenharmony_ci * @brief Resets to the animation clock to initial state, even if the animation is running. 1288bf80f4bSopenharmony_ci */ 1298bf80f4bSopenharmony_ci void ResetClock(); 1308bf80f4bSopenharmony_ci 1318bf80f4bSopenharmony_cipublic: 1328bf80f4bSopenharmony_ci BASE_NS::vector<IAnimationModifier::Ptr> GetModifiers() const; 1338bf80f4bSopenharmony_ci bool Attach(const IObject::Ptr& attachment, const IObject::Ptr& dataContext); 1348bf80f4bSopenharmony_ci bool Detach(const IObject::Ptr& attachment); 1358bf80f4bSopenharmony_ci 1368bf80f4bSopenharmony_ci virtual void UpdateTotalDuration(); 1378bf80f4bSopenharmony_ci 1388bf80f4bSopenharmony_ciprotected: 1398bf80f4bSopenharmony_ci virtual TimeSpan GetAnimationBaseDuration() const; 1408bf80f4bSopenharmony_ci 1418bf80f4bSopenharmony_ciprotected: 1428bf80f4bSopenharmony_ci AnimationStateParams& GetParams() 1438bf80f4bSopenharmony_ci { 1448bf80f4bSopenharmony_ci return params_; 1458bf80f4bSopenharmony_ci } 1468bf80f4bSopenharmony_ci 1478bf80f4bSopenharmony_ci constexpr IAnimationInternal::AnimationTargetState GetAnimationTargetState() const noexcept 1488bf80f4bSopenharmony_ci { 1498bf80f4bSopenharmony_ci return state_.animationState_; 1508bf80f4bSopenharmony_ci } 1518bf80f4bSopenharmony_ci 1528bf80f4bSopenharmony_ci /** Return the owning animation of this state object */ 1538bf80f4bSopenharmony_ci IAnimation::Ptr GetOwner() const noexcept; 1548bf80f4bSopenharmony_ci /** Returns a duration with all modifiers applied */ 1558bf80f4bSopenharmony_ci IAnimationModifier::DurationData ApplyDurationModifiers(TimeSpan duration) const; 1568bf80f4bSopenharmony_ci /** Returns step data with all modifiers applied */ 1578bf80f4bSopenharmony_ci IAnimationModifier::StepData ApplyStepModifiers(float progress) const; 1588bf80f4bSopenharmony_ci 1598bf80f4bSopenharmony_ciprivate: 1608bf80f4bSopenharmony_ci void NotifyEvaluationNeeded() const; 1618bf80f4bSopenharmony_ci void NotifyStateChanged(const IAnimationInternal::AnimationStateChangedInfo& info) const; 1628bf80f4bSopenharmony_ci void UpdateController(); 1638bf80f4bSopenharmony_ci bool SetState(IAnimationInternal::AnimationTargetState state); 1648bf80f4bSopenharmony_ci void SetRunning(bool running) noexcept; 1658bf80f4bSopenharmony_ci void SetProgress(float progress) noexcept; 1668bf80f4bSopenharmony_ci 1678bf80f4bSopenharmony_ciprivate: 1688bf80f4bSopenharmony_ci IAnimationController::WeakPtr controller_; // Animation's controller 1698bf80f4bSopenharmony_ci IOnChanged::InterfaceTypePtr updateTotalDuration_; // Callback function for total duration update 1708bf80f4bSopenharmony_ci AnimationStateParams params_; // Animation parameters 1718bf80f4bSopenharmony_ci struct StateData { 1728bf80f4bSopenharmony_ci int32_t loops { 1 }; 1738bf80f4bSopenharmony_ci TimeSpan totalDuration; 1748bf80f4bSopenharmony_ci IAnimationModifier::DurationData duration; 1758bf80f4bSopenharmony_ci bool shouldInit_ { false }; 1768bf80f4bSopenharmony_ci IManualClock::Ptr clock_; 1778bf80f4bSopenharmony_ci std::optional<META_NS::TimeSpan> lastTick_; 1788bf80f4bSopenharmony_ci IAnimationInternal::AnimationTargetState animationState_ { IAnimationInternal::AnimationTargetState::STOPPED }; 1798bf80f4bSopenharmony_ci 1808bf80f4bSopenharmony_ci void ResetLastTick() noexcept 1818bf80f4bSopenharmony_ci { 1828bf80f4bSopenharmony_ci lastTick_.reset(); 1838bf80f4bSopenharmony_ci } 1848bf80f4bSopenharmony_ci void SetTime(const TimeSpan& time) 1858bf80f4bSopenharmony_ci { 1868bf80f4bSopenharmony_ci clock_->SetTime(time); 1878bf80f4bSopenharmony_ci } 1888bf80f4bSopenharmony_ci TimeSpan Tick(const TimeSpan& time) 1898bf80f4bSopenharmony_ci { 1908bf80f4bSopenharmony_ci clock_->IncrementTime(GetElapsed(time)); 1918bf80f4bSopenharmony_ci lastTick_ = time; 1928bf80f4bSopenharmony_ci return clock_->GetTime(); 1938bf80f4bSopenharmony_ci } 1948bf80f4bSopenharmony_ci TimeSpan GetCurrentTime() const 1958bf80f4bSopenharmony_ci { 1968bf80f4bSopenharmony_ci return clock_->GetTime(); 1978bf80f4bSopenharmony_ci } 1988bf80f4bSopenharmony_ci constexpr TimeSpan GetElapsed(const TimeSpan& time) const noexcept 1998bf80f4bSopenharmony_ci { 2008bf80f4bSopenharmony_ci return lastTick_ ? time - *lastTick_ : TimeSpan::Zero(); 2018bf80f4bSopenharmony_ci } 2028bf80f4bSopenharmony_ci constexpr TimeSpan GetBaseDuration() const noexcept 2038bf80f4bSopenharmony_ci { 2048bf80f4bSopenharmony_ci return duration.duration; 2058bf80f4bSopenharmony_ci } 2068bf80f4bSopenharmony_ci 2078bf80f4bSopenharmony_ci } state_; // State data 2088bf80f4bSopenharmony_ci mutable FindCache<IAnimationModifier> modifierCache_; // Cached modifier query 2098bf80f4bSopenharmony_ci}; 2108bf80f4bSopenharmony_ci 2118bf80f4bSopenharmony_ci/** 2128bf80f4bSopenharmony_ci * @brief State class implementation for animation targeting a single property. 2138bf80f4bSopenharmony_ci */ 2148bf80f4bSopenharmony_ciclass PropertyAnimationState : public AnimationState { 2158bf80f4bSopenharmony_ci using Super = AnimationState; 2168bf80f4bSopenharmony_ci 2178bf80f4bSopenharmony_cipublic: 2188bf80f4bSopenharmony_ci PropertyAnimationState() = default; 2198bf80f4bSopenharmony_ci ~PropertyAnimationState() = default; 2208bf80f4bSopenharmony_ci 2218bf80f4bSopenharmony_ci /** 2228bf80f4bSopenharmony_ci * @brief Data needed for evaluating an animation state. 2238bf80f4bSopenharmony_ci */ 2248bf80f4bSopenharmony_ci struct EvaluationData { 2258bf80f4bSopenharmony_ci /** Target value */ 2268bf80f4bSopenharmony_ci const IAny::Ptr target; 2278bf80f4bSopenharmony_ci /** Start of interpolation range */ 2288bf80f4bSopenharmony_ci const IAny::Ptr from; 2298bf80f4bSopenharmony_ci /** End of interpolation range */ 2308bf80f4bSopenharmony_ci const IAny::Ptr to; 2318bf80f4bSopenharmony_ci /** Linear animation progress [0,1] */ 2328bf80f4bSopenharmony_ci float progress; 2338bf80f4bSopenharmony_ci /** The (optional) curve to use for transforming the progress value */ 2348bf80f4bSopenharmony_ci const ICurve1D::Ptr curve; 2358bf80f4bSopenharmony_ci /** Returns true if the data is valid */ 2368bf80f4bSopenharmony_ci inline bool IsValid() const noexcept 2378bf80f4bSopenharmony_ci { 2388bf80f4bSopenharmony_ci return target && from && to; 2398bf80f4bSopenharmony_ci } 2408bf80f4bSopenharmony_ci }; 2418bf80f4bSopenharmony_ci /** 2428bf80f4bSopenharmony_ci * @brief Initialize state object's internal interpolator to support given type id. 2438bf80f4bSopenharmony_ci */ 2448bf80f4bSopenharmony_ci bool SetInterpolator(const TypeId& id); 2458bf80f4bSopenharmony_ci /** 2468bf80f4bSopenharmony_ci * @brief Return the interpolator initialized with SetInterpolator. 2478bf80f4bSopenharmony_ci */ 2488bf80f4bSopenharmony_ci IInterpolator::Ptr GetInterpolator() const; 2498bf80f4bSopenharmony_ci /** 2508bf80f4bSopenharmony_ci * @brief Evaluates target value between [from,to] based on state. 2518bf80f4bSopenharmony_ci * @param data Evaluation data. 2528bf80f4bSopenharmony_ci */ 2538bf80f4bSopenharmony_ci AnyReturnValue EvaluateValue(const EvaluationData& data) const; 2548bf80f4bSopenharmony_ci 2558bf80f4bSopenharmony_ciprivate: 2568bf80f4bSopenharmony_ci IInterpolator::Ptr interpolator_; 2578bf80f4bSopenharmony_ci}; 2588bf80f4bSopenharmony_ci 2598bf80f4bSopenharmony_ci} // namespace Internal 2608bf80f4bSopenharmony_ci 2618bf80f4bSopenharmony_ciMETA_END_NAMESPACE() 2628bf80f4bSopenharmony_ci 2638bf80f4bSopenharmony_ci#endif // META_SRC_ANIMATION_STATE_H 264