[Problem] If property owner is removed from the stage and even if Bake is set as the EndAction,
the value is never baked.
[Cause] We just disconnect with the current value set.
[Solution] If one of the bake options is selected then we jump to the final value
Destroy end action deprecated as it is redundant
Change-Id: I9aab5cf6676a6fb1bcda9e9c90c644a3f3a1c57c
END_TEST;
}
-int UtcDaliAnimationGetDestroyAction(void)
+int UtcDaliAnimationSetDisconnectAction(void)
+{
+ TestApplication application;
+ Stage stage( Stage::GetCurrent() );
+
+ // Default: BakeFinal
+ {
+ Actor actor = Actor::New();
+ stage.Add(actor);
+
+ // Build the animation
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ DALI_TEST_CHECK(animation.GetDisconnectAction() == Animation::BakeFinal);
+
+ Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+ animation.MoveTo(actor, targetPosition, AlphaFunctions::Linear);
+
+ // Start the animation
+ animation.Play();
+
+ 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(), targetPosition, TEST_LOCATION );
+ }
+
+ // Bake
+ {
+ Actor actor = Actor::New();
+ stage.Add(actor);
+
+ // Build the animation
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ animation.SetDisconnectAction( Animation::Bake );
+
+ Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+ animation.MoveTo(actor, targetPosition, AlphaFunctions::Linear);
+
+ // Start the animation
+ animation.Play();
+
+ 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(), targetPosition*0.5f, TEST_LOCATION );
+ }
+
+ // Discard
+ {
+ Actor actor = Actor::New();
+ stage.Add(actor);
+
+ // Build the animation
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ animation.SetDisconnectAction( Animation::Discard );
+
+ Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+ animation.MoveTo(actor, targetPosition, AlphaFunctions::Linear);
+
+ // Start the animation
+ animation.Play();
+
+ 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;
+}
+
+int UtcDaliAnimationGetDisconnectAction(void)
{
TestApplication application;
Animation animation = Animation::New(1.0f);
- DALI_TEST_CHECK(animation.GetDestroyAction() == Animation::Bake); // default!
+ DALI_TEST_CHECK(animation.GetDisconnectAction() == Animation::BakeFinal); // default!
- animation.SetDestroyAction(Animation::Discard);
- DALI_TEST_CHECK(animation.GetDestroyAction() == Animation::Discard);
+ animation.SetDisconnectAction(Animation::Discard);
+ DALI_TEST_CHECK(animation.GetDisconnectAction() == Animation::Discard);
- animation.SetDestroyAction(Animation::BakeFinal);
- DALI_TEST_CHECK(animation.GetDestroyAction() == Animation::BakeFinal);
+ animation.SetDisconnectAction(Animation::Bake);
+ DALI_TEST_CHECK(animation.GetDisconnectAction() == Animation::Bake);
END_TEST;
}
// Build the animation
float durationSeconds(1.0f);
Animation animation = Animation::New(durationSeconds);
+ animation.SetDisconnectAction( Animation::Discard );
Vector3 targetPosition(100.0f, 100.0f, 100.0f);
animation.MoveTo(actor, targetPosition, AlphaFunctions::Linear);
TypeAction action2( mType, Dali::Animation::ACTION_STOP, &Animation::DoAction );
TypeAction action3( mType, Dali::Animation::ACTION_PAUSE, &Animation::DoAction );
+const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
+const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
+
} // anon namespace
AnimationPtr Animation::New(float durationSeconds)
{
- return New(durationSeconds, Dali::Animation::Bake, Dali::Animation::Bake, Dali::AlphaFunctions::Linear);
-}
-
-AnimationPtr Animation::New(float durationSeconds, EndAction endAction, EndAction destroyAction)
-{
- return New(durationSeconds, endAction, destroyAction, Dali::AlphaFunctions::Linear);
-}
-
-AnimationPtr Animation::New(float durationSeconds, EndAction endAction, EndAction destroyAction, AlphaFunction alpha)
-{
ThreadLocalStorage& tls = ThreadLocalStorage::Get();
UpdateManager& updateManager = tls.GetUpdateManager();
AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
- AnimationPtr progress = new Animation( updateManager, playlist, durationSeconds, endAction, destroyAction, alpha );
+ AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
// Second-phase construction
- progress->Initialize();
+ animation->Initialize();
- return progress;
+ return animation;
}
-Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction destroyAction, AlphaFunction defaultAlpha )
+Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
: mUpdateManager( updateManager ),
mPlaylist( playlist ),
mAnimation( NULL ),
mIsLooping( false ),
mPlayRange( Vector2(0.0f,1.0f)),
mEndAction( endAction ),
- mDestroyAction( destroyAction ),
+ mDisconnectAction( disconnectAction ),
mDefaultAlpha( defaultAlpha )
{
}
DALI_ASSERT_DEBUG( mAnimation == NULL );
// Create a new animation, temporarily owned
- SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDestroyAction );
+ SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
// Keep a const pointer to the animation.
mAnimation = animation;
return mEndAction;
}
-void Animation::SetDestroyAction(EndAction action)
+void Animation::SetDisconnectAction(EndAction action)
{
// Cache for public getters
- mDestroyAction = action;
+ mDisconnectAction = action;
// mAnimation is being used in a separate thread; queue a message to set the value
- SetDestroyActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
+ SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
}
-Dali::Animation::EndAction Animation::GetDestroyAction() const
+Dali::Animation::EndAction Animation::GetDisconnectAction() const
{
// This is not animatable; the cached value is up-to-date.
- return mDestroyAction;
+ return mDisconnectAction;
}
void Animation::Play()
static AnimationPtr New(float durationSeconds);
/**
- * Create a new Animation object.
- * @param[in] durationSeconds The duration of the animation.
- * @param[in] endAction The action to perform when the animation ends.
- * @param[in] destroyAction The action to perform when the animation ends.
- * @return A smart-pointer to the newly allocated Animation.
- */
- static AnimationPtr New(float durationSeconds, EndAction endAction, EndAction destroyAction);
-
- /**
- * Create a new Animation object.
- * @param[in] durationSeconds The duration of the animation.
- * @param[in] endAction The action to perform when the animation ends.
- * @param[in] destroyAction The action to perform when the animation ends.
- * @param[in] alpha The default alpha function to apply to animators.
- * @return A smart-pointer to the newly allocated Animation.
- */
- static AnimationPtr New(float durationSeconds, EndAction endAction, EndAction destroyAction, AlphaFunction alpha);
-
- /**
* Set the duration of an animation.
* @pre durationSeconds must be greater than zero.
* @param[in] seconds The duration in seconds.
EndAction GetEndAction() const;
/**
- * Set the destroy action of the animation.
- * @param[in] action The destroy action.
+ * Set the disconnect action of the animation.
+ * @param[in] action The disconnect action.
*/
- void SetDestroyAction(EndAction action);
+ void SetDisconnectAction(EndAction action);
/**
- * Returns the destroy action of the animation.
+ * Returns the disconnect action of the animation.
*/
- EndAction GetDestroyAction() const;
+ EndAction GetDisconnectAction() const;
/**
* Set the default alpha function for an animation.
* @param[in] playlist The list of currently playing animations.
* @param[in] durationSeconds The duration of the animation in seconds.
* @param[in] endAction The action to perform when the animation ends.
- * @param[in] destroyAction The action to perform when the animation is destroyed.
+ * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
* @param[in] defaultAlpha The default alpha function to apply to animators.
*/
Animation( SceneGraph::UpdateManager& updateManager,
AnimationPlaylist& playlist,
float durationSeconds,
EndAction endAction,
- EndAction destroyAction,
+ EndAction disconnectAction,
AlphaFunction defaultAlpha);
/**
bool mIsLooping;
Vector2 mPlayRange;
EndAction mEndAction;
- EndAction mDestroyAction;
+ EndAction mDisconnectAction;
AlphaFunction mDefaultAlpha;
};
return progress; // linear
}
-Animation::Animation(float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, Dali::Animation::EndAction endAction, Dali::Animation::EndAction destroyAction)
+Animation::Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, Dali::Animation::EndAction endAction, Dali::Animation::EndAction disconnectAction )
: mDurationSeconds(durationSeconds),
mSpeedFactor( speedFactor ),
mLooping(isLooping),
mEndAction(endAction),
- mDestroyAction(destroyAction),
+ mDisconnectAction(disconnectAction),
mState(Stopped),
mElapsedSeconds(playRange.x*mDurationSeconds),
mPlayCount(0),
mEndAction = action;
}
-void Animation::SetDestroyAction(Dali::Animation::EndAction action)
+void Animation::SetDisconnectAction(Dali::Animation::EndAction action)
{
- mDestroyAction = action;
+ if ( mDisconnectAction != action )
+ {
+ mDisconnectAction = action;
+
+ for ( AnimatorIter iter = mAnimators.Begin(), endIter = mAnimators.End(); iter != endIter; ++iter )
+ {
+ (*iter)->SetDisconnectAction( action );
+ }
+ }
}
void Animation::SetPlayRange( const Vector2& range )
{
if (mState == Playing || mState == Paused)
{
- if (mDestroyAction != Dali::Animation::Discard)
+ if (mEndAction != Dali::Animation::Discard)
{
- Bake( bufferIndex, mDestroyAction );
+ Bake( bufferIndex, mEndAction );
}
}
void Animation::AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner )
{
animator->Attach( propertyOwner );
+ animator->SetDisconnectAction( mDisconnectAction );
mAnimators.PushBack( animator );
}
* @param[in] playRange Minimum and maximum progress between which the animation will play.
* @param[in] isLooping Whether the animation will loop.
* @param[in] endAction The action to perform when the animation ends.
- * @param[in] destroyAction The action to perform when the animation is destroyed.
+ * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
* @return A new Animation
*/
- static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction destroyAction )
+ static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction )
{
- return new Animation( durationSeconds, speedFactor, playRange, isLooping, endAction, destroyAction );
+ return new Animation( durationSeconds, speedFactor, playRange, isLooping, endAction, disconnectAction );
}
/**
}
/**
- * Set the destroy action of the animation.
+ * Set the disconnect action of the animation when connected objects are disconnected.
* This action is performed during the next update when
- * the animation is destroyed.
- * @param[in] action The destroy action.
+ * the connected object is disconnected.
+ * @param[in] action The disconnect action.
*/
- void SetDestroyAction(EndAction action);
+ void SetDisconnectAction(EndAction action);
/**
* Retrieve the action performed when the animation is destroyed.
* @return The destroy action.
*/
- EndAction GetDestroyAction()
+ EndAction GetDisconnectAction()
{
- return mDestroyAction;
+ return mDisconnectAction;
}
/**
/**
* Called shortly before the animation is destroyed.
- * @param[in] bufferIndex The buffer to update when mDestroyAction == Bake.
+ * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
*/
void OnDestroy(BufferIndex bufferIndex);
/**
* Protected constructor. See New()
*/
- Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction destroyAction );
+ Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction );
private:
float mSpeedFactor;
bool mLooping;
EndAction mEndAction;
- EndAction mDestroyAction;
+ EndAction mDisconnectAction;
State mState;
float mElapsedSeconds;
new (slot) LocalType( &animation, &Animation::SetEndAction, action );
}
-inline void SetDestroyActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
+inline void SetDisconnectActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
{
typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
// Construct message in the message queue memory; note that delete should not be called on the return value
- new (slot) LocalType( &animation, &Animation::SetDestroyAction, action );
+ new (slot) LocalType( &animation, &Animation::SetDisconnectAction, action );
}
inline void SetCurrentProgressMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
#include <dali/internal/update/common/property-base.h>
#include <dali/internal/common/observer-pointer.h>
#include <dali/public-api/animation/alpha-functions.h>
+#include <dali/public-api/animation/animation.h>
#include <dali/public-api/animation/time-period.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/math/quaternion.h>
: mDurationSeconds(1.0f),
mInitialDelaySeconds(0.0f),
mAlphaFunc(AlphaFunctions::Linear),
- mRelative(false)
+ mDisconnectAction(Dali::Animation::BakeFinal)
{
}
}
/**
+ * Whether to bake the animation if attached property owner is disconnected.
+ * @param [in] action The disconnect action.
+ */
+ void SetDisconnectAction( Dali::Animation::EndAction action )
+ {
+ mDisconnectAction = action;
+ }
+
+ /**
* 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;
- bool mRelative;
+ Dali::Animation::EndAction mDisconnectAction;
};
/**
{
mPropertyAccessor.Set( bufferIndex, result );
}
+
+ mCurrentProgress = progress;
}
return IsAttached(); // return false if orphaned
*/
virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
{
+ // Bake the value if required
+ if ( mDisconnectAction != Dali::Animation::Discard )
+ {
+ // Bake to target-value if BakeFinal, otherwise bake current value
+ Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
+ }
+
mPropertyOwner = NULL;
mPropertyAccessor.Reset();
}
AnimatorFunction animatorFunction )
: mPropertyOwner( NULL ),
mPropertyAccessor( property ),
- mAnimatorFunction( animatorFunction )
+ mAnimatorFunction( animatorFunction ),
+ mCurrentProgress( 0.0f )
{
}
PropertyAccessorType mPropertyAccessor;
AnimatorFunction mAnimatorFunction;
+ float mCurrentProgress;
};
} // namespace SceneGraph
void Animation::SetDestroyAction(Dali::Animation::EndAction destroyAction)
{
- GetImplementation(*this).SetDestroyAction(destroyAction);
+ // Deprecated
+ GetImplementation(*this).SetEndAction(destroyAction);
}
Dali::Animation::EndAction Animation::GetDestroyAction() const
{
- return GetImplementation(*this).GetDestroyAction();
+ // Deprecated
+ return GetImplementation(*this).GetEndAction();
+}
+
+void Animation::SetDisconnectAction( Animation::EndAction disconnectAction )
+{
+ GetImplementation(*this).SetDisconnectAction( disconnectAction );
+}
+
+Animation::EndAction Animation::GetDisconnectAction() const
+{
+ return GetImplementation(*this).GetDisconnectAction();
}
void Animation::SetDefaultAlphaFunction(AlphaFunction alpha)
/**
* @brief Set the end action of the animation.
*
- * This action is performed when the animation ends.
+ * This action is performed when the animation ends or if it is stopped.
* Default end action is bake
* @param[in] action The end action.
*/
EndAction GetEndAction() const;
/**
- * @brief Set the destroy action of the animation.
+ * @brief Deprecated
*
- * If the animation is destroyed this action is performed on the following update.
- * Default destroy action is bake
* @param[in] action The destroy action.
+ *
+ * @deprecated Use SetEndAction
*/
void SetDestroyAction(EndAction action);
/**
- * @brief Returns the destroy action of the animation.
+ * @brief Deprecated
*
* @return The destroy action.
+ *
+ * @deprecated Use GetEndAction
*/
EndAction GetDestroyAction() const;
/**
+ * @brief Set the disconnect action.
+ *
+ * If any of the animated property owners are disconnected from the stage, then this action is performed.
+ * Default action is to BakeFinal.
+ * @param[in] disconnectAction The disconnect action.
+ */
+ void SetDisconnectAction( EndAction disconnectAction );
+
+ /**
+ * @brief Returns the disconnect action.
+ *
+ * @return The disconnect action.
+ */
+ EndAction GetDisconnectAction() const;
+
+ /**
* @brief Set the default alpha function for an animation.
*
* This is applied to individual property animations, if no further alpha functions are supplied.