From ee502ab32c51a7ea0727995a307dfe9ec6f41e61 Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Fri, 2 Nov 2018 17:55:29 +0000 Subject: [PATCH] Ensure resetters reset both values when a property-owner is disconnected Change-Id: Iaf3e077b8e62d149900abb4ca719efe4326fa598 --- automated-tests/src/dali/utc-Dali-Constraint.cpp | 123 ++++++++++++++++++++++- dali/internal/update/common/property-resetter.h | 36 +++++-- 2 files changed, 151 insertions(+), 8 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Constraint.cpp b/automated-tests/src/dali/utc-Dali-Constraint.cpp index 814c453..f8f8ac5 100644 --- a/automated-tests/src/dali/utc-Dali-Constraint.cpp +++ b/automated-tests/src/dali/utc-Dali-Constraint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 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. @@ -1237,3 +1237,124 @@ int UtcDaliConstraintTestPropertyTypesP(void) /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +namespace +{ +void SetHalfOpacity( Vector4& current, const PropertyInputContainer& inputs ) +{ + current.a = 0.5f; +} +} // unnamed namespace + +int UtcDaliConstraintEnsureResetterAppliedOnStageRemoval(void) +{ + // Ensure BOTH double-buffered values of our color property is reset when a constraint is applied to it. + + TestApplication application; + + Actor actor = Actor::New(); + Stage::GetCurrent().Add( actor ); + + // Check initial value is fully opaque + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION ); + + // Create a constraint whose value is discarded when it is removed + Constraint constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, SetHalfOpacity ); + constraint.SetRemoveAction( Constraint::RemoveAction::Discard ); + constraint.Apply(); + + // Check value after one render, it should be constrained + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION ); + + // Render another frame, ensure the other value has also been updated + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION ); + + // Remove the actor from the stage and delete the constraint + actor.Unparent(); + constraint.Remove(); + constraint.Reset(); + + // Check value while off-stage, it should be fully opaque + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION ); + + // Add the actor back to the stage and check the value, it should be fully opaque again + Stage::GetCurrent().Add( actor ); + + // Check value when back on-stage, it should be fully opaque as the constraint is no longer applied to it. + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION ); + + // Render for another frame to ensure both buffers have the correct value + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliConstraintOnActorAddedAndRemoved(void) +{ + // Ensure adding and removing an actor from stage with a constraint still has it applied when it is re-added back to the stage + + TestApplication application; + + Actor actor = Actor::New(); + Stage::GetCurrent().Add( actor ); + + // Check initial value is fully opaque + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION ); + + // Create a constraint whose value is discarded when it is removed + Constraint constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, SetHalfOpacity ); + constraint.SetRemoveAction( Constraint::RemoveAction::Discard ); + constraint.Apply(); + + // Check value after one render, it should be constrained + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION ); + + // Render another frame, ensure the other value has also been updated + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION ); + + // Remove the actor from the stage + actor.Unparent(); + + // Check value while off-stage, the constraint is no longer being applied as it's off-stage + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION ); + + // Check the other buffer, the constraint should not be applied to this either. + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION ); + + // Add the actor back to the stage and check the value, the constraint should have been re-applied + Stage::GetCurrent().Add( actor ); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION ); + + // Render for another frame to ensure both buffers have the correct value + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION ); + + END_TEST; +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/dali/internal/update/common/property-resetter.h b/dali/internal/update/common/property-resetter.h index c28322f..305fb14 100644 --- a/dali/internal/update/common/property-resetter.h +++ b/dali/internal/update/common/property-resetter.h @@ -17,6 +17,9 @@ * limitations under the License. */ +// EXTERNAL INCLDUES +#include // int8_t + #include #include #include @@ -66,8 +69,16 @@ public: */ void ResetToBaseValue( BufferIndex updateBufferIndex ) { - if( mPropertyOwner != nullptr && !mDisconnected ) + if( mPropertyOwner != nullptr && mActive ) { + // If property-owner has disconnected, start aging. + // We need to reset the property for two frames after disconnection to ensure both + // property values are set appropriately. + if( mDisconnected ) + { + --mActive; + } + mBaseProperty->ResetToBaseValue( updateBufferIndex ); } }; @@ -83,6 +94,7 @@ public: virtual void PropertyOwnerConnected( PropertyOwner& owner ) override { mDisconnected = false; + mActive = ACTIVE; } /** @@ -105,7 +117,8 @@ public: mPropertyOwner = nullptr; // Don't need to wait another frame as the property is being destroyed - mRunning = 0; + mActive = STOPPED; + mRunning = STOPPED; } /** @@ -119,16 +132,23 @@ public: */ virtual bool IsFinished() { - bool finished = mRunning <= 0; - if( mRunning == 1 ) + bool finished = mRunning <= STOPPED; + if( mRunning == AGING ) { - mRunning = 0; + mRunning = STOPPED; } return finished; } protected: + enum + { + STOPPED = 0, + AGING = 1, + ACTIVE = 2, + }; + /** * Constructor * @@ -139,14 +159,16 @@ protected: PropertyBase* baseProperty ) : mPropertyOwner( propertyOwner ), mBaseProperty( baseProperty ), - mRunning( 2 ), + mRunning( ACTIVE ), + mActive( ACTIVE ), mDisconnected( false ) { } PropertyOwner* mPropertyOwner; ///< The property owner PropertyBase* mBaseProperty; ///< The base property being animated or constrained - int mRunning; ///< 2 if running, 1 if aging, 0 if stopped + int8_t mRunning; ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped + int8_t mActive; ///< 2 if active, 1 if aging, 0 if stopped bool mDisconnected; ///< True if the property owner has been disconnected }; -- 2.7.4