1 /*
2 * Copyright (c) 2022-2023 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 "animation/rs_ui_animation_manager.h"
17
18 #include "animation/rs_animation.h"
19 #include "animation/rs_render_animation.h"
20 #include "modifier/rs_modifier_manager.h"
21 #include "modifier/rs_property.h"
22 #include "modifier/rs_render_property.h"
23 #include "platform/common/rs_log.h"
24
25 namespace OHOS {
26 namespace Rosen {
RSUIAnimationManager()27 RSUIAnimationManager::RSUIAnimationManager()
28 {
29 modifierManager_ = std::make_shared<RSModifierManager>();
30 }
31
AddAnimation(const std::shared_ptr<RSRenderAnimation> & animation,const std::shared_ptr<RSAnimation> & uiAnimation)32 void RSUIAnimationManager::AddAnimation(const std::shared_ptr<RSRenderAnimation>& animation,
33 const std::shared_ptr<RSAnimation>& uiAnimation)
34 {
35 AnimationId key = animation->GetAnimationId();
36 if (animations_.find(key) != animations_.end()) {
37 ROSEN_LOGE("RSUIAnimationManager::AddAnimation, The animation already exists when is added");
38 return;
39 }
40 animations_.emplace(key, animation);
41 uiAnimations_.emplace(key, uiAnimation);
42 OnAnimationAdd(animation);
43 }
44
RemoveAnimation(AnimationId keyId)45 void RSUIAnimationManager::RemoveAnimation(AnimationId keyId)
46 {
47 auto animationItr = animations_.find(keyId);
48 if (animationItr == animations_.end()) {
49 ROSEN_LOGE("RSUIAnimationManager::RemoveAnimation, The Animation does not exist when is deleted");
50 return;
51 }
52 RemoveUIAnimation(keyId);
53 OnAnimationRemove(animationItr->second);
54 animations_.erase(animationItr);
55 }
56
RemoveUIAnimation(const AnimationId id)57 void RSUIAnimationManager::RemoveUIAnimation(const AnimationId id)
58 {
59 auto uiAnimationItr = uiAnimations_.find(id);
60 if (uiAnimationItr == uiAnimations_.end()) {
61 ROSEN_LOGE("RSUIAnimationManager::RemoveUIAnimation, The UIAnimation does not exist when is deleted");
62 return;
63 }
64 uiAnimations_.erase(uiAnimationItr);
65 }
66
AddAnimatableProp(const PropertyId id,const std::shared_ptr<RSPropertyBase> & uiProperty,const std::shared_ptr<RSRenderPropertyBase> & renderProperty)67 void RSUIAnimationManager::AddAnimatableProp(const PropertyId id,
68 const std::shared_ptr<RSPropertyBase>& uiProperty,
69 const std::shared_ptr<RSRenderPropertyBase>& renderProperty)
70 {
71 properties_.emplace(id, std::make_pair(uiProperty, renderProperty));
72 }
73
GetRenderProperty(const PropertyId id)74 const std::shared_ptr<RSRenderPropertyBase> RSUIAnimationManager::GetRenderProperty(
75 const PropertyId id)
76 {
77 auto iter = properties_.find(id);
78 if (iter != properties_.end()) {
79 return iter->second.second;
80 }
81 return {};
82 }
83
RemoveProperty(const PropertyId id)84 void RSUIAnimationManager::RemoveProperty(const PropertyId id)
85 {
86 properties_.erase(id);
87 }
88
Animate(int64_t time)89 bool RSUIAnimationManager::Animate(int64_t time)
90 {
91 // process animation
92 bool hasRunningAnimation = false;
93
94 // iterate and execute all animations, remove finished animations
95 EraseIf(animations_, [this, &hasRunningAnimation, time](auto& iter) -> bool {
96 auto& animation = iter.second;
97 bool isFinished = UpdateAnimateValue(animation, time);
98 if (isFinished) {
99 OnAnimationFinished(animation);
100 RemoveUIAnimation(animation->GetAnimationId());
101 } else {
102 hasRunningAnimation = animation->IsRunning() || hasRunningAnimation ;
103 }
104 return isFinished;
105 });
106
107 return hasRunningAnimation;
108 }
109
UpdateAnimateValue(const std::shared_ptr<RSRenderAnimation> & animation,int64_t time)110 bool RSUIAnimationManager::UpdateAnimateValue(const std::shared_ptr<RSRenderAnimation>& animation, int64_t time)
111 {
112 bool isFinished = animation->Animate(time);
113 auto uiProperty = properties_[animation->GetPropertyId()].first;
114 auto renderProperty = properties_[animation->GetPropertyId()].second;
115 if (uiProperty != nullptr && renderProperty != nullptr) {
116 uiProperty->UpdateShowingValue(renderProperty);
117 uiProperty->MarkModifierDirty(modifierManager_);
118 }
119 return isFinished;
120 }
121
Draw()122 void RSUIAnimationManager::Draw()
123 {
124 modifierManager_->Draw();
125 }
126
GetAnimation(AnimationId id) const127 const std::shared_ptr<RSRenderAnimation> RSUIAnimationManager::GetAnimation(AnimationId id) const
128 {
129 auto animationItr = animations_.find(id);
130 if (animationItr == animations_.end()) {
131 ROSEN_LOGE("RSUIAnimationManager::GetAnimation, animation [%" PRIu64 "] not found", id);
132 return nullptr;
133 }
134 return animationItr->second;
135 }
136
OnAnimationRemove(const std::shared_ptr<RSRenderAnimation> & animation)137 void RSUIAnimationManager::OnAnimationRemove(const std::shared_ptr<RSRenderAnimation>& animation)
138 {
139 auto iter = animationNum_.find(animation->GetPropertyId());
140 if (iter == animationNum_.end()) {
141 return;
142 }
143
144 iter->second--;
145 if (iter->second == 0) {
146 RemoveProperty(animation->GetPropertyId());
147 animationNum_.erase(iter);
148 }
149 }
150
OnAnimationAdd(const std::shared_ptr<RSRenderAnimation> & animation)151 void RSUIAnimationManager::OnAnimationAdd(const std::shared_ptr<RSRenderAnimation>& animation)
152 {
153 auto iter = animationNum_.find(animation->GetPropertyId());
154 if (iter == animationNum_.end()) {
155 animationNum_.emplace(animation->GetPropertyId(), 1);
156 return;
157 }
158
159 iter->second++;
160 }
161
OnAnimationFinished(const std::shared_ptr<RSRenderAnimation> & animation)162 void RSUIAnimationManager::OnAnimationFinished(const std::shared_ptr<RSRenderAnimation>& animation)
163 {
164 auto uiAnimation = uiAnimations_[animation->GetAnimationId()];
165 if (uiAnimation != nullptr) {
166 uiAnimation->UIAnimationFinish();
167 }
168 OnAnimationRemove(animation);
169 animation->Detach();
170 }
171 } // namespace Rosen
172 } // namespace OHOS
173