2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include <dali/internal/update/animation/scene-graph-animation.h>
21 #include <cmath> // fmod
24 #include <dali/internal/render/common/performance-monitor.h>
37 float DefaultAlphaFunc(float progress)
39 return progress; // linear
42 Animation::Animation(float durationSeconds, bool isLooping, Dali::Animation::EndAction endAction, Dali::Animation::EndAction destroyAction)
43 : mDurationSeconds(durationSeconds),
45 mEndAction(endAction),
46 mDestroyAction(destroyAction),
48 mElapsedSeconds(0.0f),
53 Animation::~Animation()
57 void Animation::SetDuration(float durationSeconds)
59 DALI_ASSERT_DEBUG(durationSeconds > 0.0f);
61 mDurationSeconds = durationSeconds;
64 void Animation::SetLooping(bool looping)
69 void Animation::SetEndAction(Dali::Animation::EndAction action)
74 void Animation::SetDestroyAction(Dali::Animation::EndAction action)
76 mDestroyAction = action;
79 void Animation::Play()
84 void Animation::Pause()
86 if (mState == Playing)
92 bool Animation::Stop(BufferIndex bufferIndex)
94 bool animationFinished(false);
96 if (mState == Playing || mState == Paused)
98 animationFinished = true; // The actor-thread should be notified of this
100 if( mEndAction != Dali::Animation::Discard )
102 if( mEndAction == Dali::Animation::BakeFinal )
104 mElapsedSeconds = mDurationSeconds + Math::MACHINE_EPSILON_1; // Force animation to reach it's end
106 UpdateAnimators(bufferIndex, true/*bake the final result*/);
109 // The animation has now been played to completion
113 mElapsedSeconds = 0.0f;
116 return animationFinished;
119 void Animation::OnDestroy(BufferIndex bufferIndex)
121 if (mState == Playing || mState == Paused)
123 if (mDestroyAction != Dali::Animation::Discard)
125 UpdateAnimators(bufferIndex, true/*bake the final result*/);
132 void Animation::AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner )
134 animator->Attach( propertyOwner );
136 mAnimators.PushBack( animator );
139 bool Animation::Update(BufferIndex bufferIndex, float elapsedSeconds)
141 if (mState == Stopped || mState == Destroyed)
143 // Short circuit when animation isn't running
147 // The animation must still be applied when Paused/Stopping
148 if (mState == Playing)
150 mElapsedSeconds += elapsedSeconds;
155 if (mElapsedSeconds > mDurationSeconds)
157 mElapsedSeconds = fmod(mElapsedSeconds, mDurationSeconds);
161 const bool animationFinished(mState == Playing && mElapsedSeconds > mDurationSeconds);
163 UpdateAnimators(bufferIndex, animationFinished && (mEndAction != Dali::Animation::Discard));
165 if (animationFinished)
167 // The animation has now been played to completion
170 mElapsedSeconds = 0.0f;
174 return animationFinished;
177 void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake)
179 for ( AnimatorIter iter = mAnimators.Begin(); iter != mAnimators.End(); )
181 // If an animator is not successfully applied, then it has been orphaned
184 AnimatorBase *animator = *iter;
185 const float initialDelay(animator->GetInitialDelay());
187 if (mElapsedSeconds >= initialDelay)
189 // Calculate a progress specific to each individual animator
190 float progress(1.0f);
191 const float animatorDuration = animator->GetDuration();
192 if (animatorDuration > 0.0f) // animators can be "immediate"
194 progress = min(1.0f, (mElapsedSeconds - initialDelay) / animatorDuration);
197 applied = animator->Update(bufferIndex, progress, bake);
200 // Animators are automatically removed, when orphaned from animatable scene objects.
203 iter = mAnimators.Erase(iter);
209 INCREASE_COUNTER(PerformanceMonitor::ANIMATORS_APPLIED);
214 } // namespace SceneGraph
216 } // namespace Internal