From f69222d4812124d8788917283a41dac859b309cc Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Thu, 18 May 2017 09:56:19 +0100 Subject: [PATCH] [Tizen] (Animation) Ensure TimePeriod is taken into account when setting properties on the event-thread as well Also added some more test cases to test the AnimateTo event side properties Change-Id: Ibeeb8f01316034715eb9121dfec61c18e18eeb5d --- automated-tests/src/dali/utc-Dali-Animation.cpp | 79 +++++++++++++++++++++- automated-tests/src/dali/utc-Dali-TypeRegistry.cpp | 10 +++ dali/internal/event/animation/animation-impl.cpp | 42 +++++------- dali/internal/event/animation/animation-impl.h | 25 ++++++- 4 files changed, 126 insertions(+), 30 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Animation.cpp b/automated-tests/src/dali/utc-Dali-Animation.cpp index 2a46bf5..980c108 100644 --- a/automated-tests/src/dali/utc-Dali-Animation.cpp +++ b/automated-tests/src/dali/utc-Dali-Animation.cpp @@ -10240,6 +10240,7 @@ int UtcDaliAnimationCustomIntProperty(void) Property::Index index = actor.RegisterProperty("anIndex", startValue); DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< int >( actor, index ), startValue, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< int >( index ), startValue, TEST_LOCATION ); // Build the animation float durationSeconds(1.0f); @@ -10249,6 +10250,9 @@ int UtcDaliAnimationCustomIntProperty(void) // Start the animation animation.Play(); + // Target value should be retrievable straight away + DALI_TEST_EQUALS( actor.GetProperty< int >( index ), 20, TEST_LOCATION ); + bool signalReceived(false); AnimationFinishCheck finishCheck(signalReceived); animation.FinishedSignal().Connect(&application, finishCheck); @@ -10268,6 +10272,7 @@ int UtcDaliAnimationCustomIntProperty(void) application.SendNotification(); finishCheck.CheckSignalReceived(); DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< int >( actor, index ), 20, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< int >( index ), 20, TEST_LOCATION ); END_TEST; } @@ -10642,6 +10647,12 @@ int UtcDaliAnimationTimePeriodOrder(void) application.Render(); DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + + ////////////////////////////////////////////////////////////////////////////////// tet_infoline( "With two AnimateTo calls" ); @@ -10650,34 +10661,74 @@ int UtcDaliAnimationTimePeriodOrder(void) animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 10.0f, TimePeriod( 1.0f, 1.0f ) ); animation.Play(); + tet_infoline( "The target position should change instantly" ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 100.0f, TEST_LOCATION ); + application.SendNotification(); application.Render(5000); // After the animation is complete DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 100.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 100.0f, TEST_LOCATION ); + + ////////////////////////////////////////////////////////////////////////////////// tet_infoline( "Same animation again but in a different order - should yield the same result" ); actor.SetX( 0.0f ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + application.SendNotification(); application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + animation = Animation::New( 0.0f ); animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 10.0f, TimePeriod( 1.0f, 1.0f ) ); animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 100.0f, TimePeriod( 3.0f, 1.0f ) ); animation.Play(); + tet_infoline( "The target position should change instantly" ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 100.0f, TEST_LOCATION ); + application.SendNotification(); application.Render(5000); // After the animation is complete DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 100.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 100.0f, TEST_LOCATION ); + + END_TEST; +} - tet_infoline( "Now with several AnimateTo calls" ); +int UtcDaliAnimationTimePeriodOrderSeveralAnimateToCalls(void) +{ + tet_infoline("Animate the same property with different time periods and ensure it runs correctly and ends up in the right place with several AnimateTo calls" ); + + TestApplication application; + + Actor actor = Actor::New(); + Stage::GetCurrent().Add( actor ); - actor.SetX( 0.0f ); application.SendNotification(); application.Render(); - animation = Animation::New( 0.0f ); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + + ////////////////////////////////////////////////////////////////////////////////// + + tet_infoline( "" ); + + Animation animation = Animation::New( 0.0f ); animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 1000.0f, TimePeriod( 4.0f, 2.0f ) ); animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 145.0f, TimePeriod( 3.0f, 10.0f ) ); animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 109.0f, TimePeriod( 1.0f, 1.0f ) ); @@ -10686,17 +10737,33 @@ int UtcDaliAnimationTimePeriodOrder(void) animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 10.0f, TimePeriod( 10.0f, 2.0f ) ); animation.Play(); + tet_infoline( "The target position should change instantly" ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3( 145.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 145.0f, TEST_LOCATION ); + application.SendNotification(); application.Render(14000); // After the animation is complete DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 145.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3( 145.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 145.0f, TEST_LOCATION ); + + ////////////////////////////////////////////////////////////////////////////////// tet_infoline( "Same animation again but in a different order - should end up at the same point" ); actor.SetX( 0.0f ); + + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + application.SendNotification(); application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3::ZERO, TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 0.0f, TEST_LOCATION ); + animation = Animation::New( 0.0f ); animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 200.0f, TimePeriod( 2.0f, 5.0f ) ); animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 10.0f, TimePeriod( 10.0f, 2.0f ) ); @@ -10706,10 +10773,16 @@ int UtcDaliAnimationTimePeriodOrder(void) animation.AnimateTo( Property( actor, Actor::Property::POSITION_X ), 109.0f, TimePeriod( 1.0f, 1.0f ) ); animation.Play(); + tet_infoline( "The target position should change instantly" ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( Actor::Property::POSITION ), Vector3( 145.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( Actor::Property::POSITION_X ), 145.0f, TEST_LOCATION ); + application.SendNotification(); application.Render(14000); // After the animation is complete DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 145.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< Vector3 >( actor, Actor::Property::POSITION ), Vector3( 145.0f, 0.0f, 0.0f ), TEST_LOCATION ); + DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( actor, Actor::Property::POSITION_X ), 145.0f, TEST_LOCATION ); END_TEST; } diff --git a/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp b/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp index 1e89b06..41ba9b9 100644 --- a/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp +++ b/automated-tests/src/dali/utc-Dali-TypeRegistry.cpp @@ -1179,11 +1179,16 @@ int UtcDaliTypeRegistryAnimatablePropertyRegistrationP(void) Animation animation = Animation::New(0.2f); animation.AnimateTo( Property( customActor, animatablePropertyIndex ), 15.f, AlphaFunction::LINEAR ); animation.Play(); + + // Target value should change straight away + DALI_TEST_EQUALS( customActor.GetProperty< float >( animatablePropertyIndex ), 15.0f, TEST_LOCATION ); + // Render and notify, animation play for 0.05 seconds application.SendNotification(); application.Render(50); DALI_TEST_EQUALS( 0.25f, animation.GetCurrentProgress(), TEST_LOCATION ); DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( customActor, animatablePropertyIndex ), 22.5f, TEST_LOCATION ); + // Render and notify, animation play for another 0.1 seconds application.SendNotification(); application.Render(100); @@ -1280,11 +1285,16 @@ int UtcDaliTypeRegistryAnimatablePropertyRegistrationWithDefaultP(void) Animation animation = Animation::New(0.2f); animation.AnimateTo( Property( customActor, animatablePropertyIndex ), 20.f, AlphaFunction::LINEAR ); animation.Play(); + + // Target value should change straight away + DALI_TEST_EQUALS( customActor.GetProperty< float >( animatablePropertyIndex ), 20.0f, TEST_LOCATION ); + // Render and notify, animation play for 0.05 seconds application.SendNotification(); application.Render(50); DALI_TEST_EQUALS( 0.25f, animation.GetCurrentProgress(), TEST_LOCATION ); DALI_TEST_EQUALS( DevelHandle::GetCurrentProperty< float >( customActor, animatablePropertyIndex ), 12.5f, TEST_LOCATION ); + // Render and notify, animation play for another 0.1 seconds application.SendNotification(); application.Render(100); diff --git a/dali/internal/event/animation/animation-impl.cpp b/dali/internal/event/animation/animation-impl.cpp index 0d70028..2191e2a 100644 --- a/dali/internal/event/animation/animation-impl.cpp +++ b/dali/internal/event/animation/animation-impl.cpp @@ -268,33 +268,20 @@ void Animation::Play() if( mEndAction != EndAction::Discard ) // If the animation is discarded, then we do not want to change the target values { - unsigned int connectorTargetValuesIndex( 0 ); - unsigned int numberOfConnectorTargetValues = mConnectorTargetValues.size(); - - /* - * Loop through all Animator connectors, if connector index matches the current index stored in mConnectorTargetValues container then - * should apply target values for this index to the object. - */ - for ( unsigned int connectorIndex = 0; connectorIndex < mConnectors.Count(); connectorIndex ++) - { - // Use index to check if the current connector is next in the mConnectorTargetValues container, meaning targetValues have been pushed in AnimateXXFunction - if ( connectorTargetValuesIndex < numberOfConnectorTargetValues ) - { - ConnectorTargetValues& connectorPair = mConnectorTargetValues[ connectorTargetValuesIndex ]; + // Sort according to end time with earlier end times coming first, if the end time is the same, then the connectors are not moved + std::stable_sort( mConnectorTargetValues.begin(), mConnectorTargetValues.end(), CompareConnectorEndTimes ); - if ( connectorPair.connectorIndex == connectorIndex ) - { - // Current connector index matches next in the stored connectors with target values so apply target value. - connectorTargetValuesIndex++; // Found a match for connector so increment index to next one - - AnimatorConnectorBase* connector = mConnectors[ connectorIndex ]; + // Loop through all connector target values sorted by increasing end time + ConnectorTargetValuesContainer::const_iterator iter = mConnectorTargetValues.begin(); + const ConnectorTargetValuesContainer::const_iterator endIter = mConnectorTargetValues.end(); + for( ; iter != endIter; ++iter ) + { + AnimatorConnectorBase* connector = mConnectors[ iter->connectorIndex ]; - Object* object = connector->GetObject(); - if( object ) - { - object->NotifyPropertyAnimation( *this, connector->GetPropertyIndex(), connectorPair.targetValue ); - } - } + Object* object = connector->GetObject(); + if( object ) + { + object->NotifyPropertyAnimation( *this, connector->GetPropertyIndex(), iter->targetValue ); } } } @@ -514,6 +501,7 @@ void Animation::AnimateTo(Object& targetObject, Property::Index targetPropertyIn ConnectorTargetValues connectorPair; connectorPair.targetValue = destinationValue; connectorPair.connectorIndex = mConnectors.Count(); + connectorPair.timePeriod = period; mConnectorTargetValues.push_back( connectorPair ); switch ( destinationType ) @@ -978,6 +966,10 @@ Vector2 Animation::GetPlayRange() const return mPlayRange; } +bool Animation::CompareConnectorEndTimes( const Animation::ConnectorTargetValues& lhs, const Animation::ConnectorTargetValues& rhs ) +{ + return ( ( lhs.timePeriod.delaySeconds + lhs.timePeriod.durationSeconds ) < ( rhs.timePeriod.delaySeconds + rhs.timePeriod.durationSeconds ) ); +} } // namespace Internal diff --git a/dali/internal/event/animation/animation-impl.h b/dali/internal/event/animation/animation-impl.h index 8554ff4..92dff74 100644 --- a/dali/internal/event/animation/animation-impl.h +++ b/dali/internal/event/animation/animation-impl.h @@ -442,10 +442,30 @@ private: struct ConnectorTargetValues { - unsigned int connectorIndex; + ConnectorTargetValues() + : targetValue(), + timePeriod( 0.0f ), + connectorIndex( 0 ) + { + } + Property::Value targetValue; + TimePeriod timePeriod; + unsigned int connectorIndex; }; +private: + + /** + * Compares the end times of the animators returning true if lhs end time is less than rhs end time. + * @param[in] lhs The first comparator + * @param[in] rhs The second comparator + * @return True if end time of lhs is less, false otherwise. + */ + static bool CompareConnectorEndTimes( const ConnectorTargetValues& lhs, const ConnectorTargetValues& rhs ); + +private: + const SceneGraph::Animation* mAnimation; EventThreadServices& mEventThreadServices; @@ -455,7 +475,8 @@ private: AnimatorConnectorContainer mConnectors; ///< Owned by the Animation - std::vector< ConnectorTargetValues > mConnectorTargetValues; //< Used to store animating property target value information + typedef std::vector< ConnectorTargetValues > ConnectorTargetValuesContainer; + ConnectorTargetValuesContainer mConnectorTargetValues; //< Used to store animating property target value information Vector2 mPlayRange; -- 2.7.4