Merge "Add BuildPickingRay to devel api" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-constraint.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H
2 #define DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/event/animation/property-constraint-ptr.h>
23 #include <dali/internal/render/common/performance-monitor.h>
24 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
25 #include <dali/internal/update/common/animatable-property.h>
26 #include <dali/internal/update/common/property-owner.h>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/signals/callback.h>
29
30 namespace Dali
31 {
32 namespace Internal
33 {
34 namespace SceneGraph
35 {
36 /**
37  * Used to constrain a property of a scene-object.
38  * The constraint function takes another scene-object property as an input.
39  */
40 template<class PropertyType, typename PropertyAccessorType>
41 class Constraint : public ConstraintBase
42 {
43 public:
44   using ConstraintFunctionPtr = typename PropertyConstraintPtr<PropertyType>::Type;
45
46   /**
47    * Create a new scene-graph constraint.
48    * @param[in] targetProperty The target property.
49    * @param[in] ownerSet A set of property owners; func is connected to the properties provided by these objects.
50    * @param[in] func The function to calculate the final constrained value.
51    * @param[in] removeAction Remove action to perform when constraint is removed
52    * @return A smart-pointer to a newly allocated constraint.
53    */
54   static ConstraintBase* New(const PropertyBase&     targetProperty,
55                              PropertyOwnerContainer& ownerContainer,
56                              ConstraintFunctionPtr   func,
57                              RemoveAction            removeAction)
58   {
59     // Scene-graph thread can edit these objects
60     PropertyBase& property = const_cast<PropertyBase&>(targetProperty);
61
62     return new Constraint<PropertyType, PropertyAccessorType>(property,
63                                                               ownerContainer,
64                                                               func,
65                                                               removeAction);
66   }
67
68   /**
69    * Virtual destructor.
70    */
71   ~Constraint() override = default;
72
73   /**
74    * @copydoc Dali::Internal::SceneGraph::ConstraintBase::Apply()
75    */
76   void Apply(BufferIndex updateBufferIndex) override
77   {
78     if(!mDisconnected)
79     {
80       if(mFunc->InputsInitialized())
81       {
82         PropertyType current = mTargetProperty.Get(updateBufferIndex);
83         PropertyType old     = mTargetProperty.Get(!updateBufferIndex);
84
85         mFunc->Apply(updateBufferIndex, current);
86
87         // Compare with value of the previous frame
88         if constexpr(std::is_same_v<PropertyType, float>)
89         {
90           if(!Equals(old, current))
91           {
92             if(!mObservedOwners.Empty())
93             {
94               // The first observer is the target of the constraint
95               mObservedOwners[0]->SetUpdated(true);
96             }
97           }
98         }
99         else
100         {
101           if(old != current)
102           {
103             if(!mObservedOwners.Empty())
104             {
105               // The first observer is the target of the constraint
106               mObservedOwners[0]->SetUpdated(true);
107             }
108           }
109         }
110
111         // Optionally bake the final value
112         if(Dali::Constraint::BAKE == mRemoveAction)
113         {
114           mTargetProperty.Bake(updateBufferIndex, current);
115         }
116         else
117         {
118           mTargetProperty.Set(updateBufferIndex, current);
119         }
120
121         INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_APPLIED);
122       }
123       else
124       {
125         INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_SKIPPED);
126       }
127     }
128   }
129
130 private:
131   /**
132    * @copydoc Dali::Internal::SceneGraph::Constraint::New()
133    */
134   Constraint(PropertyBase&           targetProperty,
135              PropertyOwnerContainer& ownerContainer,
136              ConstraintFunctionPtr   func,
137              RemoveAction            removeAction)
138   : ConstraintBase(ownerContainer, removeAction),
139     mTargetProperty(&targetProperty),
140     mFunc(func)
141   {
142   }
143
144   // Undefined
145   Constraint()                             = delete;
146   Constraint(const Constraint& constraint) = delete;
147   Constraint& operator=(const Constraint& rhs) = delete;
148
149   /**
150    * @copydoc Dali::Internal::SceneGraph::ConstraintBase::OnDisconnect()
151    */
152   void OnDisconnect() override
153   {
154     // Discard target object/property pointers
155     mTargetProperty.Reset();
156     mFunc = nullptr;
157   }
158
159 protected:
160   PropertyAccessorType mTargetProperty; ///< Raw-pointer to the target property. Not owned.
161
162   ConstraintFunctionPtr mFunc;
163 };
164
165 } // namespace SceneGraph
166
167 } // namespace Internal
168
169 } // namespace Dali
170
171 #endif // DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H