Revert "[Tizen] Not execute the remove callback"
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / constraint-impl.h
1 #ifndef DALI_INTERNAL_ACTIVE_CONSTRAINT_H
2 #define DALI_INTERNAL_ACTIVE_CONSTRAINT_H
3
4 /*
5  * Copyright (c) 2021 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/common/message.h>
23 #include <dali/internal/event/animation/constraint-base.h>
24 #include <dali/internal/event/animation/constraint-source-impl.h>
25 #include <dali/internal/event/animation/property-constraint-ptr.h>
26 #include <dali/internal/event/common/event-thread-services.h>
27 #include <dali/internal/event/common/object-impl.h>
28 #include <dali/internal/event/common/stage-impl.h>
29 #include <dali/internal/event/common/thread-local-storage.h>
30 #include <dali/internal/update/animation/property-accessor.h>
31 #include <dali/internal/update/animation/property-component-accessor.h>
32 #include <dali/internal/update/animation/scene-graph-constraint.h>
33 #include <dali/internal/update/common/animatable-property.h>
34 #include <dali/internal/update/common/property-owner-messages.h>
35 #include <dali/internal/update/common/property-owner.h>
36 #include <dali/internal/update/common/property-resetter.h>
37 #include <memory>
38
39 namespace Dali
40 {
41 namespace Internal
42 {
43 /**
44  * Connects a constraint which takes another property as an input.
45  */
46 template<typename PropertyType>
47 class Constraint : public ConstraintBase
48 {
49 public:
50   using ConstraintFunctionPtr = typename PropertyConstraintPtr<PropertyType>::Type;
51
52   /**
53    * Construct a new constraint.
54    * @param[in] object The property-owning object.
55    * @param[in] targetIndex The index of the property to constrain.
56    * @param[in] sources The sources of the input properties passed to func.
57    * @param[in] func The constraint function.
58    * @return A newly allocated active-constraint.
59    */
60   static ConstraintBase* New(Object&               object,
61                              Property::Index       targetIndex,
62                              SourceContainer&      sources,
63                              ConstraintFunctionPtr func)
64   {
65     return new Constraint(object, targetIndex, sources, func);
66   }
67
68   /**
69    * Virtual destructor.
70    */
71   ~Constraint() override
72   {
73     // This is not responsible for removing constraints.
74   }
75
76 private:
77   /**
78    * @copydoc ConstraintBase::DoClone()
79    */
80   ConstraintBase* DoClone(Object& object) final
81   {
82     ConstraintFunctionPtr funcPtr(mUserFunction->Clone());
83     return new Constraint(object,
84                           mTargetPropertyIndex,
85                           mSources,
86                           funcPtr);
87   }
88
89   /**
90    * Private constructor; see also Constraint::New().
91    */
92   Constraint(Object&                object,
93              Property::Index        targetIndex,
94              SourceContainer&       sources,
95              ConstraintFunctionPtr& func)
96   : ConstraintBase(object, targetIndex, sources),
97     mUserFunction(func)
98   {
99   }
100
101   // Undefined
102   Constraint()                  = delete;
103   Constraint(const Constraint&) = delete;
104   Constraint& operator=(const Constraint& rhs) = delete;
105
106   /**
107    * @copydoc ConstraintBase::ConnectConstraint()
108    */
109   void ConnectConstraint() final
110   {
111     // Should not come here if target object has been destroyed
112     DALI_ASSERT_DEBUG(nullptr != mTargetObject);
113
114     // Guard against double connections
115     DALI_ASSERT_DEBUG(nullptr == mSceneGraphConstraint);
116
117     SceneGraph::PropertyOwner& targetObject = const_cast<SceneGraph::PropertyOwner&>(mTargetObject->GetSceneObject());
118
119     // Build a container of property-owners, providing the scene-graph properties
120     SceneGraph::PropertyOwnerContainer propertyOwners;
121     propertyOwners.PushBack(&targetObject);
122
123     // Build the constraint function; this requires a scene-graph property from each source
124     ConstraintFunctionPtr func(ConnectConstraintFunction(propertyOwners));
125
126     if(func)
127     {
128       OwnerPointer<SceneGraph::PropertyResetterBase> resetter;
129       // Create the SceneGraphConstraint and PropertyResetter, and connect them to the scene-graph
130       const SceneGraph::PropertyBase* targetProperty = mTargetObject->GetSceneObjectAnimatableProperty(mTargetPropertyIndex);
131       DALI_ASSERT_ALWAYS(targetProperty && "Constraint target property does not exist");
132       if(targetProperty->IsTransformManagerProperty()) //It is a property managed by the transform manager
133       {
134         // Connect the constraint
135         mSceneGraphConstraint = SceneGraph::Constraint<PropertyType, TransformManagerPropertyAccessor<PropertyType> >::New(*targetProperty,
136                                                                                                                            propertyOwners,
137                                                                                                                            func,
138                                                                                                                            mRemoveAction);
139         // Don't create a resetter for transform manager property, it's less efficient
140       }
141       else //SceneGraph property
142       {
143         // Connect the constraint
144         mSceneGraphConstraint = SceneGraph::Constraint<PropertyType, PropertyAccessor<PropertyType> >::New(*targetProperty,
145                                                                                                            propertyOwners,
146                                                                                                            func,
147                                                                                                            mRemoveAction);
148         resetter              = SceneGraph::ConstraintResetter::New(targetObject, *targetProperty, *mSceneGraphConstraint);
149       }
150       OwnerPointer<SceneGraph::ConstraintBase> transferOwnership(const_cast<SceneGraph::ConstraintBase*>(mSceneGraphConstraint));
151       ApplyConstraintMessage(GetEventThreadServices(), targetObject, transferOwnership);
152       if(resetter)
153       {
154         AddResetterMessage(GetEventThreadServices().GetUpdateManager(), resetter);
155       }
156     }
157   }
158
159   /**
160    * Helper for ConnectConstraint. Creates a connected constraint-function.
161    * Also populates the property-owner container, for each input connected to the constraint-function.
162    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
163    * @return A connected constraint-function, or nullptr if the scene-graph properties are not available.
164    */
165   PropertyConstraint<PropertyType>* ConnectConstraintFunction(SceneGraph::PropertyOwnerContainer& propertyOwners)
166   {
167     PropertyConstraint<PropertyType>* func = mUserFunction->Clone();
168
169     for(auto&& source : mSources)
170     {
171       int32_t            componentIndex = Property::INVALID_COMPONENT_INDEX;
172       PropertyInputImpl* inputProperty  = AddInputProperty(source, propertyOwners, componentIndex);
173
174       if(nullptr == inputProperty)
175       {
176         delete func;
177         func = nullptr;
178
179         // Exit if a scene-graph object is not available from one of the sources
180         break;
181       }
182
183       func->AddInput(inputProperty, componentIndex);
184     }
185
186     return func;
187   }
188
189 protected:
190   ConstraintFunctionPtr mUserFunction;
191 };
192
193 /**
194  * Variant which allows float components to be constrained individually.
195  */
196 template<>
197 class Constraint<float> : public ConstraintBase
198 {
199 public:
200   using ConstraintFunctionPtr = typename PropertyConstraintPtr<float>::Type;
201
202   /**
203    * Construct a new constraint.
204    * @param[in] object The property-owning object.
205    * @param[in] targetIndex The index of the property to constrain.
206    * @param[in] sources The sources of the input properties passed to func.
207    * @param[in] func The constraint function.
208    * @return A newly allocated constraint.
209    */
210   static ConstraintBase* New(Object&               object,
211                              Property::Index       targetIndex,
212                              SourceContainer&      sources,
213                              ConstraintFunctionPtr func)
214   {
215     return new Constraint(object, targetIndex, sources, func);
216   }
217
218   /**
219    * Virtual destructor.
220    */
221   ~Constraint() override
222   {
223     // This is not responsible for removing constraints.
224   }
225
226 private:
227   /**
228    * @copydoc ConstraintBase::DoClone()
229    */
230   ConstraintBase* DoClone(Object& object) final
231   {
232     ConstraintFunctionPtr funcPtr(mUserFunction->Clone());
233     return new Constraint(object,
234                           mTargetPropertyIndex,
235                           mSources,
236                           funcPtr);
237   }
238
239   /**
240    * Private constructor; see also Constraint::New().
241    */
242   Constraint(Object&                object,
243              Property::Index        targetIndex,
244              SourceContainer&       sources,
245              ConstraintFunctionPtr& func)
246   : ConstraintBase(object, targetIndex, sources),
247     mUserFunction(func)
248   {
249   }
250
251   // Undefined
252   Constraint()                  = delete;
253   Constraint(const Constraint&) = delete;
254   Constraint& operator=(const Constraint& rhs) = delete;
255
256   /**
257    * @copydoc ConstraintBase::ConnectConstraint()
258    */
259   void ConnectConstraint() final
260   {
261     // Should not come here if target object has been destroyed
262     DALI_ASSERT_DEBUG(nullptr != mTargetObject);
263     // Guard against double connections
264     DALI_ASSERT_DEBUG(nullptr == mSceneGraphConstraint);
265
266     SceneGraph::PropertyOwner& targetObject = const_cast<SceneGraph::PropertyOwner&>(mTargetObject->GetSceneObject());
267
268     // Build a container of property-owners, providing the scene-graph properties
269     SceneGraph::PropertyOwnerContainer propertyOwners;
270     propertyOwners.PushBack(&targetObject);
271
272     // Build the constraint function; this requires a scene-graph property from each source
273     ConstraintFunctionPtr func(ConnectConstraintFunction(propertyOwners));
274
275     if(func)
276     {
277       // Create the SceneGraphConstraint, and connect to the scene-graph
278       bool                            resetterRequired = false;
279       const SceneGraph::PropertyBase* targetProperty   = mTargetObject->GetSceneObjectAnimatableProperty(mTargetPropertyIndex);
280       // The targetProperty should exist, when targetObject exists
281       DALI_ASSERT_ALWAYS(nullptr != targetProperty && "Constraint target property does not exist");
282       const int32_t componentIndex = mTargetObject->GetPropertyComponentIndex(mTargetPropertyIndex);
283       if(Property::INVALID_COMPONENT_INDEX == componentIndex)
284       {
285         // Not a Vector2, Vector3 or Vector4 component, expecting float type
286         DALI_ASSERT_DEBUG(PropertyTypes::Get<float>() == targetProperty->GetType());
287
288         mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyAccessor<float> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
289         resetterRequired      = true;
290       }
291       else
292       {
293         // Expecting Vector2, Vector3 or Vector4 type
294         if(PropertyTypes::Get<Vector2>() == targetProperty->GetType())
295         {
296           // Constrain float component of Vector2 property
297           if(0 == componentIndex)
298           {
299             mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorX<Vector2> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
300           }
301           else if(1 == componentIndex)
302           {
303             mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorY<Vector2> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
304           }
305           resetterRequired = (mSceneGraphConstraint != nullptr);
306         }
307         else if(PropertyTypes::Get<Vector3>() == targetProperty->GetType())
308         {
309           // Constrain float component of Vector3 property
310           if(targetProperty->IsTransformManagerProperty())
311           {
312             if(0 == componentIndex)
313             {
314               mSceneGraphConstraint = SceneGraph::Constraint<float, TransformManagerPropertyComponentAccessor<Vector3, 0> >::New(*targetProperty,
315                                                                                                                                  propertyOwners,
316                                                                                                                                  func,
317                                                                                                                                  mRemoveAction);
318             }
319             else if(1 == componentIndex)
320             {
321               mSceneGraphConstraint = SceneGraph::Constraint<float, TransformManagerPropertyComponentAccessor<Vector3, 1> >::New(*targetProperty,
322                                                                                                                                  propertyOwners,
323                                                                                                                                  func,
324                                                                                                                                  mRemoveAction);
325             }
326             else if(2 == componentIndex)
327             {
328               mSceneGraphConstraint = SceneGraph::Constraint<float, TransformManagerPropertyComponentAccessor<Vector3, 2> >::New(*targetProperty,
329                                                                                                                                  propertyOwners,
330                                                                                                                                  func,
331                                                                                                                                  mRemoveAction);
332             }
333             // Do not create a resetter for transform manager property
334           }
335           else
336           {
337             if(0 == componentIndex)
338             {
339               mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorX<Vector3> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
340             }
341             else if(1 == componentIndex)
342             {
343               mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorY<Vector3> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
344             }
345             else if(2 == componentIndex)
346             {
347               mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorZ<Vector3> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
348             }
349             resetterRequired = (mSceneGraphConstraint != nullptr);
350           }
351         }
352         else if(PropertyTypes::Get<Vector4>() == targetProperty->GetType())
353         {
354           // Constrain float component of Vector4 property
355           if(0 == componentIndex)
356           {
357             mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorX<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
358           }
359           else if(1 == componentIndex)
360           {
361             mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorY<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
362           }
363           else if(2 == componentIndex)
364           {
365             mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorZ<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
366           }
367           else if(3 == componentIndex)
368           {
369             mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorW<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
370           }
371
372           resetterRequired = (mSceneGraphConstraint != nullptr);
373         }
374       }
375       if(mSceneGraphConstraint)
376       {
377         OwnerPointer<SceneGraph::ConstraintBase> transferOwnership(const_cast<SceneGraph::ConstraintBase*>(mSceneGraphConstraint));
378         ApplyConstraintMessage(GetEventThreadServices(), targetObject, transferOwnership);
379         if(resetterRequired)
380         {
381           OwnerPointer<SceneGraph::PropertyResetterBase> resetter = SceneGraph::ConstraintResetter::New(targetObject, *targetProperty, *mSceneGraphConstraint);
382           AddResetterMessage(GetEventThreadServices().GetUpdateManager(), resetter);
383         }
384       }
385     }
386   }
387
388   /**
389    * Helper for ConnectConstraint. Creates a connected constraint-function.
390    * Also populates the property-owner container, for each input connected to the constraint-function.
391    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
392    * @return A connected constraint-function, or nullptr if the scene-graph properties are not available.
393    */
394   PropertyConstraint<float>* ConnectConstraintFunction(SceneGraph::PropertyOwnerContainer& propertyOwners)
395   {
396     PropertyConstraint<float>* func = mUserFunction->Clone();
397
398     for(auto&& source : mSources)
399     {
400       int32_t            componentIndex = Property::INVALID_COMPONENT_INDEX;
401       PropertyInputImpl* inputProperty  = AddInputProperty(source, propertyOwners, componentIndex);
402
403       if(nullptr == inputProperty)
404       {
405         delete func;
406         func = nullptr;
407
408         // Exit if a scene-graph object is not available from one of the sources
409         break;
410       }
411
412       func->AddInput(inputProperty, componentIndex);
413     }
414
415     return func;
416   }
417
418 protected:
419   ConstraintFunctionPtr mUserFunction;
420 };
421
422 } // namespace Internal
423
424 } // namespace Dali
425
426 #endif // DALI_INTERNAL_ACTIVE_CONSTRAINT_H