2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/update/animation/scene-graph-animation.h>
22 #include <cmath> // fmod
25 #include <dali/internal/render/common/performance-monitor.h>
38 float DefaultAlphaFunc(float progress)
40 return progress; // linear
43 Animation::Animation(float durationSeconds, bool isLooping, Dali::Animation::EndAction endAction, Dali::Animation::EndAction destroyAction)
44 : mDurationSeconds(durationSeconds),
46 mEndAction(endAction),
47 mDestroyAction(destroyAction),
49 mElapsedSeconds(0.0f),
54 Animation::~Animation()
58 void Animation::SetDuration(float durationSeconds)
60 DALI_ASSERT_DEBUG(durationSeconds > 0.0f);
62 mDurationSeconds = durationSeconds;
65 void Animation::SetLooping(bool looping)
70 void Animation::SetEndAction(Dali::Animation::EndAction action)
75 void Animation::SetDestroyAction(Dali::Animation::EndAction action)
77 mDestroyAction = action;
80 void Animation::Play()
85 void Animation::PlayFrom( float progress )
87 //If the animation is already playing this has no effect
88 if( mState != Playing )
90 mElapsedSeconds = progress * mDurationSeconds;
95 void Animation::Pause()
97 if (mState == Playing)
103 bool Animation::Stop(BufferIndex bufferIndex)
105 bool animationFinished(false);
107 if (mState == Playing || mState == Paused)
109 animationFinished = true; // The actor-thread should be notified of this
111 if( mEndAction != Dali::Animation::Discard )
113 if( mEndAction == Dali::Animation::BakeFinal )
115 mElapsedSeconds = mDurationSeconds + Math::MACHINE_EPSILON_1; // Force animation to reach it's end
117 UpdateAnimators(bufferIndex, true/*bake the final result*/);
120 // The animation has now been played to completion
124 mElapsedSeconds = 0.0f;
127 return animationFinished;
130 void Animation::OnDestroy(BufferIndex bufferIndex)
132 if (mState == Playing || mState == Paused)
134 if (mDestroyAction != Dali::Animation::Discard)
136 UpdateAnimators(bufferIndex, true/*bake the final result*/);
143 void Animation::AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner )
145 animator->Attach( propertyOwner );
147 mAnimators.PushBack( animator );
150 bool Animation::Update(BufferIndex bufferIndex, float elapsedSeconds)
152 if (mState == Stopped || mState == Destroyed)
154 // Short circuit when animation isn't running
158 // The animation must still be applied when Paused/Stopping
159 if (mState == Playing)
161 mElapsedSeconds += elapsedSeconds;
166 if (mElapsedSeconds > mDurationSeconds)
168 mElapsedSeconds = fmod(mElapsedSeconds, mDurationSeconds);
172 const bool animationFinished(mState == Playing && mElapsedSeconds > mDurationSeconds);
174 UpdateAnimators(bufferIndex, animationFinished && (mEndAction != Dali::Animation::Discard));
176 if (animationFinished)
178 // The animation has now been played to completion
181 mElapsedSeconds = 0.0f;
185 return animationFinished;
188 void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake)
190 for ( AnimatorIter iter = mAnimators.Begin(); iter != mAnimators.End(); )
192 // If an animator is not successfully applied, then it has been orphaned
195 AnimatorBase *animator = *iter;
196 const float initialDelay(animator->GetInitialDelay());
198 if (mElapsedSeconds >= initialDelay)
200 // Calculate a progress specific to each individual animator
201 float progress(1.0f);
202 const float animatorDuration = animator->GetDuration();
203 if (animatorDuration > 0.0f) // animators can be "immediate"
205 progress = min(1.0f, (mElapsedSeconds - initialDelay) / animatorDuration);
208 applied = animator->Update(bufferIndex, progress, bake);
211 // Animators are automatically removed, when orphaned from animatable scene objects.
214 iter = mAnimators.Erase(iter);
220 INCREASE_COUNTER(PerformanceMonitor::ANIMATORS_APPLIED);
225 } // namespace SceneGraph
227 } // namespace Internal