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 
PreventFrameJank()203     void PreventFrameJank() {
204         needFrameJankReport_ = false;
205     }
206 
207     bool PrintVsyncInfoIfNeed() const;
208 
209 private:
210     // Screen refresh callback. duration is in millisecond.
211     void OnFrame(int64_t duration);
212 
213     // Callback the played time to the interpolator animation.
214     void NotifyInterpolator(int32_t playedTime);
215 
216     // Callback the played time to the motion animation.
217     void NotifyMotion(int32_t playedTime);
218 
219     void StartInner(bool alwaysNotify);
220 
221     AnimationOption GetAnimationOption();
222 
223     bool IsSupportedRunningAsynchronously();
224 
225     bool StartAsync();
226 
227     bool StartInnerAsync();
228 
229     void StopInnerAsync();
230 
231     // Calculate played loops and remaining in playedTime
232     int32_t GetPlayedLoopsAndRemaining(int32_t& playedTime);
233 
234     bool GetInitAnimationDirection();
235 
236     // update repeatTimesLeft_ and returns true if run out of repeat times.
237     bool UpdateRepeatTimesLeftAndCheckFinished(int32_t playedLoops);
238 
239     void ToggleDirection();
240     float GetNormalizedTime(float playedTime, bool needStop) const;
241 
242     void UpdateScaledTime();
243     void UpdateIteration(int32_t iteration);
244 
245     void Copy(const RefPtr<Animator>& controller);
246 
247     std::list<RefPtr<Interpolator>> interpolators_;
248     std::list<RefPtr<Animator>> proxyControllers_;
249     RefPtr<Scheduler> scheduler_;
250     RefPtr<Motion> motion_;
251     FillMode fillMode_ = FillMode::FORWARDS;
252     AnimationDirection direction_ = AnimationDirection::NORMAL;
253     int32_t duration_ = 0;        // millisecond.
254     int64_t elapsedTime_ = 0;     // millisecond. in range: 0 ~ startDelay_ + INTERPOLATE_DURATION_MAX
255     int32_t startDelay_ = 0;      // millisecond.
256     int32_t repeatTimes_ = 0;     // user configured repeat times.
257     int32_t iteration_ = 1;       // user configured iteration times.
258     int32_t repeatTimesLeft_ = 0; // repeat times for controller to play
259     int32_t scaledDuration_ = 0;
260     int32_t scaledStartDelay_ = 0;
261     int asyncRunningAnimationCount_ = 0;
262     bool isReverse_ = false;
263     bool isResume_ = false;
264     bool isCurDirection_ = false;
265     bool isOddRound_ = true;
266     bool toggleDirectionPending_ = false;
267     bool allowRunningAsynchronously_ = false;
268     bool needFrameJankReport_ = true;
269     Status status_ = Status::IDLE;
270     int32_t controllerId_ = 0;
271     static float scale_;
272     float tempo_ = 1.0f;
273     bool isBothBackwards = false;
274     std::shared_ptr<AceAsyncScopedTrace> asyncTrace_;
275     std::string animatorName_ = "Animator";
276 };
277 
278 } // namespace OHOS::Ace
279 
280 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATOR_H
281