application.SendNotification();
application.Render(0);
- // expect finished signal recieved due to Stop API.
+ // expect finished signal not recieved.
application.SendNotification();
finishCheck.CheckSignalNotReceived();
finishCheck.Reset();
application.SendNotification();
application.Render(0);
- // expect finished signal recieved due to Stop API.
+ // expect finished signal not recieved.
application.SendNotification();
finishCheck.CheckSignalNotReceived();
finishCheck.Reset();
END_TEST;
}
+int UtcDaliAnimationClearIgnoreFinishedSignal(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ application.GetScene().Add(actor);
+
+ // Build the animation
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ Vector3 targetPosition(100.0f, 100.0f, 100.0f);
+ animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+
+ Vector3 fiftyPercentProgress(targetPosition * 0.5f);
+
+ // Start the animation
+ animation.Play();
+
+ bool signalReceived(false);
+ AnimationFinishCheck finishCheck(signalReceived);
+ animation.FinishedSignal().Connect(&application, finishCheck);
+
+ // Check finished signal not emmited if animation was cleared.
+ {
+ tet_printf("Check whether stop and clear case didnt send finished signal\n");
+ // Play the animation, and stop after animation finished naturally, and clear.
+ animation.Play();
+
+ application.SendNotification();
+
+ animation.Stop();
+ animation.Clear();
+
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ finishCheck.Reset();
+
+ // Finish animation naturally. (Note that dali don't call finished callback even if one render frame spend more than duration.)
+ application.Render(static_cast<uint32_t>(durationSeconds * 500.0f));
+ application.Render(static_cast<uint32_t>(durationSeconds * 500.0f) + 10u);
+ application.SendNotification();
+
+ // expect finished signal not recieved.
+ finishCheck.CheckSignalNotReceived();
+ finishCheck.Reset();
+
+ application.SendNotification();
+ application.Render(0);
+ }
+ {
+ tet_printf("Check whether stop and clear and render-well case send finished signal\n");
+ // Play the animation, and stop after animation finished naturally, and clear, and play again.
+ animation.PlayAfter(durationSeconds);
+
+ application.SendNotification();
+
+ // delay 50%.
+ application.Render(static_cast<uint32_t>(durationSeconds * 500.0f));
+
+ animation.Stop();
+ animation.Clear();
+ animation.Play();
+
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ finishCheck.Reset();
+
+ // Finish animation naturally. (Note that dali don't call finished callback even if one render frame spend more than duration.)
+ application.Render(static_cast<uint32_t>(durationSeconds * 500.0f));
+ application.Render(static_cast<uint32_t>(durationSeconds * 500.0f) + 10u);
+ application.SendNotification();
+
+ // expect finished signal recieved due to Animation finished.
+ application.SendNotification();
+ finishCheck.CheckSignalReceived();
+ finishCheck.Reset();
+
+ application.SendNotification();
+ application.Render(0);
+ }
+
+ END_TEST;
+}
+
int UtcDaliAnimationEmptyAnimatorAndLoopCount(void)
{
// Clear and play the empty animation, and get the state values.
// Let we don't change current loop value if the state was paused.
if(mState != Paused)
{
- mCurrentLoop = 0;
+ mCurrentLoop = 0;
+ mDelaySeconds = 0.0f;
}
mState = Playing;
// Let we don't change current loop value if the state was paused.
if(mState != Paused)
{
- mCurrentLoop = 0;
+ mCurrentLoop = 0;
+ mDelaySeconds = 0.0f;
}
mState = Playing;
if(mState == Playing || mState == Paused)
{
animationFinished = true; // The actor-thread should be notified of this
+ mIsStopped = true;
if(mEndAction != Dali::Animation::DISCARD)
{
mCurrentLoop = 0;
}
+ mDelaySeconds = 0.0f;
mElapsedSeconds = mPlayRange.x * mDurationSeconds;
mState = Stopped;
mIsFirstLoop = true;
return animationFinished;
}
-void Animation::Clear(BufferIndex bufferIndex)
+void Animation::ClearAnimator(BufferIndex bufferIndex)
{
// Stop animation immediatly.
Stop(bufferIndex);
mAnimatorSortRequired = false;
// Reset animation state values.
+ mIsStopped = false; ///< Do not make notify.
mPlayedCount = 0;
mCurrentLoop = 0;
}
}
}
- mState = Destroyed;
+ mIsStopped = false; ///< Do not make notify.
+ mState = Destroyed;
}
void Animation::SetLoopingMode(bool loopingMode)
mAnimators.PushBack(animator.Release());
}
-void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached)
+void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& stopped, bool& finished, bool& progressReached)
{
- looped = false;
+ // Reset mIsStopped flag now.
+ stopped = mIsStopped;
+ mIsStopped = false;
+
finished = false;
// Short circuit when animation isn't running
float markerFactor = signSpeedFactor * mProgressMarker;
// check it is looped
- looped = (elapsedFactor > edgeFactor);
+ const bool looped = (elapsedFactor > edgeFactor);
if(looped)
{
bool Stop(BufferIndex bufferIndex);
/**
- * Clear the animation. It will clear all animator, and make this animation never played before.
+ * Clear the animator. It will stop animation, clear all animators, and make this animation never played before.
* @param[in] bufferIndex The buffer to update when mEndAction == Bake.
*/
- void Clear(BufferIndex bufferIndex);
+ void ClearAnimator(BufferIndex bufferIndex);
/**
* Called shortly before the animation is destroyed.
* @pre The animation is playing or paused.
* @param[in] bufferIndex The buffer to update.
* @param[in] elapsedSeconds The time elapsed since the previous frame.
- * @param[out] looped True if the animation looped
+ * @param[out] stopped True if the animation stopped this loop
* @param[out] finished True if the animation has finished.
* @param[out] progressReached True if progress marker reached
*/
- void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached);
+ void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& stopped, bool& finished, bool& progressReached);
static uint32_t GetMemoryPoolCapacity();
bool mAnimatorSortRequired; // Flag to whether we need to sort animator or not.
bool mIsActive[2]; // Flag to indicate whether the animation is active in the current frame (which is double buffered)
bool mIsFirstLoop;
+ bool mIsStopped; // Flag to whether this animation call stoped by user at this frame.
};
}; // namespace SceneGraph
// Construct message in the message queue memory; note that delete should not be called on the return value
new(slot) LocalType(&animation, &Animation::Play);
}
+
inline void PlayAnimationFromMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
{
using LocalType = MessageValue1<Animation, float>;
bool animationFinished = animation->Stop(mSceneGraphBuffers.GetUpdateBufferIndex());
- // Queue this animation into notify required animations. Since we need to send Finished signal
- mImpl->notifyRequiredAnimations.PushBack(animation->GetNotifyId());
-
mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
}
{
DALI_ASSERT_DEBUG(animation && "NULL animation called to clear");
- animation->Clear(mSceneGraphBuffers.GetUpdateBufferIndex());
-
- // We should remove all notify lists what we requests before clear.
- // TODO : Could we do this more faster?
- Dali::EraseIf(mImpl->notifyRequiredAnimations, [&animation](const NotifierInterface::NotifyId& key) { return key == animation->GetNotifyId(); });
+ animation->ClearAnimator(mSceneGraphBuffers.GetUpdateBufferIndex());
}
void UpdateManager::RemoveAnimation(Animation* animation)
bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds)
{
bool animationActive = false;
- bool animationLooped = false;
auto&& iter = mImpl->animations.Begin();
{
Animation* animation = *iter;
bool finished = false;
- bool looped = false;
+ bool stopped = false;
bool progressMarkerReached = false;
- animation->Update(bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached);
+ animation->Update(bufferIndex, elapsedSeconds, stopped, finished, progressMarkerReached);
animationActive = animationActive || animation->IsActive();
}
mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
- animationLooped = animationLooped || looped;
- // queue the notification on finished or stoped
- if(finished)
+ // queue the notification on finished or stopped
+ if(finished || stopped)
{
mImpl->notifyRequiredAnimations.PushBack(animation->GetNotifyId());
}