Add logs to check the messages processed by the update thread
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animation.cpp
index 3f33f3c..1fed088 100644 (file)
@@ -24,6 +24,8 @@
 // INTERNAL INCLUDES
 #include <dali/internal/common/memory-pool-object-allocator.h>
 #include <dali/internal/render/common/performance-monitor.h>
+#include <dali/public-api/math/math-utils.h>
+#include <dali/integration-api/debug.h>
 
 namespace //Unnamed namespace
 {
@@ -45,7 +47,7 @@ inline void WrapInPlayRange( float& elapsed, const Dali::Vector2& playRangeSecon
 /// Compares the end times of the animators and if the end time is less, then it is moved earlier in the list. If end times are the same, then no change.
 bool CompareAnimatorEndTimes( const Dali::Internal::SceneGraph::AnimatorBase* lhs, const Dali::Internal::SceneGraph::AnimatorBase* rhs )
 {
-  return ( ( lhs->GetInitialDelay() + lhs->GetDuration() ) < ( rhs->GetInitialDelay() + rhs->GetDuration() ) );
+  return ( ( lhs->GetIntervalDelay() + lhs->GetDuration() ) < ( rhs->GetIntervalDelay() + rhs->GetDuration() ) );
 }
 
 } // unnamed namespace
@@ -65,16 +67,20 @@ Animation* Animation::New( float durationSeconds, float speedFactor, const Vecto
 }
 
 Animation::Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, Dali::Animation::EndAction endAction, Dali::Animation::EndAction disconnectAction )
-: mDurationSeconds(durationSeconds),
+: mPlayRange( playRange ),
+  mDurationSeconds( durationSeconds ),
+  mDelaySeconds( 0.0f ),
+  mElapsedSeconds( playRange.x*mDurationSeconds ),
   mSpeedFactor( speedFactor ),
+  mProgressMarker( 0.0f ),
+  mPlayedCount( 0 ),
+  mLoopCount(loopCount),
+  mCurrentLoop(0),
   mEndAction(endAction),
   mDisconnectAction(disconnectAction),
   mState(Stopped),
-  mElapsedSeconds(playRange.x*mDurationSeconds),
-  mPlayedCount(0),
-  mLoopCount(loopCount),
-  mCurrentLoop(0),
-  mPlayRange( playRange )
+  mProgressReachedSignalRequired( false ),
+  mAutoReverseEnabled( false )
 {
 }
 
@@ -92,6 +98,15 @@ void Animation::SetDuration(float durationSeconds)
   mDurationSeconds = durationSeconds;
 }
 
+void Animation::SetProgressNotification( float progress )
+{
+  mProgressMarker = progress;
+  if ( mProgressMarker > 0.0f )
+  {
+    mProgressReachedSignalRequired = true;
+  }
+}
+
 void Animation::SetLoopCount(int loopCount)
 {
   mLoopCount = loopCount;
@@ -138,9 +153,13 @@ void Animation::SetPlayRange( const Vector2& range )
 
 void Animation::Play()
 {
+  DALI_LOG_ERROR("Scene Graph Animation::Play: Before stable_sort\n");
+
   // Sort according to end time with earlier end times coming first, if the end time is the same, then the animators are not moved
   std::stable_sort( mAnimators.Begin(), mAnimators.End(), CompareAnimatorEndTimes );
 
+  DALI_LOG_ERROR("Scene Graph Animation::Play: After stable_sort\n");
+
   mState = Playing;
 
   if ( mSpeedFactor < 0.0f && mElapsedSeconds <= mPlayRange.x*mDurationSeconds )
@@ -148,8 +167,12 @@ void Animation::Play()
     mElapsedSeconds = mPlayRange.y * mDurationSeconds;
   }
 
+  DALI_LOG_ERROR("Scene Graph Animation::Play: Before SetAnimatorsActive\n");
+
   SetAnimatorsActive( true );
 
+  DALI_LOG_ERROR("Scene Graph Animation::Play: After SetAnimatorsActive\n");
+
   mCurrentLoop = 0;
 }
 
@@ -166,6 +189,24 @@ void Animation::PlayFrom( float progress )
   }
 }
 
+void Animation::PlayAfter( float delaySeconds )
+{
+  if( mState != Playing )
+  {
+    mDelaySeconds = delaySeconds;
+    mState = Playing;
+
+    if ( mSpeedFactor < 0.0f && mElapsedSeconds <= mPlayRange.x*mDurationSeconds )
+    {
+      mElapsedSeconds = mPlayRange.y * mDurationSeconds;
+    }
+
+    SetAnimatorsActive( true );
+
+    mCurrentLoop = 0;
+  }
+}
+
 void Animation::Pause()
 {
   if (mState == Playing)
@@ -248,15 +289,29 @@ void Animation::OnDestroy(BufferIndex bufferIndex)
   mState = Destroyed;
 }
 
-void Animation::AddAnimator( AnimatorBase* animator )
+void Animation::SetLoopingMode( bool loopingMode )
+{
+  mAutoReverseEnabled = loopingMode;
+
+  for ( AnimatorIter iter = mAnimators.Begin(), endIter = mAnimators.End(); iter != endIter; ++iter )
+  {
+    // Send some variables together to figure out the Animation status
+    (*iter)->SetSpeedFactor( mSpeedFactor );
+    (*iter)->SetLoopCount( mLoopCount );
+
+    (*iter)->SetLoopingMode( loopingMode );
+  }
+}
+
+void Animation::AddAnimator( OwnerPointer<AnimatorBase>& animator )
 {
   animator->ConnectToSceneGraph();
   animator->SetDisconnectAction( mDisconnectAction );
 
-  mAnimators.PushBack( animator );
+  mAnimators.PushBack( animator.Release() );
 }
 
-void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished )
+void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached )
 {
   looped = false;
   finished = false;
@@ -270,21 +325,43 @@ void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& loop
   // The animation must still be applied when Paused/Stopping
   if (mState == Playing)
   {
-    mElapsedSeconds += elapsedSeconds * mSpeedFactor;
+    // If there is delay time before Animation starts, wait the Animation until mDelaySeconds.
+    if( mDelaySeconds > 0.0f )
+    {
+      float reduceSeconds = fabsf( elapsedSeconds * mSpeedFactor );
+      if( reduceSeconds > mDelaySeconds )
+      {
+        if( mSpeedFactor < 0.0f )
+        {
+          mElapsedSeconds -= reduceSeconds - mDelaySeconds;
+        }
+        else
+        {
+          mElapsedSeconds += reduceSeconds - mDelaySeconds;
+        }
+        mDelaySeconds = 0.0f;
+      }
+      else
+      {
+        mDelaySeconds -= reduceSeconds;
+      }
+    }
+    else
+    {
+      mElapsedSeconds += ( elapsedSeconds * mSpeedFactor );
+    }
+
+    if ( mProgressReachedSignalRequired && ( mElapsedSeconds >= mProgressMarker ) )
+    {
+      // The application should be notified by NotificationManager, in another thread
+      progressReached = true;
+      mProgressReachedSignalRequired = false;
+    }
   }
 
   Vector2 playRangeSeconds = mPlayRange * mDurationSeconds;
 
-  if( 0 == mLoopCount )
-  {
-    // loop forever
-    WrapInPlayRange(mElapsedSeconds, playRangeSeconds);
-
-    UpdateAnimators(bufferIndex, false, false);
-
-    // don't increment mPlayedCount as event loop tracks this to indicate animation finished (end of all loops)
-  }
-  else if( mCurrentLoop < mLoopCount - 1) // '-1' here so last loop iteration uses play once below
+  if( 0 == mLoopCount || mCurrentLoop < mLoopCount - 1) // '-1' here so last loop iteration uses play once below
   {
     // looping
     looped =  (mState == Playing                                                 &&
@@ -293,11 +370,15 @@ void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& loop
 
     WrapInPlayRange( mElapsedSeconds, playRangeSeconds );
 
-    UpdateAnimators(bufferIndex, false, false);
+    UpdateAnimators(bufferIndex, false, false );
 
     if(looped)
     {
-      ++mCurrentLoop;
+      if( mLoopCount != 0 )
+      {
+        ++mCurrentLoop;
+      }
+      mProgressReachedSignalRequired = mProgressMarker > 0.0f;
       // don't increment mPlayedCount until the finished final loop
     }
   }
@@ -309,7 +390,7 @@ void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& loop
                  ( mSpeedFactor < 0.0f && mElapsedSeconds < playRangeSeconds.x )) );
 
     // update with bake if finished
-    UpdateAnimators(bufferIndex, finished && (mEndAction != Dali::Animation::Discard), finished);
+    UpdateAnimators(bufferIndex, finished && (mEndAction != Dali::Animation::Discard), finished );
 
     if(finished)
     {
@@ -323,6 +404,7 @@ void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& loop
         DALI_ASSERT_DEBUG(mCurrentLoop == mLoopCount);
       }
 
+      mProgressReachedSignalRequired = mProgressMarker > 0.0f;
       mElapsedSeconds = playRangeSeconds.x;
       mState = Stopped;
     }
@@ -349,15 +431,16 @@ void Animation::UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animat
     {
       if( animator->IsEnabled() )
       {
-        const float initialDelay( animator->GetInitialDelay() );
-        if( elapsedSecondsClamped >= initialDelay )
+        const float intervalDelay( animator->GetIntervalDelay() );
+
+        if( elapsedSecondsClamped >= intervalDelay )
         {
           // Calculate a progress specific to each individual animator
           float progress(1.0f);
           const float animatorDuration = animator->GetDuration();
           if (animatorDuration > 0.0f) // animators can be "immediate"
           {
-            progress = Clamp((elapsedSecondsClamped - initialDelay) / animatorDuration, 0.0f , 1.0f );
+            progress = Clamp((elapsedSecondsClamped - intervalDelay) / animatorDuration, 0.0f , 1.0f );
           }
           animator->Update(bufferIndex, progress, bake);
         }