1 /*
2 * Copyright (c) 2021 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 #include "core/animation/scheduler.h"
17
18 #include "base/log/log.h"
19 #include "core/pipeline/pipeline_base.h"
20
21 namespace OHOS::Ace {
22
Start()23 void Scheduler::Start()
24 {
25 if (isRunning_) {
26 LOGW("Already running, no need to start again.");
27 return;
28 }
29 auto context = context_.Upgrade();
30 if (!context) {
31 LOGE("Start failed, context is null.");
32 return;
33 }
34 isRunning_ = true;
35 startupTimestamp_ = context->GetTimeFromExternalTimer();
36 scheduleId_ = static_cast<int32_t>(context->AddScheduleTask(AceType::Claim(this)));
37 }
38
Stop()39 void Scheduler::Stop()
40 {
41 if (!isRunning_) {
42 LOGD("Already stopped, no need to stop again.");
43 return;
44 }
45 auto context = context_.Upgrade();
46 if (!context) {
47 LOGE("Stop failed, context is null.");
48 return;
49 }
50 isRunning_ = false;
51 context->RemoveScheduleTask(scheduleId_);
52 scheduleId_ = 0;
53 }
54
OnFrame(uint64_t nanoTimestamp)55 void Scheduler::OnFrame(uint64_t nanoTimestamp)
56 {
57 if (!isRunning_) {
58 LOGD("Already stopped, no need to send frame event.");
59 return;
60 }
61
62 // Refresh the startup time every frame.
63 uint64_t elapsedTimeMs = 0;
64 if (nanoTimestamp > startupTimestamp_) {
65 static const uint64_t milliToNano = 1000000;
66 elapsedTimeMs = (nanoTimestamp - startupTimestamp_) / milliToNano;
67 startupTimestamp_ += elapsedTimeMs * milliToNano;
68 }
69
70 // Consume previous schedule as default.
71 scheduleId_ = 0;
72 if (callback_) {
73 // Need to convert nanoseconds to milliseconds
74 callback_(elapsedTimeMs);
75 }
76
77 // Schedule next frame task.
78 auto context = context_.Upgrade();
79 if (!context) {
80 LOGE("Schedule next frame task failed, context is null.");
81 return;
82 }
83 if (IsActive()) {
84 scheduleId_ = static_cast<int32_t>(context->AddScheduleTask(AceType::Claim(this)));
85 }
86 }
87
Animate(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> propertyCallback,const std::function<void ()> & finishCallBack)88 bool Scheduler::Animate(const AnimationOption& option, const RefPtr<Curve>& curve,
89 const std::function<void()> propertyCallback, const std::function<void()>& finishCallBack)
90 {
91 auto context = context_.Upgrade();
92 if (context == nullptr) {
93 LOGE("Failed to animate asynchronously, context is null!");
94 return false;
95 }
96
97 return context->Animate(option, curve, propertyCallback, finishCallBack);
98 }
99
OpenImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallBack)100 void Scheduler::OpenImplicitAnimation(const AnimationOption& option, const RefPtr<Curve>& curve,
101 const std::function<void()>& finishCallBack)
102 {
103 auto context = context_.Upgrade();
104 if (context == nullptr) {
105 LOGE("Failed to open implicit animation, context is null!");
106 return;
107 }
108
109 return context->OpenImplicitAnimation(option, curve, finishCallBack);
110 }
111
CloseImplicitAnimation()112 bool Scheduler::CloseImplicitAnimation()
113 {
114 auto context = context_.Upgrade();
115 if (context == nullptr) {
116 LOGE("Failed to close implicit animation, context is null!");
117 return false;
118 }
119
120 return context->CloseImplicitAnimation();
121 }
122
AddKeyFrame(float fraction,const RefPtr<Curve> & curve,const std::function<void ()> & propertyCallback)123 void Scheduler::AddKeyFrame(
124 float fraction, const RefPtr<Curve>& curve, const std::function<void()>& propertyCallback)
125 {
126 auto context = context_.Upgrade();
127 if (context == nullptr) {
128 LOGE("Failed to add keyframe, context is null!");
129 return;
130 }
131
132 return context->AddKeyFrame(fraction, curve, propertyCallback);
133 }
134
AddKeyFrame(float fraction,const std::function<void ()> & propertyCallback)135 void Scheduler::AddKeyFrame(float fraction, const std::function<void()>& propertyCallback)
136 {
137 auto context = context_.Upgrade();
138 if (context == nullptr) {
139 LOGE("Failed to add keyframe, context is null!");
140 return;
141 }
142
143 return context->AddKeyFrame(fraction, propertyCallback);
144 }
145
146 } // namespace OHOS::Ace
147