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_SRC_ANIMATION_STATE_H 17 #define META_SRC_ANIMATION_STATE_H 18 19 #include <optional> 20 21 #include <meta/api/container/find_cache.h> 22 #include <meta/ext/implementation_macros.h> 23 #include <meta/interface/animation/intf_animation.h> 24 #include <meta/interface/animation/intf_animation_modifier.h> 25 #include <meta/interface/intf_any.h> 26 #include <meta/interface/intf_attachment.h> 27 #include <meta/interface/intf_container.h> 28 #include <meta/interface/intf_manual_clock.h> 29 #include <meta/interface/property/property_events.h> 30 31 #include "intf_animation_internal.h" 32 33 META_BEGIN_NAMESPACE() 34 35 namespace Internal { 36 37 /** 38 * @brief Base animation state implementation, handles animation state, evaluation. 39 */ 40 class AnimationState { 41 public: 42 AnimationState() = default; 43 ~AnimationState() = default; 44 META_NO_COPY_MOVE(AnimationState) 45 46 public: 47 struct AnimationStateParams { 48 /** Owning animation */ 49 IAnimation::WeakPtr owner; 50 /** Writeable IAnimation::Running property */ 51 Property<bool> runningProperty; 52 /** Writeable IAnimation::Progress property */ 53 Property<float> progressProperty; 54 /** Writeable IAnimation::TotalDuration property */ 55 Property<TimeSpan> totalDuration; 56 }; 57 58 /** 59 * @brief Initialize AnimationState. 60 * @param owner Owning animation for AnimationState. 61 */ 62 virtual bool Initialize(AnimationStateParams&& params); 63 /** 64 * @brief Uninitializes the state object. 65 */ 66 virtual void Uninitialize(); 67 /** Result of a step operation */ 68 struct StepStatus { 69 IAnimationInternal::AnimationTargetState state { IAnimationInternal::AnimationTargetState::UNDEFINED }; 70 float progress {}; 71 bool changed {}; 72 73 constexpr bool StatusChanged() const noexcept 74 { 75 return changed; 76 } 77 }; 78 /** 79 * @brief Step the state based on clock. 80 * @param clock Clock containing the step time. 81 */ 82 virtual StepStatus Step(const IClock::ConstPtr& clock); 83 /** 84 * @brief Seeks the animation state to given position [0,1] 85 */ 86 virtual void Seek(float position); 87 /** 88 * @brief Pauses the animation. Returns true if state changed. 89 */ 90 virtual bool Pause(); 91 /** 92 * @brief Starts the animation. Returns true if state changed. 93 */ 94 virtual bool Start(); 95 /** 96 * @brief Stops the animation. Returns true if state changed. 97 */ 98 virtual bool Stop(); 99 /** 100 * @brief Restarts the animation. Returns true if state changed. 101 */ 102 virtual bool Restart(); 103 /** 104 * @brief Finishes the animation. Returns true if state changed. 105 */ 106 virtual bool Finish(); 107 /** 108 * @brief Returns true if the animation is running. 109 */ 110 bool IsRunning() const noexcept; 111 /** 112 * @brief REturns true if the animation is paused. 113 */ 114 bool IsPaused() const noexcept; 115 /** 116 * @brief Returns the current progress of the animation. 117 */ 118 float GetProgress() const noexcept; 119 /** 120 * @brief Move the animation to a requested step position 121 * @param step 122 * @param state 123 * @return 124 */ 125 StepStatus Move(const IAnimationInternal::MoveParams& move); 126 /** 127 * @brief Resets to the animation clock to initial state, even if the animation is running. 128 */ 129 void ResetClock(); 130 131 public: 132 BASE_NS::vector<IAnimationModifier::Ptr> GetModifiers() const; 133 bool Attach(const IObject::Ptr& attachment, const IObject::Ptr& dataContext); 134 bool Detach(const IObject::Ptr& attachment); 135 136 virtual void UpdateTotalDuration(); 137 138 protected: 139 virtual TimeSpan GetAnimationBaseDuration() const; 140 141 protected: GetParams()142 AnimationStateParams& GetParams() 143 { 144 return params_; 145 } 146 147 constexpr IAnimationInternal::AnimationTargetState GetAnimationTargetState() const noexcept 148 { 149 return state_.animationState_; 150 } 151 152 /** Return the owning animation of this state object */ 153 IAnimation::Ptr GetOwner() const noexcept; 154 /** Returns a duration with all modifiers applied */ 155 IAnimationModifier::DurationData ApplyDurationModifiers(TimeSpan duration) const; 156 /** Returns step data with all modifiers applied */ 157 IAnimationModifier::StepData ApplyStepModifiers(float progress) const; 158 159 private: 160 void NotifyEvaluationNeeded() const; 161 void NotifyStateChanged(const IAnimationInternal::AnimationStateChangedInfo& info) const; 162 void UpdateController(); 163 bool SetState(IAnimationInternal::AnimationTargetState state); 164 void SetRunning(bool running) noexcept; 165 void SetProgress(float progress) noexcept; 166 167 private: 168 IAnimationController::WeakPtr controller_; // Animation's controller 169 IOnChanged::InterfaceTypePtr updateTotalDuration_; // Callback function for total duration update 170 AnimationStateParams params_; // Animation parameters 171 struct StateData { 172 int32_t loops { 1 }; 173 TimeSpan totalDuration; 174 IAnimationModifier::DurationData duration; 175 bool shouldInit_ { false }; 176 IManualClock::Ptr clock_; 177 std::optional<META_NS::TimeSpan> lastTick_; 178 IAnimationInternal::AnimationTargetState animationState_ { IAnimationInternal::AnimationTargetState::STOPPED }; 179 180 void ResetLastTick() noexcept 181 { 182 lastTick_.reset(); 183 } SetTimeInternal::AnimationState::StateData184 void SetTime(const TimeSpan& time) 185 { 186 clock_->SetTime(time); 187 } TickInternal::AnimationState::StateData188 TimeSpan Tick(const TimeSpan& time) 189 { 190 clock_->IncrementTime(GetElapsed(time)); 191 lastTick_ = time; 192 return clock_->GetTime(); 193 } GetCurrentTimeInternal::AnimationState::StateData194 TimeSpan GetCurrentTime() const 195 { 196 return clock_->GetTime(); 197 } 198 constexpr TimeSpan GetElapsed(const TimeSpan& time) const noexcept 199 { 200 return lastTick_ ? time - *lastTick_ : TimeSpan::Zero(); 201 } 202 constexpr TimeSpan GetBaseDuration() const noexcept 203 { 204 return duration.duration; 205 } 206 207 } state_; // State data 208 mutable FindCache<IAnimationModifier> modifierCache_; // Cached modifier query 209 }; 210 211 /** 212 * @brief State class implementation for animation targeting a single property. 213 */ 214 class PropertyAnimationState : public AnimationState { 215 using Super = AnimationState; 216 217 public: 218 PropertyAnimationState() = default; 219 ~PropertyAnimationState() = default; 220 221 /** 222 * @brief Data needed for evaluating an animation state. 223 */ 224 struct EvaluationData { 225 /** Target value */ 226 const IAny::Ptr target; 227 /** Start of interpolation range */ 228 const IAny::Ptr from; 229 /** End of interpolation range */ 230 const IAny::Ptr to; 231 /** Linear animation progress [0,1] */ 232 float progress; 233 /** The (optional) curve to use for transforming the progress value */ 234 const ICurve1D::Ptr curve; 235 /** Returns true if the data is valid */ 236 inline bool IsValid() const noexcept 237 { 238 return target && from && to; 239 } 240 }; 241 /** 242 * @brief Initialize state object's internal interpolator to support given type id. 243 */ 244 bool SetInterpolator(const TypeId& id); 245 /** 246 * @brief Return the interpolator initialized with SetInterpolator. 247 */ 248 IInterpolator::Ptr GetInterpolator() const; 249 /** 250 * @brief Evaluates target value between [from,to] based on state. 251 * @param data Evaluation data. 252 */ 253 AnyReturnValue EvaluateValue(const EvaluationData& data) const; 254 255 private: 256 IInterpolator::Ptr interpolator_; 257 }; 258 259 } // namespace Internal 260 261 META_END_NAMESPACE() 262 263 #endif // META_SRC_ANIMATION_STATE_H 264