From dfdc24ae708e68e50eaaa0fbe407435ee2112e5d Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Thu, 10 Jul 2014 16:41:22 +0100 Subject: [PATCH] Property - Allow the custom property to be INTEGER type Change-Id: Icf3299e6e6429a0ed2b33e045f720f2fae31e073 Signed-off-by: Xiangyin Ma --- automated-tests/src/dali/utc-Dali-Animation.cpp | 513 +++++++++++++++++++++ automated-tests/src/dali/utc-Dali-Constraint.cpp | 214 ++++++++- automated-tests/src/dali/utc-Dali-Handle.cpp | 7 + dali/internal/event/actors/actor-impl.cpp | 11 + dali/internal/event/animation/animation-impl.cpp | 48 ++ dali/internal/event/animation/constraint-impl.cpp | 11 + dali/internal/event/animation/key-frames-impl.cpp | 9 + dali/internal/event/animation/key-frames-impl.h | 13 +- dali/internal/event/animation/progress-value.h | 10 +- .../event/animation/property-input-accessor.h | 18 + .../event/animation/property-input-indexer.h | 8 + dali/internal/event/common/property-input-impl.h | 32 ++ dali/internal/event/common/proxy-object.cpp | 25 + dali/internal/render/shaders/shader.cpp | 5 + .../update/animation/scene-graph-animator.h | 49 ++ dali/internal/update/common/animatable-property.h | 180 ++++++++ .../update/common/property-condition-functions.cpp | 44 ++ .../update/common/property-condition-functions.h | 32 ++ .../common/property-condition-step-functions.cpp | 11 + .../common/property-condition-step-functions.h | 8 + .../property-condition-variable-step-functions.cpp | 11 + .../property-condition-variable-step-functions.h | 8 + dali/public-api/animation/animation.h | 1 + .../animation/interpolator-functions.cpp | 11 + dali/public-api/animation/interpolator-functions.h | 20 + dali/public-api/object/property-input.h | 8 + 26 files changed, 1302 insertions(+), 5 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Animation.cpp b/automated-tests/src/dali/utc-Dali-Animation.cpp index effd38a..8d77d41 100644 --- a/automated-tests/src/dali/utc-Dali-Animation.cpp +++ b/automated-tests/src/dali/utc-Dali-Animation.cpp @@ -110,6 +110,23 @@ struct AnimateFloatTestFunctor float mEnd; }; +struct AnimateIntegerTestFunctor +{ + AnimateIntegerTestFunctor( int start, int end ) + : mStart( start ), + mEnd( end ) + { + } + + int operator()( float alpha, const int& current ) + { + return static_cast( mStart + ((mEnd - mStart) * alpha ) + 0.5f ); + } + + int mStart; + int mEnd; +}; + struct AnimateVector2TestFunctor { AnimateVector2TestFunctor( Vector2 start, Vector2 end ) @@ -1776,6 +1793,236 @@ int UtcDaliAnimationAnimateByFloatAlphaFunctionTimePeriod(void) END_TEST; } +int UtcDaliAnimationAnimateByInteger(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(1); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(2.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(50); + int relativeValue(targetValue - startValue); + animation.AnimateBy(Property(actor, index), relativeValue); + + int ninetyFivePercentProgress(static_cast(startValue + relativeValue*0.95f + 0.5f)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*950.0f)/* 95% progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), ninetyFivePercentProgress, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*50.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliAnimationAnimateByIntegerAlphaFunction(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(1); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(1.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(90); + int relativeValue(targetValue - startValue); + animation.AnimateBy(Property(actor, index), relativeValue, AlphaFunctions::EaseOut); + + int ninetyFivePercentProgress(static_cast(startValue + relativeValue*0.95f + 0.5f)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*950.0f)/* 95% progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + + // The position should have moved more, than with a linear alpha function + int current(actor.GetProperty(index)); + DALI_TEST_CHECK( current > ninetyFivePercentProgress ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*50.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliAnimationAnimateByIntegerTimePeriod(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(10); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(1.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(30); + int relativeValue(targetValue - startValue); + float delay = 0.5f; + animation.AnimateBy(Property(actor, index), + relativeValue, + TimePeriod(delay, durationSeconds - delay)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*500.0f)/* 50% animation progress, 0% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f)/* 75% animation progress, 50% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), static_cast(startValue+(relativeValue*0.5f)+0.5f), TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliAnimationAnimateByIntegerAlphaFunctionTimePeriod(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(10); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(1.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(30); + int relativeValue(targetValue - startValue); + float delay = 0.5f; + animation.AnimateBy(Property(actor, index), + relativeValue, + AlphaFunctions::Linear, + TimePeriod(delay, durationSeconds - delay)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*500.0f)/* 50% animation progress, 0% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f)/* 75% animation progress, 50% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), static_cast(startValue+(relativeValue*0.5f)+0.5f), TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + int UtcDaliAnimationAnimateByVector2(void) { TestApplication application; @@ -3187,6 +3434,212 @@ int UtcDaliAnimationAnimateToFloatAlphaFunctionTimePeriod(void) END_TEST; } +int UtcDaliAnimationAnimateToInteger(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(10); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(2.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(50); + int relativeValue(targetValue - startValue); + animation.AnimateTo(Property(actor, "test-property"), targetValue); + + int ninetyFivePercentProgress(static_cast(startValue + relativeValue*0.95f + 0.5f)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*950.0f)/* 95% progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), ninetyFivePercentProgress, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*50.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliAnimationAnimateToIntegerAlphaFunction(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(10); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(1.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(90); + int relativeValue(targetValue - startValue); + animation.AnimateTo(Property(actor, index), targetValue, AlphaFunctions::EaseOut); + + int ninetyFivePercentProgress(static_cast(startValue + relativeValue*0.95f + 0.5f)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*950.0f)/* 95% progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + + // The position should have moved more, than with a linear alpha function + int current(actor.GetProperty(index)); + DALI_TEST_CHECK( current > ninetyFivePercentProgress ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*50.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliAnimationAnimateToIntegerTimePeriod(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(10); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(1.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(30); + int relativeValue(targetValue - startValue); + float delay = 0.5f; + animation.AnimateTo(Property(actor, index), + targetValue, + TimePeriod(delay, durationSeconds - delay)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*500.0f)/* 50% animation progress, 0% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f)/* 75% animation progress, 50% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), static_cast(startValue+(relativeValue*0.5f)+0.5f), TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliAnimationAnimateToIntegerAlphaFunctionTimePeriod(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(10); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(1.0f); + Animation animation = Animation::New(durationSeconds); + int targetValue(30); + int relativeValue(targetValue - startValue); + float delay = 0.5f; + animation.AnimateTo(Property(actor, index), + targetValue, + AlphaFunctions::Linear, + TimePeriod(delay, durationSeconds - delay)); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*500.0f)/* 50% animation progress, 0% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f)/* 75% animation progress, 50% animator progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), static_cast(startValue+(relativeValue*0.5f)+0.5f), TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetValue, TEST_LOCATION ); + END_TEST; +} + int UtcDaliAnimationAnimateToVector2(void) { TestApplication application; @@ -8367,6 +8820,66 @@ int UtcDaliAnimationAnimateFloat(void) END_TEST; } +int UtcDaliAnimationAnimateInteger(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + Stage::GetCurrent().Add(actor); + + // Register an integer property + int startValue(10); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Build the animation + float durationSeconds(10.0f); + Animation animation = Animation::New(durationSeconds); + int targetPosition(0); + AnimateIntegerTestFunctor func( 100, targetPosition ); + animation.Animate( Property(actor, index), func ); + + // Start the animation + animation.Play(); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f)/* 25% progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), 75, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f)/* 50% progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), 50, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f)/* 75% progress */); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), 25, TEST_LOCATION ); + + application.SendNotification(); + application.Render(static_cast(durationSeconds*250.0f) + 1u/*just beyond the animation duration*/); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + DALI_TEST_EQUALS( actor.GetProperty(index), targetPosition, TEST_LOCATION ); + END_TEST; +} + int UtcDaliAnimationAnimateVector2(void) { TestApplication application; diff --git a/automated-tests/src/dali/utc-Dali-Constraint.cpp b/automated-tests/src/dali/utc-Dali-Constraint.cpp index cd832d4..56d773e 100644 --- a/automated-tests/src/dali/utc-Dali-Constraint.cpp +++ b/automated-tests/src/dali/utc-Dali-Constraint.cpp @@ -66,6 +66,7 @@ class PropertyInputAbstraction : public Dali::PropertyInput public: PropertyInputAbstraction(const bool& val) : mType(Dali::Property::BOOLEAN), mBoolData( val ) {} PropertyInputAbstraction(const float& val) : mType(Dali::Property::FLOAT), mFloatData( val ) {} + PropertyInputAbstraction(const int& val) : mType(Dali::Property::INTEGER), mIntData( val ) {} PropertyInputAbstraction(const Vector2& val) : mType(Dali::Property::VECTOR2), mVector2Data( val ) {} PropertyInputAbstraction(const Vector3& val) : mType(Dali::Property::VECTOR3), mVector3Data( val ) {} PropertyInputAbstraction(const Vector4& val) : mType(Dali::Property::VECTOR4), mVector4Data( val ) {} @@ -81,6 +82,8 @@ public: const float& GetFloat() const { return mFloatData; } + const int& GetInteger() const { return mIntData; } + const Vector2& GetVector2() const { return mVector2Data; } const Vector3& GetVector3() const { return mVector3Data; } const Vector4& GetVector4() const { return mVector4Data; } @@ -94,6 +97,7 @@ private: Dali::Property::Type mType; bool mBoolData; float mFloatData; + int mIntData; Vector2 mVector2Data; Vector3 mVector3Data; Vector4 mVector4Data; @@ -167,9 +171,9 @@ struct TestAlwaysTrueConstraint } }; -struct TestAlwaysEqualOrGreaterThanConstraint +struct TestAlwaysEqualOrGreaterThanConstraintFloat { - TestAlwaysEqualOrGreaterThanConstraint( float value ) + TestAlwaysEqualOrGreaterThanConstraintFloat( float value ) : mValue( value ) { } @@ -182,6 +186,21 @@ struct TestAlwaysEqualOrGreaterThanConstraint float mValue; }; +struct TestAlwaysEqualOrGreaterThanConstraintInteger +{ + TestAlwaysEqualOrGreaterThanConstraintInteger( int value ) + : mValue( value ) + { + } + + int operator()( const int& current ) + { + return ( current < mValue ) ? mValue : current; + } + + int mValue; +}; + struct TestAlwaysEqualOrGreaterThanConstraintVector2 { TestAlwaysEqualOrGreaterThanConstraintVector2( Vector2 value ) @@ -251,6 +270,21 @@ struct TestConstraintFloat float mValue; }; +struct TestConstraintInteger +{ + TestConstraintInteger( int value ) + : mValue( value ) + { + } + + int operator()( const int& current ) + { + return mValue; + } + + int mValue; +}; + struct TestConstraintVector2 { TestConstraintVector2( Vector2 value ) @@ -592,7 +626,7 @@ int UtcDaliConstraintNewFloat(void) // Apply constraint float minValue( 2.0f ); - Constraint constraint = Constraint::New( index, TestAlwaysEqualOrGreaterThanConstraint( minValue ) ); + Constraint constraint = Constraint::New( index, TestAlwaysEqualOrGreaterThanConstraintFloat( minValue ) ); actor.ApplyConstraint( constraint ); DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); @@ -650,6 +684,91 @@ int UtcDaliConstraintNewFloat(void) END_TEST; } +int UtcDaliConstraintNewInteger(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue( 1 ); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + Stage::GetCurrent().Add(actor); + DALI_TEST_CHECK( actor.GetProperty(index) == startValue ); + + /** + * Test that the Constraint is correctly applied on a clean Node + */ + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK( actor.GetProperty(index) == startValue ); + application.Render(0); + DALI_TEST_CHECK( actor.GetProperty(index) == startValue ); + application.Render(0); + DALI_TEST_CHECK( actor.GetProperty(index) == startValue ); + + // Apply constraint + + int minValue( 2 ); + Constraint constraint = Constraint::New( index, TestAlwaysEqualOrGreaterThanConstraintInteger( minValue ) ); + + actor.ApplyConstraint( constraint ); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + application.SendNotification(); + application.Render(0); + + // Constraint should be fully applied + DALI_TEST_EQUALS( actor.GetProperty(index), minValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), minValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), minValue, TEST_LOCATION ); + + // Set to greater than 2f, the constraint will allow this + actor.SetProperty( index, 3 ); + + application.SendNotification(); + application.Render(0); + + DALI_TEST_EQUALS( actor.GetProperty(index), 3, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), 3, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), 3, TEST_LOCATION ); + + // Set to less than 2, the constraint will NOT allow this + actor.SetProperty( index, 1 ); + + application.SendNotification(); + application.Render(0); + + DALI_TEST_EQUALS( actor.GetProperty(index), minValue/*not 1*/, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), minValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), minValue, TEST_LOCATION ); + + // Remove the constraint, then set new value + actor.RemoveConstraints(); + actor.SetProperty( index, 1 ); + + // Constraint should have been removed + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), 1, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), 1, TEST_LOCATION ); + END_TEST; + +} + int UtcDaliConstraintNewVector2(void) { TestApplication application; @@ -1231,6 +1350,95 @@ int UtcDaliConstraintNewOffStageFloat(void) END_TEST; } +int UtcDaliConstraintNewOffStageInteger(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + + // Register an integer property + int startValue(1); + Property::Index index = actor.RegisterProperty( "test-property", startValue ); + DALI_TEST_CHECK( actor.GetProperty(index) == startValue ); + + // Apply constraint to off-stage Actor + int constrainedValue( 2 ); + Constraint constraint = Constraint::New( index, TestConstraintInteger( constrainedValue ) ); + actor.ApplyConstraint( constraint ); + + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Add actor to stage + Stage::GetCurrent().Add(actor); + application.SendNotification(); + application.Render(0); + + // Constraint should be fully applied + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + + // Take the actor off-stage + Stage::GetCurrent().Remove(actor); + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + + // Set back to startValue; the constraint will not prevent this + actor.SetProperty( index, startValue ); + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Add actor to stage (2nd time) + Stage::GetCurrent().Add(actor); + application.SendNotification(); + application.Render(0); + + // Constraint should be fully applied (2nd time) + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + + // Take the actor off-stage (2nd-time) + Stage::GetCurrent().Remove(actor); + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), constrainedValue, TEST_LOCATION ); + + // Remove the constraint, and set back to startValue + actor.RemoveConstraints(); + actor.SetProperty( index, startValue ); + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Add actor to stage (3rd time) + Stage::GetCurrent().Add(actor); + application.SendNotification(); + application.Render(0); + + // Constraint should be gone + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + + // Check that nothing has changed after a couple of buffer swaps + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + application.Render(0); + DALI_TEST_EQUALS( actor.GetProperty(index), startValue, TEST_LOCATION ); + END_TEST; +} + int UtcDaliConstraintNewOffStageVector2(void) { TestApplication application; diff --git a/automated-tests/src/dali/utc-Dali-Handle.cpp b/automated-tests/src/dali/utc-Dali-Handle.cpp index 8587420..8ff666b 100644 --- a/automated-tests/src/dali/utc-Dali-Handle.cpp +++ b/automated-tests/src/dali/utc-Dali-Handle.cpp @@ -435,6 +435,7 @@ int UtcDaliHandleGetPropertyType(void) // Register some dynamic properties Property::Index boolIndex = actor.RegisterProperty( "bool-property", bool(true) ); Property::Index floatIndex = actor.RegisterProperty( "float-property", float(123.0f) ); + Property::Index intIndex = actor.RegisterProperty( "int-property", 123 ); Property::Index vector2Index = actor.RegisterProperty( "vector2-property", Vector2(1.0f, 2.0f) ); Property::Index vector3Index = actor.RegisterProperty( "vector3-property", Vector3(1.0f, 2.0f, 3.0f) ); Property::Index vector4Index = actor.RegisterProperty( "vector4-property", Vector4(1.0f, 2.0f, 3.0f, 4.0f) ); @@ -442,6 +443,7 @@ int UtcDaliHandleGetPropertyType(void) DALI_TEST_CHECK( Property::BOOLEAN == actor.GetPropertyType( boolIndex ) ); DALI_TEST_CHECK( Property::FLOAT == actor.GetPropertyType( floatIndex ) ); + DALI_TEST_CHECK( Property::INTEGER == actor.GetPropertyType( intIndex ) ); DALI_TEST_CHECK( Property::VECTOR2 == actor.GetPropertyType( vector2Index ) ); DALI_TEST_CHECK( Property::VECTOR3 == actor.GetPropertyType( vector3Index ) ); DALI_TEST_CHECK( Property::VECTOR4 == actor.GetPropertyType( vector4Index ) ); @@ -454,6 +456,7 @@ int UtcDaliHandleGetPropertyType(void) Property::Index nonAnimV4Index = actor.RegisterProperty( "v4", Vector4(1.f, 2.f, 3.f, 4.f), Property::READ_WRITE); Property::Index nonAnimBooleanIndex = actor.RegisterProperty( "bool", true, Property::READ_WRITE); Property::Index nonAnimFloatIndex = actor.RegisterProperty( "float", 0.f, Property::READ_WRITE); + Property::Index nonAnimIntegerIndex = actor.RegisterProperty( "int", 0, Property::READ_WRITE); Property::Index nonAnimUnsignedIntIndex = actor.RegisterProperty( "unsinged-int", unsingedIntTest, Property::READ_WRITE); DALI_TEST_CHECK( nonAnimStringIndex != Property::INVALID_INDEX ); @@ -462,6 +465,7 @@ int UtcDaliHandleGetPropertyType(void) DALI_TEST_CHECK( nonAnimV4Index != Property::INVALID_INDEX ); DALI_TEST_CHECK( nonAnimBooleanIndex != Property::INVALID_INDEX ); DALI_TEST_CHECK( nonAnimFloatIndex != Property::INVALID_INDEX ); + DALI_TEST_CHECK( nonAnimIntegerIndex != Property::INVALID_INDEX ); DALI_TEST_CHECK( nonAnimUnsignedIntIndex != Property::INVALID_INDEX ); DALI_TEST_CHECK( Property::STRING == actor.GetPropertyType( nonAnimStringIndex ) ); @@ -470,6 +474,7 @@ int UtcDaliHandleGetPropertyType(void) DALI_TEST_CHECK( Property::VECTOR4 == actor.GetPropertyType( nonAnimV4Index ) ); DALI_TEST_CHECK( Property::BOOLEAN == actor.GetPropertyType( nonAnimBooleanIndex ) ); DALI_TEST_CHECK( Property::FLOAT == actor.GetPropertyType( nonAnimFloatIndex ) ); + DALI_TEST_CHECK( Property::INTEGER == actor.GetPropertyType( nonAnimIntegerIndex ) ); DALI_TEST_CHECK( Property::UNSIGNED_INTEGER == actor.GetPropertyType( nonAnimUnsignedIntIndex ) ); DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimStringIndex ) ); @@ -478,6 +483,7 @@ int UtcDaliHandleGetPropertyType(void) DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimV4Index ) ); DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimBooleanIndex ) ); DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimFloatIndex ) ); + DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimIntegerIndex ) ); DALI_TEST_CHECK( !actor.IsPropertyAnimatable( nonAnimUnsignedIntIndex ) ); DALI_TEST_EQUALS( "yes" , actor.GetProperty( nonAnimStringIndex ).Get(), TEST_LOCATION ); @@ -486,6 +492,7 @@ int UtcDaliHandleGetPropertyType(void) DALI_TEST_EQUALS( Vector4(1.f, 2.f, 3.f, 4.f) , actor.GetProperty( nonAnimV4Index ).Get(), TEST_LOCATION ); DALI_TEST_EQUALS( true, actor.GetProperty( nonAnimBooleanIndex ).Get(), TEST_LOCATION ); DALI_TEST_EQUALS( 0.f, actor.GetProperty( nonAnimFloatIndex ).Get(), TEST_LOCATION ); + DALI_TEST_EQUALS( 0, actor.GetProperty( nonAnimIntegerIndex ).Get(), TEST_LOCATION ); DALI_TEST_EQUALS( unsingedIntTest, actor.GetProperty( nonAnimUnsignedIntIndex ).Get(), TEST_LOCATION ); END_TEST; diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 1f926f0..abc78c9 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -2690,6 +2690,17 @@ void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entr break; } + case Property::INTEGER: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + SceneGraph::NodePropertyMessage::Send( mStage->GetUpdateManager(), mNode, property, &AnimatableProperty::Bake, value.Get() ); + + break; + } + case Property::VECTOR2: { AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); diff --git a/dali/internal/event/animation/animation-impl.cpp b/dali/internal/event/animation/animation-impl.cpp index 4129c3d..232c1cd 100644 --- a/dali/internal/event/animation/animation-impl.cpp +++ b/dali/internal/event/animation/animation-impl.cpp @@ -310,6 +310,17 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph break; } + case Property::INTEGER: + { + AddAnimatorConnector( AnimatorConnector::New( proxy, + target.propertyIndex, + target.componentIndex, + AnimateByInteger(relativeValue.Get()), + alpha, + period ) ); + break; + } + case Property::VECTOR2: { AddAnimatorConnector( AnimatorConnector::New( proxy, @@ -422,6 +433,17 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope break; } + case Property::INTEGER: + { + AddAnimatorConnector( AnimatorConnector::New(targetObject, + targetPropertyIndex, + componentIndex, + AnimateToInteger(destinationValue.Get()), + alpha, + period) ); + break; + } + case Property::VECTOR2: { AddAnimatorConnector( AnimatorConnector::New(targetObject, @@ -517,6 +539,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph period ) ); break; } + case Dali::Property::FLOAT: { const KeyFrameNumber* kf; @@ -531,6 +554,20 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph break; } + case Dali::Property::INTEGER: + { + const KeyFrameInteger* kf; + GetSpecialization(keyFrames, kf); + KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf); + AddAnimatorConnector( AnimatorConnector::New( proxy, + target.propertyIndex, + target.componentIndex, + KeyFrameIntegerFunctor(kfCopy), + alpha, + period ) ); + break; + } + case Dali::Property::VECTOR2: { const KeyFrameVector2* kf; @@ -647,6 +684,17 @@ void Animation::Animate( Property& target, Property::Type targetType, AnyFunctio break; } + case Property::INTEGER: + { + AddAnimatorConnector( AnimatorConnector::New(proxy, + target.propertyIndex, + target.componentIndex, + AnyCast< AnimatorFunctionInteger >( func ), + alpha, + period) ); + break; + } + case Property::VECTOR2: { AddAnimatorConnector( AnimatorConnector::New(proxy, diff --git a/dali/internal/event/animation/constraint-impl.cpp b/dali/internal/event/animation/constraint-impl.cpp index c69f8c6..d790191 100644 --- a/dali/internal/event/animation/constraint-impl.cpp +++ b/dali/internal/event/animation/constraint-impl.cpp @@ -151,6 +151,17 @@ Constraint::Constraint( Property::Index targetIndex, break; } + case Property::INTEGER: + { + PropertyConstraintPtr::Type funcPtr( CreatePropertyConstraint( func, sources.size() ) ); + + mActiveConstraintTemplate = ActiveConstraint::New( targetIndex, + sources, + funcPtr, + AnyCast< IntegerInterpolator >( interpolator ) ); + break; + } + case Property::VECTOR2: { PropertyConstraintPtr::Type funcPtr( CreatePropertyConstraint( func, sources.size() ) ); diff --git a/dali/internal/event/animation/key-frames-impl.cpp b/dali/internal/event/animation/key-frames-impl.cpp index 969d8f3..3237e4d 100644 --- a/dali/internal/event/animation/key-frames-impl.cpp +++ b/dali/internal/event/animation/key-frames-impl.cpp @@ -51,6 +51,9 @@ void KeyFrames::CreateKeyFramesSpec(Property::Type type) case Property::FLOAT: mKeyFrames = Internal::KeyFrameNumber::New(); break; + case Property::INTEGER: + mKeyFrames = Internal::KeyFrameInteger::New(); + break; case Property::VECTOR2: mKeyFrames = Internal::KeyFrameVector2::New(); break; @@ -100,6 +103,12 @@ void KeyFrames::Add(float time, Property::Value value, AlphaFunction alpha) kf->AddKeyFrame(time, value.Get(), alpha); break; } + case Property::INTEGER: + { + Internal::KeyFrameInteger* kf = static_cast(mKeyFrames.Get()); + kf->AddKeyFrame(time, value.Get(), alpha); + break; + } case Property::VECTOR2: { Internal::KeyFrameVector2* kf = static_cast(mKeyFrames.Get()); diff --git a/dali/internal/event/animation/key-frames-impl.h b/dali/internal/event/animation/key-frames-impl.h index 768375d..b102b88 100644 --- a/dali/internal/event/animation/key-frames-impl.h +++ b/dali/internal/event/animation/key-frames-impl.h @@ -240,6 +240,7 @@ public: typedef KeyFrameBaseSpec KeyFrameNumber; typedef KeyFrameBaseSpec KeyFrameBoolean; +typedef KeyFrameBaseSpec KeyFrameInteger; typedef KeyFrameBaseSpec KeyFrameVector2; typedef KeyFrameBaseSpec KeyFrameVector3; typedef KeyFrameBaseSpec KeyFrameVector4; @@ -247,6 +248,7 @@ typedef KeyFrameBaseSpec KeyFrameQuaternion; typedef IntrusivePtr KeyFrameBooleanPtr; typedef IntrusivePtr KeyFrameNumberPtr; +typedef IntrusivePtr KeyFrameIntegerPtr; typedef IntrusivePtr KeyFrameVector2Ptr; typedef IntrusivePtr KeyFrameVector3Ptr; typedef IntrusivePtr KeyFrameVector4Ptr; @@ -263,7 +265,6 @@ inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Intern keyFrameSpec = static_cast(keyFrames.GetKeyFramesBase()); } - inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameNumber*& keyFrameSpec) { keyFrameSpec = static_cast(keyFrames.GetKeyFramesBase()); @@ -274,6 +275,16 @@ inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Intern keyFrameSpec = static_cast(keyFrames.GetKeyFramesBase()); } +inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameInteger*& keyFrameSpec) +{ + keyFrameSpec = static_cast(keyFrames.GetKeyFramesBase()); +} + +inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameInteger*& keyFrameSpec) +{ + keyFrameSpec = static_cast(keyFrames.GetKeyFramesBase()); +} + inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector2*& keyFrameSpec) { keyFrameSpec = static_cast(keyFrames.GetKeyFramesBase()); diff --git a/dali/internal/event/animation/progress-value.h b/dali/internal/event/animation/progress-value.h index 4800416..b7fd320 100644 --- a/dali/internal/event/animation/progress-value.h +++ b/dali/internal/event/animation/progress-value.h @@ -66,7 +66,7 @@ typedef ProgressValue ProgressQuaternion; typedef std::vector ProgressQuaternionContainer; typedef ProgressValue ProgressAngleAxis; -typedef std::vector ProgressQuaternionContainer; +typedef std::vector ProgressAngleAxisContainer; typedef ProgressValue ProgressBoolean; typedef std::vector ProgressBooleanContainer; @@ -74,6 +74,9 @@ typedef std::vector ProgressBooleanContainer typedef ProgressValue ProgressNumber; typedef std::vector ProgressNumberContainer; +typedef ProgressValue ProgressInteger; +typedef std::vector ProgressIntegerContainer; + typedef ProgressValue ProgressVector2; typedef std::vector ProgressVector2Container; @@ -112,6 +115,11 @@ inline float Interpolate (ProgressNumber& a, ProgressNumber& b, float progress) return (a.GetValue() + (b.GetValue() - a.GetValue()) * progress); } +inline int Interpolate (ProgressInteger& a, ProgressInteger& b, float progress) +{ + return static_cast(a.GetValue() + (b.GetValue() - a.GetValue()) * progress + 0.5f); +} + inline Vector2 Interpolate (ProgressVector2& a, ProgressVector2& b, float progress) { return (a.GetValue() + (b.GetValue() - a.GetValue()) * progress); diff --git a/dali/internal/event/animation/property-input-accessor.h b/dali/internal/event/animation/property-input-accessor.h index a47b8be..5caf4a8 100644 --- a/dali/internal/event/animation/property-input-accessor.h +++ b/dali/internal/event/animation/property-input-accessor.h @@ -108,6 +108,14 @@ public: } /** + * @copydoc Dali::Internal::PropertyInputImpl::GetConstraintInputInteger() const + */ + const int& GetConstraintInputInteger( BufferIndex updateBufferIndex ) const + { + return mInput->GetConstraintInputInteger( updateBufferIndex ); + } + + /** * @copydoc Dali::Internal::PropertyInputImpl::GetConstraintInputVector2() */ const Vector2& GetConstraintInputVector2( BufferIndex updateBufferIndex ) const @@ -290,6 +298,16 @@ public: } /** + * @copydoc Dali::Internal::PropertyInputImpl::GetConstraintInputInteger() const + */ + const int& GetConstraintInputInteger( BufferIndex updateBufferIndex ) const + { + DALI_ASSERT_DEBUG( mComponentIndex < 0 && "Did not expect valid component index" ); + + return mInput->GetConstraintInputInteger( updateBufferIndex ); + } + + /** * @copydoc Dali::Internal::PropertyInputImpl::GetConstraintInputVector2() */ const Vector2& GetConstraintInputVector2( BufferIndex updateBufferIndex ) const diff --git a/dali/internal/event/animation/property-input-indexer.h b/dali/internal/event/animation/property-input-indexer.h index 9c3f5c6..6d0151e 100644 --- a/dali/internal/event/animation/property-input-indexer.h +++ b/dali/internal/event/animation/property-input-indexer.h @@ -73,6 +73,14 @@ public: } /** + * @copydoc Dali::Internal::PropertyInput::GetInteger() + */ + virtual const int& GetInteger() const + { + return mInput->GetConstraintInputInteger( mBufferIndex ); + } + + /** * @copydoc Dali::Internal::PropertyInput::GetVector2() */ virtual const Vector2& GetVector2() const diff --git a/dali/internal/event/common/property-input-impl.h b/dali/internal/event/common/property-input-impl.h index 967bde7..367c28b 100644 --- a/dali/internal/event/common/property-input-impl.h +++ b/dali/internal/event/common/property-input-impl.h @@ -39,6 +39,7 @@ namespace Internal */ static const bool DUMMY_BOOLEAN_VALUE( false ); static const float DUMMY_FLOAT_VALUE( 0.0f ); +static const int DUMMY_INTEGER_VALUE( 0 ); static const Vector2 DUMMY_VECTOR2_VALUE( 0.0f, 0.0f ); static const Vector3 DUMMY_VECTOR3_VALUE( 0.0f, 0.0f, 0.0f ); static const Vector4 DUMMY_VECTOR4_VALUE( 0.0f, 0.0f, 0.0f, 0.0f ); @@ -104,6 +105,18 @@ public: } /** + * Retrieve an integer value. + * @pre GetType() returns Property::INTEGER. + * @param[in] bufferIndex The buffer to read from. + * @return The integer value. + */ + virtual const int& GetInteger( BufferIndex bufferIndex ) const + { + DALI_ASSERT_ALWAYS( false && "Property type mismatch" ); + return DUMMY_INTEGER_VALUE; + } + + /** * Retrieve a Vector2 value. * @pre GetType() returns Property::VECTOR2. * @param[in] bufferIndex The buffer to read from. @@ -204,6 +217,19 @@ public: } /** + * Retrieve an integer input for a constraint function. + * @note For inherited properties, this method should be overriden to return the value + * from the previous frame i.e. not from the current update buffer. + * @pre GetType() returns Property::INTEGER. + * @param[in] updateBufferIndex The current update buffer index. + * @return The integer value. + */ + virtual const int& GetConstraintInputInteger( BufferIndex updateBufferIndex ) const + { + return GetInteger( updateBufferIndex ); + } + + /** * Retrieve a Vector2 input for a constraint function. * @note For inherited properties, this method should be overriden to return the value * from the previous frame i.e. not from the current update buffer. @@ -302,6 +328,12 @@ public: break; } + case Property::INTEGER: + { + debugStream << GetInteger( bufferIndex ); + break; + } + case Property::VECTOR2: { debugStream << GetVector2( bufferIndex ); diff --git a/dali/internal/event/common/proxy-object.cpp b/dali/internal/event/common/proxy-object.cpp index fafe4be..54c740c 100644 --- a/dali/internal/event/common/proxy-object.cpp +++ b/dali/internal/event/common/proxy-object.cpp @@ -424,6 +424,15 @@ Property::Value ProxyObject::GetProperty(Property::Index index) const break; } + case Property::INTEGER: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry->second.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + value = (*property)[ bufferIndex ]; + break; + } + case Property::VECTOR2: { AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry->second.GetSceneGraphProperty() ); @@ -540,6 +549,12 @@ Property::Index ProxyObject::RegisterProperty( std::string name, const Property: break; } + case Property::INTEGER: + { + newProperty.reset(new AnimatableProperty( propertyValue.Get())); + break; + } + case Property::VECTOR2: { newProperty.reset(new AnimatableProperty( propertyValue.Get())); @@ -811,6 +826,16 @@ void ProxyObject::SetCustomProperty( Property::Index index, const CustomProperty break; } + case Property::INTEGER: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + case Property::VECTOR2: { AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); diff --git a/dali/internal/render/shaders/shader.cpp b/dali/internal/render/shaders/shader.cpp index a307294..6b9d3cd 100644 --- a/dali/internal/render/shaders/shader.cpp +++ b/dali/internal/render/shaders/shader.cpp @@ -357,6 +357,11 @@ void Shader::SetUniforms( Context& context, program.SetUniform1f( loc, property.GetFloat( bufferIndex ) ); break; } + case Property::INTEGER : + { + program.SetUniform1i( loc, property.GetInteger( bufferIndex ) ); + break; + } case Property::VECTOR2 : { Vector2 value( property.GetVector2( bufferIndex ) ); diff --git a/dali/internal/update/animation/scene-graph-animator.h b/dali/internal/update/animation/scene-graph-animator.h index ace176d..c7e1db0 100644 --- a/dali/internal/update/animation/scene-graph-animator.h +++ b/dali/internal/update/animation/scene-graph-animator.h @@ -335,6 +335,36 @@ struct AnimateToFloat float mTarget; }; +struct AnimateByInteger +{ + AnimateByInteger(const int& relativeValue) + : mRelative(relativeValue) + { + } + + float operator()(float alpha, const int& property) + { + return int(property + mRelative * alpha + 0.5f ); + } + + int mRelative; +}; + +struct AnimateToInteger +{ + AnimateToInteger(const int& targetValue) + : mTarget(targetValue) + { + } + + float operator()(float alpha, const int& property) + { + return int(property + ((mTarget - property) * alpha) + 0.5f); + } + + int mTarget; +}; + struct AnimateByVector2 { AnimateByVector2(const Vector2& relativeValue) @@ -569,6 +599,25 @@ struct KeyFrameNumberFunctor KeyFrameNumberPtr mKeyFrames; }; +struct KeyFrameIntegerFunctor +{ + KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames) + : mKeyFrames(keyFrames) + { + } + + float operator()(float progress, const int& property) + { + if(mKeyFrames->IsActive(progress)) + { + return mKeyFrames->GetValue(progress); + } + return property; + } + + KeyFrameIntegerPtr mKeyFrames; +}; + struct KeyFrameVector2Functor { KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames) diff --git a/dali/internal/update/common/animatable-property.h b/dali/internal/update/common/animatable-property.h index 3108050..a5f30c4 100644 --- a/dali/internal/update/common/animatable-property.h +++ b/dali/internal/update/common/animatable-property.h @@ -473,6 +473,186 @@ private: }; /** + * An integer animatable property of a scene-graph object. + */ +template <> +class AnimatableProperty : public AnimatablePropertyBase +{ +public: + + /** + * Create an animatable property. + * @param [in] initialValue The initial value of the property. + */ + AnimatableProperty( int initialValue ) + : mValue( initialValue ), + mBaseValue( initialValue ) + { + } + + /** + * Virtual destructor. + */ + virtual ~AnimatableProperty() + { + } + + /** + * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType() + */ + virtual Dali::Property::Type GetType() const + { + return Dali::PropertyTypes::Get(); + } + + /** + * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue() + */ + virtual void ResetToBaseValue(BufferIndex updateBufferIndex) + { + if (CLEAN_FLAG != mDirtyFlags) + { + mValue[updateBufferIndex] = mBaseValue; + + mDirtyFlags = ( mDirtyFlags >> 1 ); + } + } + + /** + * @copydoc Dali::Internal::PropertyInputImpl::GetInteger() + */ + virtual const int& GetInteger( BufferIndex bufferIndex ) const + { + return mValue[ bufferIndex ]; + } + + /** + * Set the property value. This will only persist for the current frame; the property + * will be reset with the base value, at the beginning of the next frame. + * @param[in] bufferIndex The buffer to write. + * @param[in] value The new property value. + */ + void Set(BufferIndex bufferIndex, int value) + { + mValue[bufferIndex] = value; + + OnSet(); + } + + /** + * Change the property value by a relative amount. + * @param[in] bufferIndex The buffer to write. + * @param[in] delta The property will change by this amount. + */ + void SetRelative(BufferIndex bufferIndex, int delta) + { + mValue[bufferIndex] = mValue[bufferIndex] + delta; + + OnSet(); + } + + /** + * @copydoc Dali::SceneGraph::AnimatableProperty::Get() + */ + int& Get(size_t bufferIndex) + { + return mValue[bufferIndex]; + } + + /** + * @copydoc Dali::SceneGraph::AnimatableProperty::Get() + */ + const int& Get(size_t bufferIndex) const + { + return mValue[bufferIndex]; + } + + /** + * Retrieve the property value. + * @param[in] bufferIndex The buffer to read. + * @return The property value. + */ + int& operator[](size_t bufferIndex) + { + return mValue[bufferIndex]; + } + + /** + * Retrieve the property value. + * @param[in] bufferIndex The buffer to read. + * @return The property value. + */ + const int& operator[](size_t bufferIndex) const + { + return mValue[bufferIndex]; + } + + /** + * Set both the property value & base value. + * @param[in] bufferIndex The buffer to write for the property value. + * @param[in] value The new property value. + */ + void Bake(BufferIndex bufferIndex, int value) + { + mValue[bufferIndex] = value; + mBaseValue = mValue[bufferIndex]; + + OnBake(); + } + + /** + * Change the property value & base value by a relative amount. + * @param[in] bufferIndex The buffer to write for the local property value. + * @param[in] delta The property will change by this amount. + */ + void BakeRelative(BufferIndex bufferIndex, int delta) + { + mValue[bufferIndex] = mValue[bufferIndex] + delta; + mBaseValue = mValue[bufferIndex]; + + OnBake(); + } + + /** + * Sets both double-buffered values & the base value. + * This should only be used when the owning object has not been connected to the scene-graph. + * @param[in] value The new property value. + */ + void SetInitial(const int& value) + { + mValue[0] = value; + mValue[1] = mValue[0]; + mBaseValue = mValue[0]; + } + + /** + * Change both double-buffered values & the base value by a relative amount. + * This should only be used when the owning object has not been connected to the scene-graph. + * @param[in] delta The property will change by this amount. + */ + void SetInitialRelative(const int& delta) + { + mValue[0] = mValue[0] + delta; + mValue[1] = mValue[0]; + mBaseValue = mValue[0]; + } + +private: + + // Undefined + AnimatableProperty(const AnimatableProperty& property); + + // Undefined + AnimatableProperty& operator=(const AnimatableProperty& rhs); + +private: + + DoubleBuffered mValue; ///< The double-buffered property value + int mBaseValue; ///< Reset to this base value at the beginning of each frame + +}; + +/** * An Vector2 animatable property of a scene-graph object. */ template <> diff --git a/dali/internal/update/common/property-condition-functions.cpp b/dali/internal/update/common/property-condition-functions.cpp index 30b9374..67167cf 100644 --- a/dali/internal/update/common/property-condition-functions.cpp +++ b/dali/internal/update/common/property-condition-functions.cpp @@ -49,6 +49,11 @@ ConditionFunction LessThan::GetFunction(Property::Type valueType) function = LessThan::EvalFloat; break; } + case Property::INTEGER: + { + function = LessThan::EvalInteger; + break; + } case Property::VECTOR2: { function = LessThan::EvalVector2; @@ -86,6 +91,12 @@ bool LessThan::EvalFloat( const Dali::PropertyInput& value, PropertyNotification return (value.GetFloat() < arg0); } +bool LessThan::EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) +{ + const int arg0 = arg[0]; + return (value.GetInteger() < arg0); +} + bool LessThan::EvalVector2( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) { const float arg0 = arg[0]; @@ -127,6 +138,11 @@ ConditionFunction GreaterThan::GetFunction(Property::Type valueType) function = GreaterThan::EvalFloat; break; } + case Property::INTEGER: + { + function = GreaterThan::EvalInteger; + break; + } case Property::VECTOR2: { function = GreaterThan::EvalVector2; @@ -164,6 +180,12 @@ bool GreaterThan::EvalFloat( const Dali::PropertyInput& value, PropertyNotificat return (value.GetFloat() > arg0); } +bool GreaterThan::EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) +{ + const int arg0 = arg[0]; + return (value.GetInteger() > arg0); +} + bool GreaterThan::EvalVector2( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) { const float arg0 = arg[0]; @@ -205,6 +227,11 @@ ConditionFunction Inside::GetFunction(Property::Type valueType) function = Inside::EvalFloat; break; } + case Property::INTEGER: + { + function = Inside::EvalInteger; + break; + } case Property::VECTOR2: { function = Inside::EvalVector2; @@ -242,6 +269,12 @@ bool Inside::EvalFloat( const Dali::PropertyInput& value, PropertyNotification:: return ( (valueFloat > arg[0]) && (valueFloat < arg[1]) ); } +bool Inside::EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) +{ + const int valueInteger = value.GetInteger(); + return ( (valueInteger > arg[0]) && (valueInteger < arg[1]) ); +} + bool Inside::EvalVector2( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) { const float length2 = value.GetVector2().LengthSquared(); @@ -283,6 +316,11 @@ ConditionFunction Outside::GetFunction(Property::Type valueType) function = Outside::EvalFloat; break; } + case Property::INTEGER: + { + function = Outside::EvalInteger; + break; + } case Property::VECTOR2: { function = Outside::EvalVector2; @@ -320,6 +358,12 @@ bool Outside::EvalFloat( const Dali::PropertyInput& value, PropertyNotification: return ( (valueFloat < arg[0]) || (valueFloat > arg[1]) ); } +bool Outside::EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) +{ + const int valueInterger = value.GetInteger(); + return ( (valueInterger < arg[0]) || (valueInterger > arg[1]) ); +} + bool Outside::EvalVector2( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) { const float length2 = value.GetVector2().LengthSquared(); diff --git a/dali/internal/update/common/property-condition-functions.h b/dali/internal/update/common/property-condition-functions.h index dde0e10..8296091 100644 --- a/dali/internal/update/common/property-condition-functions.h +++ b/dali/internal/update/common/property-condition-functions.h @@ -81,6 +81,14 @@ private: static bool EvalFloat( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); /** + * Checks if integer is LessThan + * @param[in] value The value being examined. + * @param[in] arg The supplied arguments for the condition. + * @return Condition result (true if condition met, false if not) + */ + static bool EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); + + /** * Checks if Vector2.Length() is LessThan * @param[in] value The value being examined. * @param[in] arg The supplied arguments for the condition. @@ -157,6 +165,14 @@ private: static bool EvalFloat( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); /** + * Checks if integer is GreaterThan + * @param[in] value The value being examined. + * @param[in] arg The supplied arguments for the condition. + * @return Condition result (true if condition met, false if not) + */ + static bool EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); + + /** * Checks if Vector2.Length() is GreaterThan * @param[in] value The value being examined. * @param[in] arg The supplied arguments for the condition. @@ -233,6 +249,14 @@ private: static bool EvalFloat( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); /** + * Checks if integer is Inside + * @param[in] value The value being examined. + * @param[in] arg The supplied arguments for the condition. + * @return Condition result (true if condition met, false if not) + */ + static bool EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); + + /** * Checks if Vector2.Length() is Inside * @param[in] value The value being examined. * @param[in] arg The supplied arguments for the condition. @@ -309,6 +333,14 @@ private: static bool EvalFloat( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); /** + * Checks if integer is Outside + * @param[in] value The value being examined. + * @param[in] arg The supplied arguments for the condition. + * @return Condition result (true if condition met, false if not) + */ + static bool EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); + + /** * Checks if Vector2.Length() is Outside * @param[in] value The value being examined. * @param[in] arg The supplied arguments for the condition. diff --git a/dali/internal/update/common/property-condition-step-functions.cpp b/dali/internal/update/common/property-condition-step-functions.cpp index 585f224..92110fd 100644 --- a/dali/internal/update/common/property-condition-step-functions.cpp +++ b/dali/internal/update/common/property-condition-step-functions.cpp @@ -51,6 +51,11 @@ ConditionFunction Step::GetFunction(Property::Type valueType) function = EvalFloat; break; } + case Property::INTEGER: + { + function = EvalInteger; + break; + } case Property::VECTOR2: { function = EvalVector2; @@ -100,6 +105,12 @@ bool Step::EvalFloat( const Dali::PropertyInput& value, PropertyNotification::Ra return Evaluate( propertyValue, arg ); } +bool Step::EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) +{ + const float propertyValue = static_cast( value.GetInteger() ); + return Evaluate( propertyValue, arg ); +} + bool Step::EvalVector2( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) { const float propertyValue = value.GetVector2().LengthSquared(); diff --git a/dali/internal/update/common/property-condition-step-functions.h b/dali/internal/update/common/property-condition-step-functions.h index 1a73e83..8f07188 100644 --- a/dali/internal/update/common/property-condition-step-functions.h +++ b/dali/internal/update/common/property-condition-step-functions.h @@ -68,6 +68,14 @@ private: static bool EvalFloat( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); /** + * Checks if integer is Outside + * @param[in] value The value being examined. + * @param[in] arg The supplied arguments for the condition. + * @return Condition result (true if condition met, false if not) + */ + static bool EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); + + /** * Checks if Vector2.Length() is Outside * @param[in] value The value being examined. * @param[in] arg The supplied arguments for the condition. diff --git a/dali/internal/update/common/property-condition-variable-step-functions.cpp b/dali/internal/update/common/property-condition-variable-step-functions.cpp index 51b2bd1..1be75e8 100644 --- a/dali/internal/update/common/property-condition-variable-step-functions.cpp +++ b/dali/internal/update/common/property-condition-variable-step-functions.cpp @@ -51,6 +51,11 @@ ConditionFunction VariableStep::GetFunction( Property::Type valueType ) function = EvalFloat; break; } + case Property::INTEGER: + { + function = EvalInteger; + break; + } case Property::VECTOR2: { function = EvalVector2; @@ -149,6 +154,12 @@ bool VariableStep::EvalFloat( const Dali::PropertyInput& value, PropertyNotifica return Evaluate( propertyValue, arg ); } +bool VariableStep::EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) +{ + const float propertyValue = static_cast( value.GetInteger() ); + return Evaluate( propertyValue, arg ); +} + bool VariableStep::EvalVector2( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ) { const float propertyValue = value.GetVector2().LengthSquared(); diff --git a/dali/internal/update/common/property-condition-variable-step-functions.h b/dali/internal/update/common/property-condition-variable-step-functions.h index b64c0c0..35927b6 100644 --- a/dali/internal/update/common/property-condition-variable-step-functions.h +++ b/dali/internal/update/common/property-condition-variable-step-functions.h @@ -73,6 +73,14 @@ private: static bool EvalFloat( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); /** + * Checks if integer is Outside + * @param[in] value The value being examined. + * @param[in] arg The supplied arguments for the condition. + * @return Condition result (true if condition met, false if not) + */ + static bool EvalInteger( const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg ); + + /** * Checks if Vector2.Length() is Outside * @param[in] value The value being examined. * @param[in] arg The supplied arguments for the condition. diff --git a/dali/public-api/animation/animation.h b/dali/public-api/animation/animation.h index 7ed8c61..f24ee9e 100644 --- a/dali/public-api/animation/animation.h +++ b/dali/public-api/animation/animation.h @@ -45,6 +45,7 @@ struct Vector4; typedef boost::function AnimatorFunctionBool; ///< Animator function signature for boolean properties. typedef boost::function AnimatorFunctionFloat; ///< Animator function signature for float properties. +typedef boost::function AnimatorFunctionInteger; ///< Animator function signature for integer properties. typedef boost::function AnimatorFunctionVector2; ///< Animator function signature for Vector2 properties. typedef boost::function AnimatorFunctionVector3; ///< Animator function signature for Vector3 properties. typedef boost::function AnimatorFunctionVector4; ///< Animator function signature for Vector4 properties. diff --git a/dali/public-api/animation/interpolator-functions.cpp b/dali/public-api/animation/interpolator-functions.cpp index 3cba421..ab3b6b0 100644 --- a/dali/public-api/animation/interpolator-functions.cpp +++ b/dali/public-api/animation/interpolator-functions.cpp @@ -40,6 +40,11 @@ float LerpFloat( const float& current, const float& target, float progress ) return current + ((target - current) * progress); } +int LerpInteger( const int& current, const int& target, float progress ) +{ + return static_cast( current + ( (target - current) * progress ) + 0.5f ); +} + Vector2 LerpVector2( const Vector2& current, const Vector2& target, float progress ) { return current + ((target - current) * progress); @@ -98,6 +103,12 @@ AnyInterpolator GetDefaultInterpolator( Property::Type type ) break; } + case Property::INTEGER: + { + function = boost::function( &LerpInteger ); + break; + } + case Property::VECTOR2: { function = boost::function( &LerpVector2 ); diff --git a/dali/public-api/animation/interpolator-functions.h b/dali/public-api/animation/interpolator-functions.h index ce3ae83..6bd8dbd 100644 --- a/dali/public-api/animation/interpolator-functions.h +++ b/dali/public-api/animation/interpolator-functions.h @@ -53,6 +53,16 @@ bool LerpBoolean( const bool& current, const bool& target, float progress ); float LerpFloat( const float& current, const float& target, float progress ); /** + * @brief Interpolate linearly between two integer values. + * + * @param [in] current The current value. + * @param [in] target The target value. + * @param [in] progress The current progress (between 0 & 1). + * @return The interpolated value. + */ +int LerpInteger( const int& current, const int& target, float progress ); + +/** * @brief Interpolate linearly between two Vector2 values. * * @param [in] current The current value. @@ -120,6 +130,16 @@ typedef boost::function IntegerInterpolator; + +/** + * @brief A function which interpolates between a start and target value. + * + * @param[in] start The start value. + * @param[in] target The target value. + * @param[in] progress The current progress (between 0 and 1). + * @return The interpolated value. + */ typedef boost::function Vector2Interpolator; /** diff --git a/dali/public-api/object/property-input.h b/dali/public-api/object/property-input.h index 0fbeacc..bd9f87e 100644 --- a/dali/public-api/object/property-input.h +++ b/dali/public-api/object/property-input.h @@ -67,6 +67,14 @@ public: virtual const float& GetFloat() const = 0; /** + * @brief Retrieve an integer value. + * + * @pre GetType() returns Property::INTEGER. + * @return The integer value. + */ + virtual const int& GetInteger() const = 0; + + /** * @brief Retrieve a Vector2 value. * * @pre GetType() returns Property::VECTOR2. -- 2.7.4