Merge "Add BuildPickingRay to devel api" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-constraint.h
index ba9f660..dc6a867 100644 (file)
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H__
-
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// EXTERNAL INCLUDES
-#include <boost/function.hpp>
+#ifndef DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H
+#define DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 // INTERNAL INCLUDES
-#include <dali/public-api/animation/active-constraint.h>
-#include <dali/public-api/animation/alpha-functions.h>
-#include <dali/public-api/common/dali-common.h>
 #include <dali/internal/event/animation/property-constraint-ptr.h>
+#include <dali/internal/render/common/performance-monitor.h>
+#include <dali/internal/update/animation/scene-graph-constraint-base.h>
 #include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/common/property-owner.h>
-#include <dali/internal/update/animation/scene-graph-constraint-base.h>
-#include <dali/internal/render/common/performance-monitor.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/signals/callback.h>
 
 namespace Dali
 {
-
 namespace Internal
 {
-
 namespace SceneGraph
 {
-
 /**
  * Used to constrain a property of a scene-object.
  * The constraint function takes another scene-object property as an input.
  */
-template < class PropertyType, typename PropertyAccessorType >
+template<class PropertyType, typename PropertyAccessorType>
 class Constraint : public ConstraintBase
 {
 public:
-
-  typedef typename PropertyConstraintPtr< PropertyType >::Type ConstraintFunctionPtr;
-  typedef boost::function< PropertyType (const PropertyType&, const PropertyType&, float progress) > InterpolatorFunc;
+  using ConstraintFunctionPtr = typename PropertyConstraintPtr<PropertyType>::Type;
 
   /**
    * Create a new scene-graph constraint.
    * @param[in] targetProperty The target property.
    * @param[in] ownerSet A set of property owners; func is connected to the properties provided by these objects.
    * @param[in] func The function to calculate the final constrained value.
-   * @param[in] interpolator The function to interpolate between start & final value.
-   * @param[in] customWeight A custom weight property, or NULL if the constraint is using its own.
+   * @param[in] removeAction Remove action to perform when constraint is removed
    * @return A smart-pointer to a newly allocated constraint.
    */
-  static ConstraintBase* New( const PropertyBase& targetProperty,
-                              PropertyOwnerSet& ownerSet,
-                              ConstraintFunctionPtr func,
-                              InterpolatorFunc interpolator,
-                              const AnimatableProperty<float>* customWeight )
+  static ConstraintBase* New(const PropertyBase&     targetProperty,
+                             PropertyOwnerContainer& ownerContainer,
+                             ConstraintFunctionPtr   func,
+                             RemoveAction            removeAction)
   {
     // Scene-graph thread can edit these objects
-    PropertyBase& property = const_cast< PropertyBase& >( targetProperty );
+    PropertyBase& property = const_cast<PropertyBase&>(targetProperty);
 
-    return new Constraint< PropertyType, PropertyAccessorType >( property,
-                                                                 ownerSet,
-                                                                 func,
-                                                                 interpolator,
-                                                                 customWeight );
+    return new Constraint<PropertyType, PropertyAccessorType>(property,
+                                                              ownerContainer,
+                                                              func,
+                                                              removeAction);
   }
 
   /**
    * Virtual destructor.
    */
-  virtual ~Constraint()
-  {
-  }
-
-  /**
-   * Query whether the constraint needs to be applied. If a constraint depends on a set of properties,
-   * then it should be applied when any of those properties have changed.
-   */
-  bool ApplyNeeded()
-  {
-    if ( mFirstApply )
-    {
-      mFirstApply = false;
-      return true;
-    }
-
-    if ( ! mTargetProperty.IsClean() ||
-           mFunc->InputsChanged()    ||
-         ! mWeightInput->IsClean() )
-    {
-      return true;
-    }
-
-    // We don't need to reapply constraint if none of the properties changed
-    return false;
-  }
+  ~Constraint() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::ConstraintBase::Apply()
    */
-  virtual void Apply( BufferIndex updateBufferIndex )
+  void Apply(BufferIndex updateBufferIndex) override
   {
-    if ( mDisconnected )
+    if(!mDisconnected)
     {
-      return; // Early-out when property owners have been disconnected
-    }
+      if(mFunc->InputsInitialized())
+      {
+        PropertyType current = mTargetProperty.Get(updateBufferIndex);
+        PropertyType old     = mTargetProperty.Get(!updateBufferIndex);
 
-    if ( mFunc->InputsInitialized() &&
-         ApplyNeeded() )
-    {
-      const PropertyType& current = mTargetProperty.Get( updateBufferIndex );
+        mFunc->Apply(updateBufferIndex, current);
 
-      // FINAL_WEIGHT means the constraint is fully-applied, unless weight is still being animated
-      if ( ! mWeightInput->IsClean() ||
-           ! Equals( Dali::ActiveConstraint::FINAL_WEIGHT, (*mWeightInput)[updateBufferIndex] ) )
-      {
-        // Constraint is not fully-applied; interpolation between start & final values
-        mTargetProperty.Set( updateBufferIndex,
-                             mInterpolator( current, mFunc->Apply( updateBufferIndex, current ), (*mWeightInput)[updateBufferIndex] ) );
-      }
-      else
-      {
-        // Constraint is fully-applied; optionally bake the final value
-        if ( Dali::Constraint::Bake == mRemoveAction )
+        // Compare with value of the previous frame
+        if constexpr(std::is_same_v<PropertyType, float>)
         {
-          mTargetProperty.Bake( updateBufferIndex, mFunc->Apply( updateBufferIndex, current ) );
+          if(!Equals(old, current))
+          {
+            if(!mObservedOwners.Empty())
+            {
+              // The first observer is the target of the constraint
+              mObservedOwners[0]->SetUpdated(true);
+            }
+          }
         }
         else
         {
-          mTargetProperty.Set( updateBufferIndex, mFunc->Apply( updateBufferIndex, current ) );
+          if(old != current)
+          {
+            if(!mObservedOwners.Empty())
+            {
+              // The first observer is the target of the constraint
+              mObservedOwners[0]->SetUpdated(true);
+            }
+          }
         }
-      }
 
-      INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_APPLIED);
-    }
-    else
-    {
-      INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_SKIPPED);
+        // Optionally bake the final value
+        if(Dali::Constraint::BAKE == mRemoveAction)
+        {
+          mTargetProperty.Bake(updateBufferIndex, current);
+        }
+        else
+        {
+          mTargetProperty.Set(updateBufferIndex, current);
+        }
+
+        INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_APPLIED);
+      }
+      else
+      {
+        INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_SKIPPED);
+      }
     }
   }
 
 private:
-
   /**
    * @copydoc Dali::Internal::SceneGraph::Constraint::New()
    */
-  Constraint( PropertyBase& targetProperty,
-              PropertyOwnerSet& ownerSet,
-              ConstraintFunctionPtr func,
-              InterpolatorFunc interpolator,
-              const AnimatableProperty<float>* customWeight )
-  : ConstraintBase( ownerSet ),
-    mTargetProperty( &targetProperty ),
-    mFunc( func ),
-    mInterpolator( interpolator ),
-    mWeightInput( customWeight ? customWeight : &mWeight)
+  Constraint(PropertyBase&           targetProperty,
+             PropertyOwnerContainer& ownerContainer,
+             ConstraintFunctionPtr   func,
+             RemoveAction            removeAction)
+  : ConstraintBase(ownerContainer, removeAction),
+    mTargetProperty(&targetProperty),
+    mFunc(func)
   {
   }
 
   // Undefined
-  Constraint( const Constraint& constraint );
-
-  // Undefined
-  Constraint& operator=( const Constraint& rhs );
+  Constraint()                             = delete;
+  Constraint(const Constraint& constraint) = delete;
+  Constraint& operator=(const Constraint& rhs) = delete;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::ConstraintBase::OnDisconnect()
    */
-  virtual void OnDisconnect()
+  void OnDisconnect() override
   {
     // Discard target object/property pointers
     mTargetProperty.Reset();
-    mFunc = NULL;
+    mFunc = nullptr;
   }
 
 protected:
-
   PropertyAccessorType mTargetProperty; ///< Raw-pointer to the target property. Not owned.
 
   ConstraintFunctionPtr mFunc;
-
-  InterpolatorFunc mInterpolator;
-
-  const AnimatableProperty<float>* mWeightInput;
 };
 
 } // namespace SceneGraph
@@ -201,4 +168,4 @@ protected:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H