1 /* 2 * Copyright (c) 2021-2022 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 FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATOR_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATOR_H 18 19 #include <fstream> 20 #include <list> 21 22 #include "base/log/ace_trace.h" 23 #include "base/memory/referenced.h" 24 #include "base/utils/macros.h" 25 #include "base/utils/system_properties.h" 26 #include "core/animation/animation_pub.h" 27 #include "core/animation/interpolator.h" 28 #include "core/animation/motion.h" 29 #include "core/animation/scheduler.h" 30 #include "core/animation/status_listener.h" 31 #include "core/animation/time_event.h" 32 #include "core/components/common/properties/animation_option.h" 33 #include "core/components_ng/syntax/if_else_model.h" 34 35 #ifdef PREVIEW 36 #define CREATE_ANIMATOR(...) AceType::MakeRefPtr<Animator>(__VA_ARGS__) 37 #else 38 #define CREATE_ANIMATOR(...) Animator::CreateAnimator(__FILE__, __LINE__, ##__VA_ARGS__) 39 #endif 40 41 namespace OHOS::Ace { 42 class ACE_FORCE_EXPORT Animator : public AceType, public StatusListenable { 43 DECLARE_ACE_TYPE(Animator, AceType); 44 45 public: 46 enum class Status { 47 IDLE, // when animation not start or been cancel. 48 RUNNING, // play in reverse / forward direction. 49 PAUSED, // paused by call Pause API. 50 STOPPED, // stopped by call Finish/Stop API or has played to the end. 51 }; 52 53 // Adjust global animation duration, default scale is 1.0f. 54 static void SetDurationScale(float scale); 55 56 // Animator can play animations. 57 // So far, animation has two types: Interpolator and Motion(physical-based animation). 58 // But only one type will be played at a time. When playing one, the other's setting will be cleared. 59 // 1. Interpolator: Play/Reverse/Stop/Finish will work 60 // 2. Motion: PlayMotion will work 61 Animator(const WeakPtr<PipelineBase>& context, const char* name = nullptr); 62 63 Animator(const char* name = nullptr); 64 65 ~Animator() override; 66 67 private: CombineStrUint(const char * fileName,int line)68 static std::string CombineStrUint(const char* fileName, int line) 69 { 70 std::string output = fileName; 71 output += " Line : "; 72 output += std::to_string(line); 73 return output; 74 } 75 76 public: 77 static RefPtr<Animator> CreateAnimator( 78 const char* fileName, int line, const WeakPtr<PipelineBase>& context, const char* name = nullptr) 79 { 80 if (SystemProperties::GetDebugEnabled()) { 81 if (name == nullptr) { 82 return AceType::MakeRefPtr<Animator>(context, CombineStrUint(fileName, line).c_str()); 83 } else { 84 return AceType::MakeRefPtr<Animator>(context, (CombineStrUint(fileName, line) + name).c_str()); 85 } 86 } else { 87 return AceType::MakeRefPtr<Animator>(context, name); 88 } 89 } 90 91 static RefPtr<Animator> CreateAnimator(const char* fileName, int line, const char* name = nullptr) 92 { 93 if (SystemProperties::GetDebugEnabled()) { 94 if (name == nullptr) { 95 return AceType::MakeRefPtr<Animator>(CombineStrUint(fileName, line).c_str()); 96 } else { 97 return AceType::MakeRefPtr<Animator>((CombineStrUint(fileName, line) + name).c_str()); 98 } 99 } else { 100 return AceType::MakeRefPtr<Animator>(name); 101 } 102 } 103 104 void AttachScheduler(const WeakPtr<PipelineBase>& context); 105 bool AttachSchedulerOnContainer(); 106 bool HasScheduler() const; 107 bool SetExpectedFrameRateRange(const FrameRateRange& frameRateRange); 108 109 // Every interpolate animation needs to add itself into animator and use the controller to drive. 110 void AddInterpolator(const RefPtr<Interpolator>& animation); 111 void RemoveInterpolator(const RefPtr<Interpolator>& animation); 112 void ClearInterpolators(); 113 114 // Controller (A) can be added to other controller (B) as a proxy when (B) is running. 115 void AddProxyController(const RefPtr<Animator>& proxy); 116 void RemoveProxyController(const RefPtr<Animator>& proxy); 117 void ClearProxyControllers(); 118 119 // Can use these APIs to check controller's current state. 120 Status GetStatus() const; 121 bool IsStopped() const; 122 bool IsRunning() const; 123 bool IsPending() const; 124 125 // Sets the total running time of the animator to drive the animation. 126 void SetDuration(int32_t duration); 127 int32_t GetDuration() const; 128 void SetStartDelay(int32_t startDelay); 129 130 // At last will run iteration loops. repeatTimes equals 0 as default. 131 bool SetIteration(int32_t iteration); 132 133 // fillmode used to decided the attr of last frame or first frame. 134 void SetFillMode(FillMode fillMode); 135 136 // tempo is used to control speed of animation. 137 void SetTempo(float tempo); 138 139 // init animation parameters with animationOption 140 void ApplyOption(const AnimationOption& option); 141 142 // Whether the animation should be played in reverse in turn. 143 void SetAnimationDirection(AnimationDirection direction); 144 145 // Set Whether or not the animator is allowed to run asynchronously off of the UI thread. 146 void SetAllowRunningAsynchronously(bool runAsync); 147 148 // Get whether or not the animator is allowed to run asynchronously off of the UI thread. 149 bool GetAllowRunningAsynchronously(); 150 151 // Update the played time, will not trigger OnFrame callback. 152 void UpdatePlayedTime(int32_t playedTime, bool checkReverse = false); 153 int64_t GetPlayedTime() const; 154 155 // Trigger one frame callback by the given time. 156 void TriggerFrame(int32_t playedTime, bool checkReverse = false); 157 158 // Motion not support set duration & repeat & Reverse. 159 void PlayMotion(const RefPtr<Motion>& motion); 160 161 // Play the Animation based current direction. 162 void Play(); 163 164 // Reverse the Animation based current direction. 165 void Reverse(); 166 167 // Means play forward and set direction reverse false. 168 void Forward(); 169 170 // Means play backward and set direction reverse true. 171 void Backward(); 172 173 // Stop at the current frame(Continueable stop). 174 void Pause(); 175 176 // Resume animation from the pause frame. 177 void Resume(); 178 179 // Stop at the current frame(Unrecoverable stop). 180 void Stop(); 181 182 // Stop at the end frame. 183 void Finish(); 184 185 // Stop at the start frame. 186 void Cancel(); 187 188 // Reset isReverse_ value. 189 void ResetIsReverse(); 190 191 // Get Controller Id. 192 int32_t GetId() const; 193 194 // Get AnimationScale 195 float GetAnimationScale() const; 196 197 // Get FillMode 198 FillMode GetFillMode() const; 199 200 // Get Iteration 201 int32_t GetIteration() const; 202 203 // Set AnimationType SetAnimationType(AnimationInterface type)204 void SetAnimationType(AnimationInterface type) 205 { 206 animationType_ = type; 207 } 208 209 // Get AnimationType GetAnimationType()210 AnimationInterface GetAnimationType() 211 { 212 return animationType_; 213 } 214 PreventFrameJank()215 void PreventFrameJank() { 216 needFrameJankReport_ = false; 217 } 218 219 bool PrintVsyncInfoIfNeed() const; 220 221 private: 222 // Screen refresh callback. duration is in millisecond. 223 void OnFrame(int64_t duration); 224 225 // Callback the played time to the interpolator animation. 226 void NotifyInterpolator(int32_t playedTime); 227 228 // Callback the played time to the motion animation. 229 void NotifyMotion(int32_t playedTime); 230 231 void StartInner(bool alwaysNotify); 232 233 AnimationOption GetAnimationOption(); 234 235 bool IsSupportedRunningAsynchronously(); 236 237 bool StartAsync(); 238 239 bool StartInnerAsync(); 240 241 void StopInnerAsync(); 242 243 // Calculate played loops and remaining in playedTime 244 int32_t GetPlayedLoopsAndRemaining(int32_t& playedTime); 245 246 bool GetInitAnimationDirection(); 247 248 // update repeatTimesLeft_ and returns true if run out of repeat times. 249 bool UpdateRepeatTimesLeftAndCheckFinished(int32_t playedLoops); 250 251 void ToggleDirection(); 252 float GetNormalizedTime(float playedTime, bool needStop) const; 253 254 void UpdateScaledTime(); 255 void UpdateIteration(int32_t iteration); 256 257 void Copy(const RefPtr<Animator>& controller); 258 259 std::list<RefPtr<Interpolator>> interpolators_; 260 std::list<RefPtr<Animator>> proxyControllers_; 261 RefPtr<Scheduler> scheduler_; 262 RefPtr<Motion> motion_; 263 FillMode fillMode_ = FillMode::FORWARDS; 264 AnimationDirection direction_ = AnimationDirection::NORMAL; 265 int32_t duration_ = 0; // millisecond. 266 int64_t elapsedTime_ = 0; // millisecond. in range: 0 ~ startDelay_ + INTERPOLATE_DURATION_MAX 267 int32_t startDelay_ = 0; // millisecond. 268 int32_t repeatTimes_ = 0; // user configured repeat times. 269 int32_t iteration_ = 1; // user configured iteration times. 270 int32_t repeatTimesLeft_ = 0; // repeat times for controller to play 271 int32_t scaledDuration_ = 0; 272 int32_t scaledStartDelay_ = 0; 273 int asyncRunningAnimationCount_ = 0; 274 bool isReverse_ = false; 275 bool isResume_ = false; 276 bool isCurDirection_ = false; 277 bool isOddRound_ = true; 278 bool toggleDirectionPending_ = false; 279 bool allowRunningAsynchronously_ = false; 280 bool needFrameJankReport_ = true; 281 Status status_ = Status::IDLE; 282 int32_t controllerId_ = 0; 283 static float scale_; 284 float tempo_ = 1.0f; 285 bool isBothBackwards = false; 286 std::shared_ptr<AceAsyncScopedTrace> asyncTrace_; 287 std::string animatorName_ = "Animator"; 288 AnimationInterface animationType_ = AnimationInterface::UNKNOWN; 289 }; 290 291 } // namespace OHOS::Ace 292 293 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATOR_H 294