Merge branch 'devel/master' into tizen 34/143934/1
authorSeoyeon Kim <seoyeon2.kim@samsung.com>
Mon, 14 Aug 2017 04:57:45 +0000 (13:57 +0900)
committerSeoyeon Kim <seoyeon2.kim@samsung.com>
Mon, 14 Aug 2017 04:57:54 +0000 (13:57 +0900)
Change-Id: Id7675c8f2ba06883eb6d5bc186511dc23a265bf2

26 files changed:
automated-tests/src/dali/utc-Dali-Animation.cpp
automated-tests/src/dali/utc-Dali-CSharp-TypeRegistry.cpp
automated-tests/src/dali/utc-Dali-TypeRegistry.cpp
dali/devel-api/animation/animation-devel.cpp
dali/devel-api/animation/animation-devel.h
dali/integration-api/events/key-event-integ.cpp
dali/integration-api/events/key-event-integ.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/animation/animation-impl.cpp
dali/internal/event/animation/animation-impl.h
dali/internal/event/animation/linear-constrainer-impl.cpp
dali/internal/event/animation/linear-constrainer-impl.h
dali/internal/event/common/type-registry-impl.cpp
dali/internal/event/common/type-registry-impl.h
dali/internal/event/events/key-event-processor.cpp
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/renderers/render-texture.cpp
dali/internal/render/renderers/render-texture.h
dali/internal/update/animation/scene-graph-animation.cpp
dali/internal/update/animation/scene-graph-animation.h
dali/internal/update/animation/scene-graph-animator.h
dali/internal/update/gestures/scene-graph-pan-gesture.h
dali/public-api/animation/animation.h
dali/public-api/dali-core-version.cpp
packaging/dali.spec

index d753f98..9c2f9be 100644 (file)
@@ -11537,6 +11537,303 @@ int UtcDaliAnimationPlayAfterP3(void)
   END_TEST;
 }
 
+int UtcDaliAnimationSetLoopingModeP(void)
+{
+  // Test Loop forever and Loop mode being set
+  TestApplication application;
+  Stage stage( Stage::GetCurrent() );
+
+  // Default: LoopingMode::RESTART
+  {
+    Actor actor = Actor::New();
+    stage.Add( actor );
+
+    float durationSeconds( 1.0f );
+    Animation animation = Animation::New( durationSeconds );
+    DALI_TEST_CHECK( DevelAnimation::GetLoopingMode( animation ) == DevelAnimation::RESTART );
+
+    Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+    animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition );
+
+    // Start the animation
+    animation.Play();
+    application.SendNotification();
+    application.Render(static_cast<unsigned int>(durationSeconds*0.5f*1000.0f)/*Only half the animation*/);
+
+    actor.Unparent();
+
+    application.SendNotification();
+    application.Render();
+    DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+  }
+
+  // LoopingMode::AUTO_REVERSE
+  {
+    Actor actor = Actor::New();
+    stage.Add( actor );
+
+    float durationSeconds( 1.0f );
+    Animation animation = Animation::New( durationSeconds );
+    animation.SetLooping( true );
+
+    bool signalReceived( false );
+    AnimationFinishCheck finishCheck( signalReceived );
+    animation.FinishedSignal().Connect( &application, finishCheck );
+    application.SendNotification();
+
+    Vector3 targetPosition(100.0f, 100.0f, 100.0f);
+    animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition );
+
+    DevelAnimation::SetLoopingMode( animation, DevelAnimation::LoopingMode::AUTO_REVERSE );
+    DALI_TEST_CHECK( DevelAnimation::GetLoopingMode( animation ) == DevelAnimation::AUTO_REVERSE );
+
+    // Start the animation
+    animation.Play();
+    application.SendNotification();
+    application.Render(0);
+
+    for( int iterations = 0; iterations < 3; ++iterations )
+    {
+      application.Render( static_cast< unsigned int >( durationSeconds * 500.0f )/* 50% time progress */ );
+      application.SendNotification();
+      finishCheck.CheckSignalNotReceived();
+
+      // AUTO_REVERSE mode means, for Animation duration time, the actor starts from the beginning, passes the targetPosition,
+      // and arrives at the beginning.
+      DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+
+      application.SendNotification();
+      application.Render( static_cast< unsigned int >( durationSeconds * 500.0f )/* 100% time progress */ );
+
+      // We did expect the animation to finish
+      application.SendNotification();
+      finishCheck.CheckSignalNotReceived();
+      DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION );
+    }
+
+    animation.SetLooping( false );
+    application.SendNotification();
+    application.Render(static_cast< unsigned int >( durationSeconds * 1000.0f ) + 1u /*just beyond the animation duration*/);
+
+    application.SendNotification();
+    finishCheck.CheckSignalReceived();
+
+    DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION );
+  }
+
+  // LoopingMode::AUTO_REVERSE in Reverse mode, which begin from the end
+  {
+    Actor actor = Actor::New();
+    stage.Add( actor );
+
+    float durationSeconds( 1.0f );
+    Animation animation = Animation::New( durationSeconds );
+    animation.SetLooping( true );
+
+    bool signalReceived( false );
+    AnimationFinishCheck finishCheck( signalReceived );
+    animation.FinishedSignal().Connect( &application, finishCheck );
+    application.SendNotification();
+
+    // Specify a negative multiplier to play the animation in reverse
+    animation.SetSpeedFactor( -1.0f );
+
+    Vector3 targetPosition(100.0f, 100.0f, 100.0f);
+    animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition );
+
+    DevelAnimation::SetLoopingMode( animation, DevelAnimation::LoopingMode::AUTO_REVERSE );
+    DALI_TEST_CHECK( DevelAnimation::GetLoopingMode( animation ) == DevelAnimation::AUTO_REVERSE );
+
+    // Start the animation
+    animation.Play();
+    application.SendNotification();
+    application.Render(0);
+
+    for( int iterations = 0; iterations < 3; ++iterations )
+    {
+      application.Render( static_cast< unsigned int >( durationSeconds * 500.0f )/* 50% time progress */ );
+      application.SendNotification();
+      finishCheck.CheckSignalNotReceived();
+
+      // Setting a negative speed factor is to play the animation in reverse.
+      // So, when LoopingMode::AUTO_REVERSE and SetSpeedFactor( -1.0f ) is, for Animation duration time,
+      // the actor starts from the targetPosition, passes the beginning, and arrives at the targetPosition.
+      DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION );
+
+      application.SendNotification();
+      application.Render( static_cast< unsigned int >( durationSeconds * 500.0f )/* 100% time progress */ );
+
+      // We did expect the animation to finish
+      application.SendNotification();
+      finishCheck.CheckSignalNotReceived();
+      DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+    }
+
+    animation.SetLooping( false );
+    application.SendNotification();
+    application.Render(static_cast< unsigned int >( durationSeconds * 1000.0f ) + 1u /*just beyond the animation duration*/);
+
+    application.SendNotification();
+    finishCheck.CheckSignalReceived();
+
+    DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
+int UtcDaliAnimationSetLoopingModeP2(void)
+{
+  // Test Loop Count and Loop mode being set
+  TestApplication application;
+  Stage stage( Stage::GetCurrent() );
+
+  // LoopingMode::AUTO_REVERSE
+  {
+    Actor actor = Actor::New();
+    stage.Add( actor );
+
+    float durationSeconds( 1.0f );
+    Animation animation = Animation::New( durationSeconds );
+    animation.SetLoopCount(3);
+    DALI_TEST_CHECK(animation.IsLooping());
+
+    bool signalReceived( false );
+    AnimationFinishCheck finishCheck( signalReceived );
+    animation.FinishedSignal().Connect( &application, finishCheck );
+    application.SendNotification();
+
+    Vector3 targetPosition(100.0f, 100.0f, 100.0f);
+    animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition );
+
+    DevelAnimation::SetLoopingMode( animation, DevelAnimation::LoopingMode::AUTO_REVERSE );
+    DALI_TEST_CHECK( DevelAnimation::GetLoopingMode( animation ) == DevelAnimation::AUTO_REVERSE );
+
+    // Start the animation
+    animation.Play();
+
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+
+    // Loop
+    float intervalSeconds = 3.0f;
+
+    application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+    // AUTO_REVERSE mode means, for Animation duration time, the actor starts from the beginning, passes the targetPosition,
+    // and arrives at the beginning.
+    DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION );
+
+    application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    finishCheck.CheckSignalNotReceived();
+
+    application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+    application.SendNotification();
+    finishCheck.CheckSignalReceived();
+    DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION );
+
+    finishCheck.Reset();
+  }
+
+  // LoopingMode::AUTO_REVERSE in Reverse mode, which begin from the end
+  {
+    Actor actor = Actor::New();
+    stage.Add( actor );
+
+    float durationSeconds( 1.0f );
+    Animation animation = Animation::New( durationSeconds );
+    animation.SetLoopCount(3);
+    DALI_TEST_CHECK(animation.IsLooping());
+
+    bool signalReceived( false );
+    AnimationFinishCheck finishCheck( signalReceived );
+    animation.FinishedSignal().Connect( &application, finishCheck );
+    application.SendNotification();
+
+    // Specify a negative multiplier to play the animation in reverse
+    animation.SetSpeedFactor( -1.0f );
+
+    Vector3 targetPosition(100.0f, 100.0f, 100.0f);
+    animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition );
+
+    DevelAnimation::SetLoopingMode( animation, DevelAnimation::LoopingMode::AUTO_REVERSE );
+    DALI_TEST_CHECK( DevelAnimation::GetLoopingMode( animation ) == DevelAnimation::AUTO_REVERSE );
+
+    // Start the animation
+    animation.Play();
+
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+
+    // Loop
+    float intervalSeconds = 3.0f;
+
+    application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+    // Setting a negative speed factor is to play the animation in reverse.
+    // So, when LoopingMode::AUTO_REVERSE and SetSpeedFactor( -1.0f ) is, for Animation duration time,
+    // the actor starts from the targetPosition, passes the beginning, and arrives at the targetPosition.
+    DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+
+    application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    finishCheck.CheckSignalNotReceived();
+
+    application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+    application.SendNotification();
+    finishCheck.CheckSignalReceived();
+    DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+
+    finishCheck.Reset();
+  }
+
+  END_TEST;
+}
+
+int UtcDaliAnimationGetLoopingModeP(void)
+{
+  TestApplication application;
+
+  Animation animation = Animation::New(1.0f);
+
+  // default mode
+  DALI_TEST_CHECK( DevelAnimation::GetLoopingMode( animation ) == DevelAnimation::RESTART );
+
+  DevelAnimation::SetLoopingMode( animation, DevelAnimation::LoopingMode::AUTO_REVERSE );
+  DALI_TEST_CHECK( DevelAnimation::GetLoopingMode( animation ) == DevelAnimation::AUTO_REVERSE );
+
+  END_TEST;
+}
+
 int UtcDaliAnimationProgressSignalConnectionWithoutProgressMarkerP(void)
 {
   TestApplication application;
index 67272f3..10f60a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -111,7 +111,7 @@ int UtcDaliRegisterCSharpTypeN(void)
   }
   catch ( DaliException& e )
   {
-    DALI_TEST_ASSERT( e, "Duplicate type name for Type Registation", TEST_LOCATION );
+    DALI_TEST_ASSERT( e, "Duplicate type name in Type Registration", TEST_LOCATION );
   }
 
   END_TEST;
index 42b24c2..0594fe5 100644 (file)
@@ -880,7 +880,7 @@ int UtcDaliTypeRegistryRegisteredNameN(void)
   }
   catch ( DaliException& e )
   {
-    DALI_TEST_ASSERT( e, "Duplicate type name for Type Registation", TEST_LOCATION );
+    DALI_TEST_ASSERT( e, "Duplicate type name in Type Registration", TEST_LOCATION );
   }
 
   END_TEST;
index 5484256..79ebbb3 100644 (file)
@@ -45,6 +45,16 @@ void PlayAfter( Animation animation, float delaySeconds )
   GetImplementation( animation ).PlayAfter( delaySeconds );
 }
 
+void SetLoopingMode( Animation animation, LoopingMode loopingMode )
+{
+  GetImplementation( animation ).SetLoopingMode( loopingMode );
+}
+
+LoopingMode GetLoopingMode( Animation animation )
+{
+  return GetImplementation(animation).GetLoopingMode();
+}
+
 } // namespace DevelAnimation
 
 } // namespace Dali
index 4efa70a..209b4b0 100644 (file)
@@ -28,6 +28,15 @@ namespace DevelAnimation
 {
 
 /**
+ * @brief Enumeration for what looping mode is in.
+ */
+enum LoopingMode
+{
+  RESTART,      ///< When the animation arrives at the end in looping mode, the animation restarts from the beginning.
+  AUTO_REVERSE  ///< When the animation arrives at the end in looping mode, the animation reverses direction and runs backwards again.
+};
+
+/**
  * @brief Set progress percentage marker to trigger ProgressHasBeenReachedSignal
  *
  * @param[in] animation the animation object to perform this operation on
@@ -61,6 +70,23 @@ DALI_IMPORT_API Animation::AnimationSignalType& ProgressReachedSignal( Animation
  */
 DALI_IMPORT_API void PlayAfter( Animation animation, float delaySeconds );
 
+/**
+ * @brief Sets the looping mode.
+ *
+ * Animation plays forwards and then restarts from the beginning or runs backwards again.
+ * @param[in] animation The animation object to perform this operation on
+ * @param[in] loopingMode The looping mode is one of RESTART and AUTO_REVERSE
+ */
+DALI_IMPORT_API void SetLoopingMode( Animation animation, LoopingMode loopingMode );
+
+/**
+ * @brief Gets one of the current looping mode.
+ *
+ * @param[in] animation The animation object to perform this operation on
+ * @return The current looping mode
+ */
+DALI_IMPORT_API LoopingMode GetLoopingMode( Animation animation );
+
 } // namespace DevelAnimation
 
 } // namespace Dali
index 79da685..56dd3e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -39,7 +39,7 @@ KeyEvent::KeyEvent()
 }
 
 KeyEvent::KeyEvent( const std::string& keyName, const std::string& keyString, int keyCode, int keyModifier,
-                    unsigned long timeStamp, const State& keyState, const std::string deviceName,
+                    unsigned long timeStamp, const State& keyState, const std::string& deviceName,
                     const DevelDevice::Class::Type deviceClass, const DevelDevice::Subclass::Type deviceSubclass )
 : Event( Key ),
   keyName( keyName ),
index 536d3ef..9040707 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTEGRATION_KEY_EVENT_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -71,7 +71,7 @@ struct KeyEvent : public Event
            int keyModifier,
            unsigned long timeStamp,
            const State& keyState,
-           const std::string deviceName,
+           const std::string& deviceName,
            const DevelDevice::Class::Type deviceClass,
            const DevelDevice::Subclass::Type deviceSubclass );
 
index e0e1604..ea7fe9f 100644 (file)
@@ -4742,7 +4742,7 @@ void Actor::NegotiateDimensions( const Vector2& allocatedSize )
   }
 }
 
-Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
+Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
 {
   switch( mRelayoutData->sizeSetPolicy )
   {
@@ -4864,8 +4864,6 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont
   SetNegotiatedSize( container );
 
   // Negotiate down to children
-  const Vector2 newBounds = mTargetSize.GetVectorXY();
-
   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
   {
     ActorPtr child = GetChildAt( i );
@@ -4887,7 +4885,7 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont
     // Only relayout if required
     if( child->RelayoutRequired() )
     {
-      container.Add( Dali::Actor( child.Get() ), newBounds );
+      container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
     }
   }
   DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
index d931353..2f73da5 100644 (file)
@@ -1869,7 +1869,7 @@ private:
    * @param[in] size The size to apply the policy to
    * @return Return the adjusted size
    */
-  Vector2 ApplySizeSetPolicy( const Vector2 size );
+  Vector2 ApplySizeSetPolicy( const Vector2& size );
 
   /**
    * Retrieve the parent object of an Actor.
index b7cc899..7290bb3 100644 (file)
@@ -130,7 +130,8 @@ Animation::Animation( EventThreadServices& eventThreadServices, AnimationPlaylis
   mDefaultAlpha( defaultAlpha ),
   mState(Dali::Animation::STOPPED),
   mProgressReachedMarker( 0.0f ),
-  mDelaySeconds( 0.0f )
+  mDelaySeconds( 0.0f ),
+  mAutoReverseEnabled( false )
 {
 }
 
@@ -1023,6 +1024,19 @@ Vector2 Animation::GetPlayRange() const
   return mPlayRange;
 }
 
+void Animation::SetLoopingMode( DevelAnimation::LoopingMode loopingMode )
+{
+  mAutoReverseEnabled = ( loopingMode == DevelAnimation::LoopingMode::AUTO_REVERSE );
+
+  // mAnimation is being used in a separate thread; queue a message to set play range
+  SetLoopingModeMessage( mEventThreadServices, *mAnimation, mAutoReverseEnabled );
+}
+
+DevelAnimation::LoopingMode Animation::GetLoopingMode()
+{
+  return mAutoReverseEnabled ? DevelAnimation::LoopingMode::AUTO_REVERSE : DevelAnimation::LoopingMode::RESTART;
+}
+
 bool Animation::CompareConnectorEndTimes( const Animation::ConnectorTargetValues& lhs, const Animation::ConnectorTargetValues& rhs )
 {
   return ( ( lhs.timePeriod.delaySeconds + lhs.timePeriod.durationSeconds ) < ( rhs.timePeriod.delaySeconds + rhs.timePeriod.durationSeconds ) );
index bf1e628..760ef02 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/object/base-object.h>
+#include <dali/devel-api/animation/animation-devel.h>
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/internal/event/animation/key-frames-impl.h>
 #include <dali/internal/event/common/event-thread-services.h>
@@ -364,36 +365,46 @@ public:
    */
   void Hide(Actor& actor, float delaySeconds);
 
-  /*
+  /**
    * @copydoc Dali::Animation::SetCurrentProgress()
    */
   void SetCurrentProgress(float progress);
 
-  /*
+  /**
    * @copydoc Dali::Animation::GetCurrentProgress()
    */
   float GetCurrentProgress();
 
-  /*
+  /**
    * @copydoc Dali::Animation::SetSpeedFactor()
    */
   void SetSpeedFactor( float factor );
 
-  /*
+  /**
    * @copydoc Dali::Animation::GetSpeedFactor()
    */
   float GetSpeedFactor() const;
 
-  /*
+  /**
    * @copydoc Dali::Animation::SetPlayRange()
    */
   void SetPlayRange( const Vector2& range );
 
-  /*
-   * @copydoc Dali::Animation::GetPlayRange
+  /**
+   * @copydoc Dali::Animation::GetPlayRange()
    */
   Vector2 GetPlayRange() const;
 
+  /**
+   * @copydoc Dali::Animation::SetLoopingMode()
+   */
+  void SetLoopingMode( Dali::DevelAnimation::LoopingMode loopingMode );
+
+  /**
+   * @copydoc Dali::Animation::GetLoopingMode()
+   */
+  Dali::DevelAnimation::LoopingMode GetLoopingMode();
+
 public: // For connecting animators to animations
 
   /**
@@ -540,6 +551,7 @@ private:
   Dali::Animation::State mState;
   float mProgressReachedMarker;
   float mDelaySeconds;
+  bool mAutoReverseEnabled;  ///< Flag to identify that the looping mode is auto reverse.
 };
 
 } // namespace Internal
index 41f2357..41f6248 100644 (file)
@@ -135,7 +135,7 @@ Property::Value LinearConstrainer::GetDefaultProperty( Property::Index index ) c
   {
     Property::Value value( Property::ARRAY );
     Property::Array* array = value.GetArray();
-    size_t count( mValue.Size() );
+    size_t count( mProgress.Size() );
 
     if( array )
     {
index 6a6d78d..22cec38 100644 (file)
@@ -110,7 +110,7 @@ struct LinearConstraintFunctor
       }
       else
       {
-        while( t >= mProgress[min] && min < valueCount-1 )
+        while( ( min < valueCount-1 )&&( t >= mProgress[min] ) )
         {
           min++;
         }
@@ -118,7 +118,7 @@ struct LinearConstraintFunctor
         min--;
         max = min+1;
 
-        if( min >= valueCount-1)
+        if( min >= valueCount-1 )
         {
           min = max = valueCount-1;
           tLocal = 0.0f;
index 5d61e49..977cb87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -61,42 +61,27 @@ TypeRegistry::~TypeRegistry()
   mRegistryLut.clear();
 }
 
-Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::string &uniqueTypeName )
+Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::stringuniqueTypeName )
 {
-  Dali::TypeInfo ret;
-
-  RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
-
-  if( iter != mRegistryLut.end() )
-  {
-    ret = iter->second;
-  }
-  else
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str());
+    // Note! mRegistryLut contains Dali::TypeInfo handles, so cannot call GetTypeName()
+    // as it calls us back resulting in infinite loop (GetTypeName is in BaseHandle part)
+    if( GetImplementation( iter ).GetName() == uniqueTypeName )
+    {
+      return iter;
+    }
   }
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str() );
 
-  return ret;
+  return Dali::TypeInfo();
 }
 
 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::type_info& registerType )
 {
-  Dali::TypeInfo ret;
-
-  std::string typeName = DemangleClassName(registerType.name());
+  std::string typeName = DemangleClassName( registerType.name() );
 
-  RegistryMap::iterator iter = mRegistryLut.find(typeName);
-
-  if( iter != mRegistryLut.end() )
-  {
-    ret = iter->second;
-  }
-  else
-  {
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", registerType.name());
-  }
-
-  return ret;
+  return GetTypeInfo( typeName );
 }
 
 size_t TypeRegistry::GetTypeNameCount() const
@@ -105,15 +90,13 @@ size_t TypeRegistry::GetTypeNameCount() const
 }
 
 
-std::string TypeRegistry::GetTypeName(size_t index) const
+std::string TypeRegistry::GetTypeName( size_t index ) const
 {
   std::string name;
 
   if( index < mRegistryLut.size() )
   {
-    RegistryMap::const_iterator iter = mRegistryLut.begin();
-    std::advance(iter, index);
-    name = iter->first;
+    name = GetImplementation( mRegistryLut[ index ] ).GetName();
   }
 
   return name;
@@ -123,7 +106,7 @@ std::string TypeRegistry::GetTypeName(size_t index) const
 bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_info& baseTypeInfo,
                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
 {
-  std::string uniqueTypeName  = DemangleClassName(theTypeInfo.name());
+  std::string uniqueTypeName  = DemangleClassName( theTypeInfo.name() );
 
   return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit );
 }
@@ -131,61 +114,55 @@ bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_
 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
 {
-  bool ret = false;
+  std::string baseTypeName = DemangleClassName( baseTypeInfo.name() );
 
-  std::string baseTypeName    = DemangleClassName(baseTypeInfo.name());
-
-  RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
-
-  if( iter == mRegistryLut.end() )
-  {
-    mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance));
-    ret = true;
-    DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
-  }
-  else
+  // check for duplicates using uniqueTypeName
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str());
-    DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation");
+    if( GetImplementation( iter ).GetName() == uniqueTypeName )
+    {
+      DALI_LOG_WARNING( "Duplicate name in TypeRegistry for '%s'\n", + uniqueTypeName.c_str() );
+      DALI_ASSERT_ALWAYS( !"Duplicate type name in Type Registration" );
+      return false;
+    }
   }
 
+  mRegistryLut.push_back( Dali::TypeInfo( new Internal::TypeInfo( uniqueTypeName, baseTypeName, createInstance ) ) );
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str() );
+
   if( callCreateOnInit )
   {
     mInitFunctions.push_back(createInstance);
   }
 
-  return ret;
+  return true;
 }
 
 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
     Dali::CSharpTypeInfo::CreateFunction createInstance )
 {
+  std::string baseTypeName = DemangleClassName( baseTypeInfo.name() );
 
-  bool ret = false;
-
-  std::string baseTypeName    = DemangleClassName(baseTypeInfo.name());
-
-  RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
-
-  if( iter == mRegistryLut.end() )
-  {
-    mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance));
-    ret = true;
-    DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
-  }
-  else
+  // check for duplicates using uniqueTypeName
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str());
-    DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation");
+    if( GetImplementation( iter ).GetName() == uniqueTypeName )
+    {
+      DALI_LOG_WARNING( "Duplicate name in TypeRegistry for '%s'\n", + uniqueTypeName.c_str() );
+      DALI_ASSERT_ALWAYS( !"Duplicate type name in Type Registration" );
+      return false;
+    }
   }
 
-  return ret;
+  mRegistryLut.push_back( Dali::TypeInfo( new Internal::TypeInfo( uniqueTypeName, baseTypeName, createInstance ) ) );
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str() );
 
+  return true;
 }
 
 void TypeRegistry::CallInitFunctions(void) const
 {
-  for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter)
+  for( auto&& iter : mInitFunctions )
   {
     (*iter)();
   }
@@ -198,45 +175,41 @@ std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
 
 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunction func )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() );
-
-  if( iter != mRegistryLut.end() )
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddConnectorFunction( name, func );
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == typeRegistration.RegisteredName() )
+    {
+      impl.AddConnectorFunction( name, func );
+      break;
+    }
   }
 }
 
-bool TypeRegistry::RegisterAction( TypeRegistration &registered, const std::string &name, Dali::TypeInfo::ActionFunction f)
+bool TypeRegistry::RegisterAction( TypeRegistration& typeRegistration, const std::string &name, Dali::TypeInfo::ActionFunction f )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
-
-  if( iter != mRegistryLut.end() )
-  {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddActionFunction( name, f );
-
-    return true;
-  }
-  else
+  for( auto&& iter : mRegistryLut )
   {
-    return false;
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == typeRegistration.RegisteredName() )
+    {
+      impl.AddActionFunction( name, f );
+      return true;
+    }
   }
+  return false;
 }
 
-bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
+bool TypeRegistry::RegisterProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
-
-  if( iter != mRegistryLut.end() )
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
-
-    return true;
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == typeRegistration.RegisteredName() )
+    {
+      impl.AddProperty( name, index, type, setFunc, getFunc );
+      return true;
+    }
   }
 
   return false;
@@ -244,87 +217,81 @@ bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::st
 
 bool TypeRegistry::RegisterProperty( const std::string& objectName, const std::string& name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( objectName );
-
-  if( iter != mRegistryLut.end() )
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
-
-    return true;
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == objectName )
+    {
+      impl.AddProperty( name, index, type, setFunc, getFunc );
+      return true;
+    }
   }
 
   return false;
-
 }
 
 
-bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
+bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Type type )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
-
-  if( iter != mRegistryLut.end() )
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddAnimatableProperty( name, index, type );
-
-    return true;
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == typeRegistration.RegisteredName() )
+    {
+      impl.AddAnimatableProperty( name, index, type );
+      return true;
+    }
   }
 
   return false;
 }
 
-bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, const Property::Value& value )
+bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, const Property::Value& value )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
-
-  if( iter != mRegistryLut.end() )
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddAnimatableProperty( name, index, value );
-
-    return true;
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == typeRegistration.RegisteredName() )
+    {
+      impl.AddAnimatableProperty( name, index, value );
+      return true;
+    }
   }
 
   return false;
 }
 
-bool TypeRegistry::RegisterAnimatablePropertyComponent( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
+bool TypeRegistry::RegisterAnimatablePropertyComponent( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
-
-  if( iter != mRegistryLut.end() )
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddAnimatablePropertyComponent( name, index, baseIndex, componentIndex );
-
-    return true;
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == typeRegistration.RegisteredName() )
+    {
+      impl.AddAnimatablePropertyComponent( name, index, baseIndex, componentIndex );
+      return true;
+    }
   }
 
   return false;
 }
 
-bool TypeRegistry::RegisterChildProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
+bool TypeRegistry::RegisterChildProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Type type )
 {
-  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
-
-  if( iter != mRegistryLut.end() )
+  for( auto&& iter : mRegistryLut )
   {
-    DALI_ASSERT_DEBUG(iter->second);
-
-    GetImplementation(iter->second).AddChildProperty( name, index, type );
-
-    return true;
+    auto&& impl = GetImplementation( iter );
+    if( impl.GetName() == typeRegistration.RegisteredName() )
+    {
+      impl.AddChildProperty( name, index, type );
+      return true;
+    }
   }
 
   return false;
 }
 
-bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const Property::Map &properties)
+bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string& actionName, const Property::Map& properties )
 {
   bool done = false;
 
@@ -332,12 +299,13 @@ bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &act
 
   while( type )
   {
-    if(GetImplementation(type).DoActionTo(object, actionName, properties))
+    auto&& impl = GetImplementation( type );
+    if( impl.DoActionTo( object, actionName, properties ) )
     {
       done = true;
       break;
     }
-    type = GetTypeInfo( type.GetBaseName() );
+    type = GetTypeInfo( impl.GetBaseName() );
   }
 
   return done;
@@ -351,12 +319,13 @@ bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface
 
   while( type )
   {
-    connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
+    auto&& impl = GetImplementation( type );
+    connected = impl.ConnectSignal( object, connectionTracker, signalName, functor );
     if( connected )
     {
       break;
     }
-    type = GetTypeInfo( type.GetBaseName() );
+    type = GetTypeInfo( impl.GetBaseName() );
   }
 
   if( !connected )
index 0690de2..47364f3 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTERNAL_TYPE_REGISTRY_H__
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@
  */
 
 // INTERNAL INCLUDES
-#include <dali/devel-api/common/map-wrapper.h>
 #include <dali/devel-api/object/csharp-type-info.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/public-api/object/base-handle.h>
@@ -215,13 +214,11 @@ public:
 
 private:
   /*
-   * Map from type name to TypeInfo
+   * Mapping from type name to TypeInfo
    */
-  typedef std::map<std::string, Dali::TypeInfo> RegistryMap;
-  RegistryMap mRegistryLut;
+  std::vector< Dali::TypeInfo > mRegistryLut;
 
-  typedef std::vector<Dali::TypeInfo::CreateFunction> InitFunctions;
-  InitFunctions mInitFunctions;
+  std::vector< Dali::TypeInfo::CreateFunction > mInitFunctions;
 
 private:
   TypeRegistry();
index 5afb81b..92daa90 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -42,7 +42,6 @@ KeyEventProcessor::~KeyEventProcessor()
 
 void KeyEventProcessor::ProcessKeyEvent(const Integration::KeyEvent& event)
 {
-  bool consumed = false;
   KeyEvent keyEvent(event.keyName, event.keyString, event.keyCode, event.keyModifier, event.time, static_cast<Dali::KeyEvent::State>(event.state));
 
   GetImplementation( &keyEvent )->SetDeviceName( event.deviceName );
@@ -50,7 +49,7 @@ void KeyEventProcessor::ProcessKeyEvent(const Integration::KeyEvent& event)
   GetImplementation( &keyEvent )->SetDeviceSubclass( event.deviceSubclass );
 
   // Emit the key event signal from stage.
-  consumed = mStage.EmitKeyEventGeneratedSignal( keyEvent );
+  bool consumed = mStage.EmitKeyEventGeneratedSignal( keyEvent );
 
   if( !consumed )
   {
index 0c50ce4..e31b8fe 100644 (file)
@@ -199,8 +199,7 @@ inline void SetupStencilBuffer( const RenderItem& item, Context& context, bool&
 
       // Setup the color buffer based on the RenderMode.
       context.ColorMask( renderMode == RenderMode::COLOR );
-      return;
-      break; // Break statement for consistency (although return will be called instead).
+      break;
     }
 
     case RenderMode::STENCIL:
index b4646d5..572e4f2 100644 (file)
 // CLASS HEADER
 #include <dali/internal/render/renderers/render-texture.h>
 
+// EXTERNAL INCLUDES
+#include <math.h>   //floor, log2
+
 // INTERNAL INCLUDES
 #include <dali/devel-api/images/pixel-devel.h>
 #include <dali/devel-api/images/native-image-interface-extension.h>
 
-// EXTERNAL INCLUDES
-#include <math.h>   //floor, log2
-
 namespace Dali
 {
 namespace Internal
index f96ca9d..d9192e0 100644 (file)
@@ -21,6 +21,7 @@
 #include <string>
 
 // INTERNAL INCLUDES
+#include <dali/public-api/images/image-operations.h> // Dali::ImageDimensions
 #include <dali/public-api/rendering/sampler.h>
 #include <dali/public-api/rendering/texture.h>
 #include <dali/internal/event/rendering/texture-impl.h>
index 9ce8ef0..709d7e7 100644 (file)
@@ -77,7 +77,8 @@ Animation::Animation( float durationSeconds, float speedFactor, const Vector2& p
   mEndAction(endAction),
   mDisconnectAction(disconnectAction),
   mState(Stopped),
-  mProgressReachedSignalRequired( false )
+  mProgressReachedSignalRequired( false ),
+  mAutoReverseEnabled( false )
 {
 }
 
@@ -278,6 +279,20 @@ void Animation::OnDestroy(BufferIndex bufferIndex)
   mState = Destroyed;
 }
 
+void Animation::SetLoopingMode( bool loopingMode )
+{
+  mAutoReverseEnabled = loopingMode;
+
+  for ( AnimatorIter iter = mAnimators.Begin(), endIter = mAnimators.End(); iter != endIter; ++iter )
+  {
+    // Send some variables together to figure out the Animation status
+    (*iter)->SetSpeedFactor( mSpeedFactor );
+    (*iter)->SetLoopCount( mLoopCount );
+
+    (*iter)->SetLoopingMode( loopingMode );
+  }
+}
+
 void Animation::AddAnimator( OwnerPointer<AnimatorBase>& animator )
 {
   animator->ConnectToSceneGraph();
index 3e27055..a30a347 100644 (file)
@@ -106,7 +106,7 @@ public:
     return mDurationSeconds;
   }
 
-  /*
+  /**
    * Retrieve the current progress of the animation.
    * @return The current progress as a normalized value between [0,1].
    */
@@ -120,7 +120,7 @@ public:
     return 0.0f;
   }
 
-  /*
+  /**
    * Sets the progress of the animation.
    * @param[in] The new progress as a normalized value between [0,1]
    */
@@ -129,6 +129,10 @@ public:
     mElapsedSeconds = mDurationSeconds * progress;
   }
 
+  /**
+   * Specifies a speed factor for the animation.
+   * @param[in] factor A value which will multiply the velocity
+   */
   void SetSpeedFactor( float factor )
   {
     mSpeedFactor = factor;
@@ -150,7 +154,7 @@ public:
     return mLoopCount != 1;
   }
 
-  /*
+  /**
    * Get the loop count
    * @return the loop count
    */
@@ -262,6 +266,14 @@ public:
   }
 
   /**
+   * @brief Sets the looping mode.
+   *
+   * Animation plays forwards and then restarts from the beginning or runs backwards again.
+   * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
+   */
+  void SetLoopingMode( bool loopingMode );
+
+  /**
    * Add a newly created animator.
    * Animators are automatically removed, when orphaned from an animatable scene object.
    * @param[in] animator The animator to add.
@@ -352,6 +364,7 @@ protected:
   State mState;
 
   bool mProgressReachedSignalRequired;  // Flag to indicate the progress marker was hit
+  bool mAutoReverseEnabled;             // Flag to identify that the looping mode is auto reverse.
 };
 
 }; //namespace SceneGraph
@@ -509,6 +522,17 @@ inline void PlayAfterMessage( EventThreadServices& eventThreadServices, const An
   new (slot) LocalType( &animation, &Animation::PlayAfter, delaySeconds );
 }
 
+inline void SetLoopingModeMessage( EventThreadServices& eventThreadServices, const Animation& animation, bool loopingMode )
+{
+  typedef MessageValue1< Animation, bool > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &animation, &Animation::SetLoopingMode, loopingMode );
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index d1cac15..19d4ecc 100644 (file)
@@ -32,7 +32,7 @@
 #include <dali/public-api/math/quaternion.h>
 #include <dali/public-api/math/radian.h>
 #include <dali/internal/update/animation/property-accessor.h>
-
+#include <dali/integration-api/debug.h>
 
 namespace Dali
 {
@@ -70,11 +70,14 @@ public:
   AnimatorBase()
   : mDurationSeconds(1.0f),
     mIntervalDelaySeconds(0.0f),
+    mSpeedFactor(1.0f),
+    mLoopCount(1),
     mAlphaFunction(AlphaFunction::DEFAULT),
     mDisconnectAction(Dali::Animation::BakeFinal),
     mActive(false),
     mEnabled(true),
-    mConnectedToSceneGraph(false)
+    mConnectedToSceneGraph(false),
+    mAutoReverseEnabled( false )
   {
   }
 
@@ -111,6 +114,36 @@ public:
     return mDurationSeconds;
   }
 
+  void SetSpeedFactor( float factor )
+  {
+    mSpeedFactor = factor;
+  }
+
+  void SetLoopCount(int loopCount)
+  {
+    mLoopCount = loopCount;
+  }
+
+  float SetProgress( float progress )
+  {
+    float value = 0.0f;
+
+    if( mAutoReverseEnabled )
+    {
+      if( mSpeedFactor > 0.0f )
+      {
+        value = 1.0f - 2.0f * std::abs( progress - 0.5f );
+      }
+      // Reverse mode
+      else if( mSpeedFactor < 0.0f )
+      {
+        value = 2.0f * std::abs( progress - 0.5f );
+      }
+    }
+
+    return value;
+  }
+
   /**
    * Set the delay before the animator should take effect.
    * The default is zero i.e. no delay.
@@ -148,7 +181,7 @@ public:
     return mAlphaFunction;
   }
 
-  /*
+  /**
    * Applies the alpha function to the specified progress
    * @param[in] Current progress
    * @return The progress after the alpha function has been aplied
@@ -317,7 +350,7 @@ public:
     return mActive;
   }
 
-  /*
+  /**
    * Retrive wheter the animator's target object is valid and on the stage.
    * @return The enabled state.
    */
@@ -325,6 +358,16 @@ public:
   {
     return mEnabled;
   }
+
+  /**
+   * @brief Sets the looping mode.
+   * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
+   */
+  void SetLoopingMode( bool loopingMode )
+  {
+    mAutoReverseEnabled = loopingMode;
+  }
+
   /**
    * Returns wheter the target object of the animator is still valid
    * or has been destroyed.
@@ -358,6 +401,9 @@ protected:
 
   float mDurationSeconds;
   float mIntervalDelaySeconds;
+  float mSpeedFactor;
+
+  int mLoopCount;
 
   AlphaFunction mAlphaFunction;
 
@@ -365,6 +411,7 @@ protected:
   bool mActive:1;                                   ///< Animator is "active" while it's running.
   bool mEnabled:1;                                  ///< Animator is "enabled" while its target object is valid and on the stage.
   bool mConnectedToSceneGraph:1;                    ///< True if ConnectToSceneGraph() has been called in update-thread.
+  bool mAutoReverseEnabled:1;
 };
 
 /**
@@ -462,7 +509,13 @@ public:
    */
   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
   {
-    float alpha = ApplyAlphaFunction(progress);
+    if( mLoopCount != 1 ) // Looping mode
+    {
+      // Update the progress value
+      progress = SetProgress( progress );
+    }
+
+    float alpha = ApplyAlphaFunction( progress );
 
     const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
 
@@ -615,7 +668,13 @@ public:
    */
   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
   {
-    float alpha = ApplyAlphaFunction(progress);
+    if( mLoopCount != 1 ) // Looping mode
+    {
+      // Update the progress value
+      progress = SetProgress( progress );
+    }
+
+    float alpha = ApplyAlphaFunction( progress );
 
     const T& current = mPropertyAccessor.Get( bufferIndex );
 
index 459c8fe..ad4e5e0 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTERNAL_SCENE_GRAPH_PAN_GESTURE_H__
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -143,6 +143,7 @@ public:
         state = rhs.state;
         local = rhs.local;
         screen = rhs.screen;
+        read = rhs.read;
       }
 
       return *this;
index 29160c3..c73e2b0 100644 (file)
@@ -340,7 +340,7 @@ public:
    */
   AlphaFunction GetDefaultAlphaFunction() const;
 
-  /*
+  /**
    * @brief Sets the progress of the animation.
    *
    * The animation will play (or continue playing) from this point. The progress
index c1cd194..16bf03a 100644 (file)
@@ -28,7 +28,7 @@ namespace Dali
 
 const unsigned int CORE_MAJOR_VERSION = 1;
 const unsigned int CORE_MINOR_VERSION = 2;
-const unsigned int CORE_MICRO_VERSION = 50;
+const unsigned int CORE_MICRO_VERSION = 52;
 const char * const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index f4818d8..c983c97 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali
 Summary:    The OpenGLES Canvas Core Library
-Version:    1.2.50
+Version:    1.2.52
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT