[Tizen] Use Dali::KeyFrames during AnimateBetween
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / animation-impl.cpp
index 6fdf660..7ef3323 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -24,6 +24,7 @@
 // INTERNAL INCLUDES
 #include <dali/internal/event/animation/animation-playlist.h>
 #include <dali/internal/event/animation/animator-connector.h>
+#include <dali/internal/event/animation/key-frames-impl.h>
 #include <dali/internal/event/animation/path-impl.h>
 #include <dali/internal/event/common/notification-manager.h>
 #include <dali/internal/event/common/property-helper.h>
@@ -393,6 +394,7 @@ void Animation::Clear()
 
   // Reset the connector target values
   mConnectorTargetValues.clear();
+  mConnectorTargetValuesSortRequired = false;
 
   // Replace the old scene-object with a new one
   DestroySceneObject();
@@ -523,8 +525,8 @@ void Animation::AnimateBy(Property& target, Property::Value relativeValue, Alpha
       DALI_ASSERT_DEBUG(false && "Property  not supported");
     }
   }
-  // Store data to later notify the object that its property is being animated
-  mConnectorTargetValues.push_back({std::move(relativeValue), period, connectorIndex, Animation::BY});
+
+  AppendConnectorTargetValues({std::move(relativeValue), period, connectorIndex, Animation::BY});
 }
 
 void Animation::AnimateTo(Property& target, Property::Value destinationValue)
@@ -643,50 +645,52 @@ void Animation::AnimateTo(Property& target, Property::Value destinationValue, Al
       DALI_ASSERT_DEBUG(false && "Property  not supported");
     }
   }
-  // Store data to later notify the object that its property is being animated
-  mConnectorTargetValues.push_back({std::move(destinationValue), period, connectorIndex, Animation::TO});
+
+  AppendConnectorTargetValues({std::move(destinationValue), period, connectorIndex, Animation::TO});
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames)
 {
   AnimateBetween(target, keyFrames, mDefaultAlpha, TimePeriod(mDurationSeconds), DEFAULT_INTERPOLATION);
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, Interpolation interpolation)
 {
   AnimateBetween(target, keyFrames, mDefaultAlpha, TimePeriod(mDurationSeconds), interpolation);
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, TimePeriod period)
 {
   AnimateBetween(target, keyFrames, mDefaultAlpha, period, DEFAULT_INTERPOLATION);
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, TimePeriod period, Interpolation interpolation)
 {
   AnimateBetween(target, keyFrames, mDefaultAlpha, period, interpolation);
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, AlphaFunction alpha)
 {
   AnimateBetween(target, keyFrames, alpha, TimePeriod(mDurationSeconds), DEFAULT_INTERPOLATION);
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, AlphaFunction alpha, Interpolation interpolation)
 {
   AnimateBetween(target, keyFrames, alpha, TimePeriod(mDurationSeconds), interpolation);
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, AlphaFunction alpha, TimePeriod period)
 {
   AnimateBetween(target, keyFrames, alpha, period, DEFAULT_INTERPOLATION);
 }
 
-void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
+void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
 {
-  Object&              object          = GetImplementation(target.object);
+  Object&          object        = GetImplementation(target.object);
+  const KeyFrames& keyFramesImpl = GetImplementation(keyFrames);
+
   const Property::Type propertyType    = object.GetPropertyType(target.propertyIndex);
-  const Property::Type destinationType = keyFrames.GetType();
+  const Property::Type destinationType = keyFramesImpl.GetType();
 
   // validate animation parameters, if component index is set then use float as checked type
   ValidateParameters((target.componentIndex == Property::INVALID_COMPONENT_INDEX) ? propertyType : Property::FLOAT,
@@ -695,15 +699,14 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
   ExtendDuration(period);
 
-  // Store data to later notify the object that its property is being animated
-  mConnectorTargetValues.push_back({keyFrames.GetLastKeyFrameValue(), period, mConnectors.Count(), BETWEEN});
+  AppendConnectorTargetValues({keyFramesImpl.GetLastKeyFrameValue(), period, mConnectors.Count(), BETWEEN});
 
   // using destination type so component animation gets correct type
   switch(destinationType)
   {
     case Dali::Property::BOOLEAN:
     {
-      auto kf = GetSpecialization<const KeyFrameBoolean*>(keyFrames);
+      auto kf = GetSpecialization<const KeyFrameBoolean*>(keyFramesImpl);
       AddAnimatorConnector(AnimatorConnector<bool>::New(object,
                                                         target.propertyIndex,
                                                         target.componentIndex,
@@ -715,7 +718,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
     case Dali::Property::INTEGER:
     {
-      auto kf = GetSpecialization<const KeyFrameInteger*>(keyFrames);
+      auto kf = GetSpecialization<const KeyFrameInteger*>(keyFramesImpl);
       AddAnimatorConnector(AnimatorConnector<int32_t>::New(object,
                                                            target.propertyIndex,
                                                            target.componentIndex,
@@ -727,7 +730,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
     case Dali::Property::FLOAT:
     {
-      auto kf = GetSpecialization<const KeyFrameNumber*>(keyFrames);
+      auto kf = GetSpecialization<const KeyFrameNumber*>(keyFramesImpl);
       AddAnimatorConnector(AnimatorConnector<float>::New(object,
                                                          target.propertyIndex,
                                                          target.componentIndex,
@@ -739,7 +742,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
     case Dali::Property::VECTOR2:
     {
-      auto kf = GetSpecialization<const KeyFrameVector2*>(keyFrames);
+      auto kf = GetSpecialization<const KeyFrameVector2*>(keyFramesImpl);
       AddAnimatorConnector(AnimatorConnector<Vector2>::New(object,
                                                            target.propertyIndex,
                                                            target.componentIndex,
@@ -751,7 +754,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
     case Dali::Property::VECTOR3:
     {
-      auto kf = GetSpecialization<const KeyFrameVector3*>(keyFrames);
+      auto kf = GetSpecialization<const KeyFrameVector3*>(keyFramesImpl);
       AddAnimatorConnector(AnimatorConnector<Vector3>::New(object,
                                                            target.propertyIndex,
                                                            target.componentIndex,
@@ -763,7 +766,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
     case Dali::Property::VECTOR4:
     {
-      auto kf = GetSpecialization<const KeyFrameVector4*>(keyFrames);
+      auto kf = GetSpecialization<const KeyFrameVector4*>(keyFramesImpl);
       AddAnimatorConnector(AnimatorConnector<Vector4>::New(object,
                                                            target.propertyIndex,
                                                            target.componentIndex,
@@ -775,7 +778,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
     case Dali::Property::ROTATION:
     {
-      auto kf = GetSpecialization<const KeyFrameQuaternion*>(keyFrames);
+      auto kf = GetSpecialization<const KeyFrameQuaternion*>(keyFramesImpl);
       AddAnimatorConnector(AnimatorConnector<Quaternion>::New(object,
                                                               target.propertyIndex,
                                                               target.componentIndex,
@@ -885,7 +888,7 @@ void Animation::Animate(Actor& actor, const Path& path, const Vector3& forward,
 
   PathPtr pathCopy = Path::Clone(path);
 
-  //Position animation
+  // Position animation
   AddAnimatorConnector(AnimatorConnector<Vector3>::New(actor,
                                                        Dali::Actor::Property::POSITION,
                                                        Property::INVALID_COMPONENT_INDEX,
@@ -893,10 +896,10 @@ void Animation::Animate(Actor& actor, const Path& path, const Vector3& forward,
                                                        alpha,
                                                        period));
 
-  //If forward is zero, PathRotationFunctor will always return the unit quaternion
+  // If forward is zero, PathRotationFunctor will always return the unit quaternion
   if(forward != Vector3::ZERO)
   {
-    //Rotation animation
+    // Rotation animation
     AddAnimatorConnector(AnimatorConnector<Quaternion>::New(actor,
                                                             Dali::Actor::Property::ORIENTATION,
                                                             Property::INVALID_COMPONENT_INDEX,
@@ -1010,11 +1013,11 @@ float Animation::GetSpeedFactor() const
 
 void Animation::SetPlayRange(const Vector2& range)
 {
-  //Make sure the range specified is between 0.0 and 1.0
+  // Make sure the range specified is between 0.0 and 1.0
   if(range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f)
   {
     Vector2 orderedRange(range);
-    //If the range is not in order swap values
+    // If the range is not in order swap values
     if(range.x > range.y)
     {
       orderedRange = Vector2(range.y, range.x);
@@ -1033,6 +1036,24 @@ Vector2 Animation::GetPlayRange() const
   return mPlayRange;
 }
 
+void Animation::SetBlendPoint(float blendPoint)
+{
+  if(blendPoint >= 0.0f && blendPoint <= 1.0f)
+  {
+    mBlendPoint = blendPoint;
+    SetBlendPointMessage(mEventThreadServices, *mAnimation, mBlendPoint);
+  }
+  else
+  {
+    DALI_LOG_ERROR("Blend Point should be a value between 0 and 1.\n");
+  }
+}
+
+float Animation::GetBlendPoint() const
+{
+  return mBlendPoint;
+}
+
 void Animation::SetLoopingMode(Dali::Animation::LoopingMode loopingMode)
 {
   mAutoReverseEnabled = (loopingMode == Dali::Animation::LoopingMode::AUTO_REVERSE);
@@ -1058,9 +1079,12 @@ void Animation::NotifyObjects(Animation::Notify notifyValueType)
   {
     // Sort according to end time with earlier end times coming first, if the end time is the same, then the connectors are not moved
     // Only do this if we're using the target value
-    if(notifyValueType == Notify::USE_TARGET_VALUE)
+    if(mConnectorTargetValuesSortRequired && notifyValueType == Notify::USE_TARGET_VALUE)
     {
       std::stable_sort(mConnectorTargetValues.begin(), mConnectorTargetValues.end(), CompareConnectorEndTimes);
+
+      // Now mConnectorTargetValues sorted. Reset flag.
+      mConnectorTargetValuesSortRequired = false;
     }
 
     // Loop through all connector target values sorted by increasing end time
@@ -1093,6 +1117,22 @@ void Animation::SendFinalProgressNotificationMessage()
   }
 }
 
+void Animation::AppendConnectorTargetValues(ConnectorTargetValues&& connectorTargetValues)
+{
+  // Check whether we need to sort mConnectorTargetValues or not.
+  // Sort will be required only if new item is smaller than last value of container.
+  if(!mConnectorTargetValuesSortRequired && !mConnectorTargetValues.empty())
+  {
+    if(CompareConnectorEndTimes(connectorTargetValues, mConnectorTargetValues.back()))
+    {
+      mConnectorTargetValuesSortRequired = true;
+    }
+  }
+
+  // Store data to later notify the object that its property is being animated
+  mConnectorTargetValues.push_back(std::move(connectorTargetValues));
+}
+
 } // namespace Internal
 
 } // namespace Dali