1 /*
2 * Copyright (c) 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_render_particle_animation.h"
17
18 #include <memory>
19
20 #include "animation/rs_value_estimator.h"
21 #include "command/rs_animation_command.h"
22 #include "platform/common/rs_log.h"
23 #include "transaction/rs_marshalling_helper.h"
24
25 namespace OHOS {
26 namespace Rosen {
RSRenderParticleAnimation(AnimationId id,const PropertyId & propertyId,const std::vector<std::shared_ptr<ParticleRenderParams>> particlesRenderParams)27 RSRenderParticleAnimation::RSRenderParticleAnimation(AnimationId id, const PropertyId& propertyId,
28 const std::vector<std::shared_ptr<ParticleRenderParams>> particlesRenderParams)
29 : RSRenderPropertyAnimation(id, propertyId)
30 {
31 particlesRenderParams_ = particlesRenderParams;
32 particleSystem_ = std::make_shared<RSRenderParticleSystem>(particlesRenderParams_);
33 }
34
Animate(int64_t time)35 bool RSRenderParticleAnimation::Animate(int64_t time)
36 {
37 int64_t deltaTime = time - animationFraction_.GetLastFrameTime();
38 animationFraction_.SetLastFrameTime(time);
39 if (particleSystem_ != nullptr) {
40 auto renderParticle = particleSystem_->Simulation(deltaTime);
41 renderParticleVector_ = RSRenderParticleVector(renderParticle);
42 }
43 auto property = std::static_pointer_cast<RSRenderProperty<RSRenderParticleVector>>(property_);
44 if (property) {
45 property->Set(renderParticleVector_);
46 }
47 auto target = GetTarget();
48 if (particleSystem_ == nullptr || particleSystem_->IsFinish()) {
49 if (target) {
50 target->RemoveModifier(property_->GetId());
51 }
52 return true;
53 }
54 return false;
55 }
56
OnAttach()57 void RSRenderParticleAnimation::OnAttach()
58 {
59 auto target = GetTarget();
60 if (target == nullptr) {
61 ROSEN_LOGE("RSRenderParticleAnimation::OnAttach, target is nullptr");
62 return;
63 }
64 auto particleAnimations = target->GetAnimationManager().GetParticleAnimations();
65 if (!particleAnimations.empty()) {
66 for (const auto& pair : particleAnimations) {
67 target->RemoveModifier(pair.first);
68 target->GetAnimationManager().RemoveAnimation(pair.second);
69 target->GetAnimationManager().UnregisterParticleAnimation(pair.first, pair.second);
70 }
71 }
72 target->GetAnimationManager().RegisterParticleAnimation(GetPropertyId(), GetAnimationId());
73 }
74
OnDetach()75 void RSRenderParticleAnimation::OnDetach()
76 {
77 auto target = GetTarget();
78 if (target == nullptr) {
79 ROSEN_LOGE("RSRenderParticleAnimation::OnDetach, target is nullptr");
80 return;
81 }
82 if (particleSystem_ != nullptr) {
83 particleSystem_->ClearEmitter();
84 particleSystem_.reset();
85 }
86 auto propertyId = GetPropertyId();
87 auto id = GetAnimationId();
88 target->GetAnimationManager().UnregisterParticleAnimation(propertyId, id);
89 }
90
Marshalling(Parcel & parcel) const91 bool RSRenderParticleAnimation::Marshalling(Parcel& parcel) const
92 {
93 auto id = GetAnimationId();
94 if (!(parcel.WriteUint64(id))) {
95 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write id failed");
96 return false;
97 }
98 if (!parcel.WriteUint64(propertyId_)) {
99 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write PropertyId failed");
100 return false;
101 }
102 if (!RSMarshallingHelper::Marshalling(parcel, particlesRenderParams_)) {
103 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write particlesRenderParams failed");
104 return false;
105 }
106 return true;
107 }
108
Unmarshalling(Parcel & parcel)109 RSRenderParticleAnimation* RSRenderParticleAnimation::Unmarshalling(Parcel& parcel)
110 {
111 RSRenderParticleAnimation* renderParticleAnimation = new RSRenderParticleAnimation();
112 if (!renderParticleAnimation->ParseParam(parcel)) {
113 ROSEN_LOGE("RSRenderParticleAnimation::Unmarshalling, failed");
114 delete renderParticleAnimation;
115 return nullptr;
116 }
117 return renderParticleAnimation;
118 }
119
ParseParam(Parcel & parcel)120 bool RSRenderParticleAnimation::ParseParam(Parcel& parcel)
121 {
122 AnimationId id = 0;
123 if (!parcel.ReadUint64(id)) {
124 ROSEN_LOGE("RSRenderParticleAnimation::ParseParam, Unmarshalling animationId failed");
125 return false;
126 }
127 SetAnimationId(id);
128 if (!(parcel.ReadUint64(propertyId_) && RSMarshallingHelper::Unmarshalling(parcel, particlesRenderParams_))) {
129 ROSEN_LOGE("RSRenderParticleAnimation::ParseParam, Unmarshalling failed");
130 return false;
131 }
132 particleSystem_ = std::make_shared<RSRenderParticleSystem>(particlesRenderParams_);
133 return true;
134 }
135
136 } // namespace Rosen
137 } // namespace OHOS
138