[problem] Animations can be created, therefore creating animators, but not played. If the
property owner was disconnected before the animation was played, the disconnect
action was still applied.
[solution] Set a state on the animator to state whether it is active or not and only apply
the disconnect action (if required) if it was active.
Change-Id: Idd615938182a22f0fd91425bc2d2e83aeea18480
DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
}
+ // Don't play the animation: disconnect action should not be applied
+ {
+ Actor actor = Actor::New();
+ stage.Add(actor);
+
+ // Build the animation
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+
+ Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+ animation.MoveTo(actor, targetPosition, AlphaFunctions::Linear);
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*0.5f*1000.0f)/*Only half the animation*/);
+
+ actor.Unparent();
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
+ }
+
END_TEST;
}
{
mElapsedSeconds = mPlayRange.y * mDurationSeconds;
}
+
+ SetAnimatorsActive( true );
}
void Animation::PlayFrom( float progress )
{
mElapsedSeconds = progress * mDurationSeconds;
mState = Playing;
+
+ SetAnimatorsActive( true );
}
}
}
}
- UpdateAnimators(bufferIndex, true/*bake the final result*/);
+ UpdateAnimators( bufferIndex, true/*bake the final result*/, true /*animation finished*/ );
+}
+
+void Animation::SetAnimatorsActive( bool active )
+{
+ for ( AnimatorIter iter = mAnimators.Begin(), endIter = mAnimators.End(); iter != endIter; ++iter )
+ {
+ (*iter)->SetActive( active );
+ }
}
bool Animation::Stop(BufferIndex bufferIndex)
if( mEndAction != Dali::Animation::Discard )
{
Bake( bufferIndex, mEndAction );
+
+ // Animators are automatically set to inactive in Bake
+ }
+ else
+ {
+ SetAnimatorsActive( false );
}
// The animation has now been played to completion
if (mEndAction != Dali::Animation::Discard)
{
Bake( bufferIndex, mEndAction );
+
+ // Animators are automatically set to inactive in Bake
+ }
+ else
+ {
+ SetAnimatorsActive( false );
}
}
( mSpeedFactor < 0.0f && mElapsedSeconds < playRangeSeconds.x ))
);
- UpdateAnimators(bufferIndex, animationFinished && (mEndAction != Dali::Animation::Discard));
+ UpdateAnimators(bufferIndex, animationFinished && (mEndAction != Dali::Animation::Discard), animationFinished);
if (animationFinished)
{
return animationFinished;
}
-void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake)
+void Animation::UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished )
{
float elapsedSecondsClamped = Clamp( mElapsedSeconds, mPlayRange.x * mDurationSeconds,mPlayRange.y * mDurationSeconds );
for ( AnimatorIter iter = mAnimators.Begin(); iter != mAnimators.End(); )
applied = animator->Update(bufferIndex, progress, bake);
}
+ if ( animationFinished )
+ {
+ animator->SetActive( false );
+ }
+
// Animators are automatically removed, when orphaned from animatable scene objects.
if (!applied)
{
* Helper for Update, also used to bake when the animation is stopped or destroyed.
* @param[in] bufferIndex The buffer to update.
* @param[in] bake True if the final result should be baked.
+ * @param[in] animationFinished True if the animation has finished.
*/
- void UpdateAnimators(BufferIndex bufferIndex, bool bake);
+ void UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished );
/**
* Helper function to bake the result of the animation when it is stopped or
*/
void Bake(BufferIndex bufferIndex, EndAction action );
+ /**
+ * Helper function to set active state of animators.
+ * @param[in] active Every animator is set to this state
+ */
+ void SetAnimatorsActive( bool active );
+
// Undefined
Animation(const Animation&);
: mDurationSeconds(1.0f),
mInitialDelaySeconds(0.0f),
mAlphaFunc(AlphaFunctions::Linear),
- mDisconnectAction(Dali::Animation::BakeFinal)
+ mDisconnectAction(Dali::Animation::BakeFinal),
+ mActive(false)
{
}
/**
* Whether to bake the animation if attached property owner is disconnected.
+ * Property is only baked if the animator is active.
* @param [in] action The disconnect action.
*/
void SetDisconnectAction( Dali::Animation::EndAction action )
}
/**
+ * Retrieve the disconnect action of an animator.
+ * @return The disconnect action.
+ */
+ Dali::Animation::EndAction GetDisconnectAction() const
+ {
+ return mDisconnectAction;
+ }
+
+ /**
+ * Whether the animator is active or not.
+ * @param [in] action The disconnect action.
+ * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
+ * @note When the property owner is disconnected, the active state is set to false.
+ */
+ void SetActive( bool active )
+ {
+ mActive = active;
+ }
+
+ /**
+ * Retrieve whether the animator has been set to active or not.
+ * @return The active state.
+ */
+ bool GetActive() const
+ {
+ return mActive;
+ }
+
+ /**
* This must be called when the animator is attached to the scene-graph.
* @pre The animatable scene object must also be attached to the scene-graph.
* @param[in] propertyOwner The scene-object that owns the animatable property.
AlphaFunc mAlphaFunc;
Dali::Animation::EndAction mDisconnectAction;
+ bool mActive:1;
};
/**
*/
virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
{
- // Bake the value if required
- if ( mDisconnectAction != Dali::Animation::Discard )
+ // If we are active, then bake the value if required
+ if ( mActive && mDisconnectAction != Dali::Animation::Discard )
{
// Bake to target-value if BakeFinal, otherwise bake current value
Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
}
+ mActive = false;
mPropertyOwner = NULL;
mPropertyAccessor.Reset();
}
/**
* @brief Set the disconnect action.
*
- * If any of the animated property owners are disconnected from the stage, then this action is performed.
+ * If any of the animated property owners are disconnected from the stage while the animation is being played, then this action is performed.
* Default action is to BakeFinal.
* @param[in] disconnectAction The disconnect action.
*/