X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fanimation%2Fscene-graph-animator.h;h=ae18f067f6341f017611aee68b142ab1d0f53625;hb=c114bfe4714e8f02c54b25e381a41d80bdcb2d93;hp=3fe041bd818d7c6a7b2a843e6ba963771b2ba6af;hpb=d4361f92ab6894ee0ba55131a9d6f7c6a975dfa2;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/animation/scene-graph-animator.h b/dali/internal/update/animation/scene-graph-animator.h index 3fe041b..ae18f06 100644 --- a/dali/internal/update/animation/scene-graph-animator.h +++ b/dali/internal/update/animation/scene-graph-animator.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,6 @@ */ // INTERNAL INCLUDES -#include -#include -#include -#include -#include #include #include #include @@ -31,8 +26,13 @@ #include #include #include +#include +#include +#include +#include +#include #include - +#include namespace Dali { @@ -65,16 +65,39 @@ public: typedef float (*AlphaFunc)(float progress); ///< Definition of an alpha function /** + * Observer to determine when the animator is no longer present + */ + class LifecycleObserver + { + public: + /** + * Called shortly before the animator is destroyed. + */ + virtual void ObjectDestroyed() = 0; + + protected: + /** + * Virtual destructor, no deletion through this interface + */ + virtual ~LifecycleObserver() = default; + }; + + + /** * Constructor. */ AnimatorBase() - : mDurationSeconds(1.0f), - mInitialDelaySeconds(0.0f), + : mLifecycleObserver(nullptr), + mDurationSeconds(1.0f), + mIntervalDelaySeconds(0.0f), + mSpeedFactor(1.0f), + mLoopCount(1), mAlphaFunction(AlphaFunction::DEFAULT), mDisconnectAction(Dali::Animation::BakeFinal), - mActive(false), + mAnimationPlaying(false), mEnabled(true), - mConnectedToSceneGraph(false) + mConnectedToSceneGraph(false), + mAutoReverseEnabled( false ) { } @@ -83,6 +106,20 @@ public: */ virtual ~AnimatorBase() { + if( mLifecycleObserver != nullptr ) + { + mLifecycleObserver->ObjectDestroyed(); + } + } + + void AddLifecycleObserver( LifecycleObserver& observer ) + { + mLifecycleObserver = &observer; + } + + void RemoveLifecycleObserver( LifecycleObserver& observer ) + { + mLifecycleObserver = nullptr; } /** @@ -111,23 +148,57 @@ public: return mDurationSeconds; } + void SetSpeedFactor( float factor ) + { + mSpeedFactor = factor; + } + + void SetLoopCount(int32_t loopCount) + { + mLoopCount = loopCount; + } + + float SetProgress( float progress ) + { + float value = 0.0f; + + if( mAutoReverseEnabled ) + { + if( mSpeedFactor > 0.0f ) + { + value = 1.0f - 2.0f * std::abs( progress - 0.5f ); + } + // Reverse mode + else if( mSpeedFactor < 0.0f ) + { + value = 2.0f * std::abs( progress - 0.5f ); + } + } + else + { + value = progress; + } + + return value; + } + /** * Set the delay before the animator should take effect. * The default is zero i.e. no delay. * @param [in] seconds The delay in seconds. */ - void SetInitialDelay(float seconds) + void SetIntervalDelay(float seconds) { - mInitialDelaySeconds = seconds; + mIntervalDelaySeconds = seconds; } /** - * Retrieve the initial delay of the animator. + * Retrieve the delay before the animator should take effect. * @return The delay in seconds. */ - float GetInitialDelay() const + float GetIntervalDelay() const { - return mInitialDelaySeconds; + return mIntervalDelaySeconds; } /** @@ -148,7 +219,7 @@ public: return mAlphaFunction; } - /* + /** * Applies the alpha function to the specified progress * @param[in] Current progress * @return The progress after the alpha function has been aplied @@ -258,7 +329,7 @@ public: float upperBound(1.0f); float currentT(0.5f); float currentX = EvaluateCubicBezier( controlPoints.x, controlPoints.z, currentT); - while( fabs( progress - currentX ) > tolerance ) + while( fabsf( progress - currentX ) > tolerance ) { if( progress > currentX ) { @@ -305,19 +376,10 @@ public: */ void SetActive( bool active ) { - mActive = active; + mAnimationPlaying = active; } /** - * Retrieve whether the animator has been set to active or not. - * @return The active state. - */ - bool GetActive() const - { - return mActive; - } - - /* * Retrive wheter the animator's target object is valid and on the stage. * @return The enabled state. */ @@ -325,6 +387,16 @@ public: { return mEnabled; } + + /** + * @brief Sets the looping mode. + * @param[in] loopingMode True when the looping mode is AUTO_REVERSE + */ + void SetLoopingMode( bool loopingMode ) + { + mAutoReverseEnabled = loopingMode; + } + /** * Returns wheter the target object of the animator is still valid * or has been destroyed. @@ -356,15 +428,20 @@ protected: return 3.0f*(1.0f-t)*(1.0f-t)*t*p0 + 3.0f*(1.0f-t)*tSquare*p1 + tSquare*t; } + LifecycleObserver* mLifecycleObserver; float mDurationSeconds; - float mInitialDelaySeconds; + float mIntervalDelaySeconds; + float mSpeedFactor; + + int32_t mLoopCount; AlphaFunction mAlphaFunction; Dali::Animation::EndAction mDisconnectAction; ///< EndAction to apply when target object gets disconnected from the stage. - bool mActive:1; ///< Animator is "active" while it's running. + bool mAnimationPlaying:1; ///< whether disconnect has been applied while it's running. bool mEnabled:1; ///< Animator is "enabled" while its target object is valid and on the stage. bool mConnectedToSceneGraph:1; ///< True if ConnectToSceneGraph() has been called in update-thread. + bool mAutoReverseEnabled:1; }; /** @@ -397,7 +474,7 @@ public: animatorFunction ); animator->SetAlphaFunction( alphaFunction ); - animator->SetInitialDelay( timePeriod.delaySeconds ); + animator->SetIntervalDelay( timePeriod.delaySeconds ); animator->SetDuration( timePeriod.durationSeconds ); return animator; @@ -439,13 +516,12 @@ public: virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner ) { // If we are active, then bake the value if required - if ( mActive && mDisconnectAction != Dali::Animation::Discard ) + if ( mAnimationPlaying && 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; mEnabled = false; } @@ -462,11 +538,18 @@ public: */ virtual void Update( BufferIndex bufferIndex, float progress, bool bake ) { - float alpha = ApplyAlphaFunction(progress); + if( mLoopCount >= 0 ) + { + // Update the progress value + progress = SetProgress( progress ); + } + + float alpha = ApplyAlphaFunction( progress ); const PropertyType& current = mPropertyAccessor.Get( bufferIndex ); - const PropertyType result = (*mAnimatorFunction)( alpha, current ); + // need to cast the return value in case property is integer + const PropertyType result = static_cast( (*mAnimatorFunction)( alpha, current ) ); if ( bake ) { mPropertyAccessor.Bake( bufferIndex, result ); @@ -550,7 +633,7 @@ public: animatorFunction ); animator->SetAlphaFunction( alphaFunction ); - animator->SetInitialDelay( timePeriod.delaySeconds ); + animator->SetIntervalDelay( timePeriod.delaySeconds ); animator->SetDuration( timePeriod.durationSeconds ); return animator; @@ -592,13 +675,12 @@ public: virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner ) { // If we are active, then bake the value if required - if ( mActive && mDisconnectAction != Dali::Animation::Discard ) + if ( mAnimationPlaying && 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; mEnabled = false; } @@ -615,12 +697,18 @@ public: */ virtual void Update( BufferIndex bufferIndex, float progress, bool bake ) { - float alpha = ApplyAlphaFunction(progress); + if( mLoopCount >= 0 ) + { + // Update the progress value + progress = SetProgress( progress ); + } - const T& current = mPropertyAccessor.Get( bufferIndex ); + float alpha = ApplyAlphaFunction( progress ); - const T result = (*mAnimatorFunction)( alpha, current ); + const T& current = mPropertyAccessor.Get( bufferIndex ); + // need to cast the return value in case property is integer + T result = static_cast( (*mAnimatorFunction)( alpha, current ) ); if ( bake ) { @@ -698,14 +786,9 @@ struct AnimatorFunctionBase return property; } - virtual float operator()(float progress, const int& property) + virtual float operator()(float progress, const int32_t& property) { - return property; - } - - virtual float operator()(float progress, const unsigned int& property) - { - return property; + return static_cast( property ); } virtual float operator()(float progress, const float& property) @@ -744,12 +827,13 @@ struct AnimateByInteger : public AnimatorFunctionBase } using AnimatorFunctionBase::operator(); - float operator()(float alpha, const int& property) + float operator()(float alpha, const int32_t& property) { - return int(property + mRelative * alpha + 0.5f ); + // integers need to be correctly rounded + return roundf(static_cast( property ) + static_cast( mRelative ) * alpha ); } - int mRelative; + int32_t mRelative; }; struct AnimateToInteger : public AnimatorFunctionBase @@ -760,12 +844,13 @@ struct AnimateToInteger : public AnimatorFunctionBase } using AnimatorFunctionBase::operator(); - float operator()(float alpha, const int& property) + float operator()(float alpha, const int32_t& property) { - return int(property + ((mTarget - property) * alpha) + 0.5f); + // integers need to be correctly rounded + return roundf(static_cast( property ) + (static_cast(mTarget - property) * alpha) ); } - int mTarget; + int32_t mTarget; }; struct AnimateByFloat : public AnimatorFunctionBase @@ -1036,13 +1121,13 @@ struct KeyFrameIntegerFunctor : public AnimatorFunctionBase } using AnimatorFunctionBase::operator(); - float operator()(float progress, const int& property) + float operator()(float progress, const int32_t& property) { if(mKeyFrames->IsActive(progress)) { - return mKeyFrames->GetValue(progress, mInterpolation); + return static_cast( mKeyFrames->GetValue(progress, mInterpolation) ); } - return property; + return static_cast( property ); } KeyFrameIntegerPtr mKeyFrames;