Remove current and future memory leaks with messages by forcing the use of OwnerPoint...
[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) 2017 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/common/event-thread-services.h>
24 #include <dali/internal/event/common/object-impl.h>
25 #include <dali/internal/event/common/thread-local-storage.h>
26 #include <dali/internal/event/common/stage-impl.h>
27 #include <dali/internal/event/animation/constraint-base.h>
28 #include <dali/internal/event/animation/constraint-source-impl.h>
29 #include <dali/internal/event/animation/property-constraint-ptr.h>
30 #include <dali/internal/update/common/animatable-property.h>
31 #include <dali/internal/update/common/property-owner.h>
32 #include <dali/internal/update/common/property-owner-messages.h>
33 #include <dali/internal/update/animation/scene-graph-constraint.h>
34 #include <dali/internal/update/animation/property-accessor.h>
35 #include <dali/internal/update/animation/property-component-accessor.h>
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 /**
44  * Helper to add only unique entries to the propertyOwner container
45  * @param propertyOwners to add the entries to
46  * @param object to add
47  */
48 inline void AddUnique( SceneGraph::PropertyOwnerContainer& propertyOwners, SceneGraph::PropertyOwner* object )
49 {
50   const SceneGraph::PropertyOwnerIter iter = std::find( propertyOwners.Begin(), propertyOwners.End(), object );
51   if( iter == propertyOwners.End() )
52   {
53     // each owner should only be added once
54     propertyOwners.PushBack( object );
55   }
56 }
57
58 /**
59  * Connects a constraint which takes another property as an input.
60  */
61 template < typename PropertyType >
62 class Constraint : public ConstraintBase
63 {
64 public:
65
66   typedef SceneGraph::Constraint< PropertyType, PropertyAccessor<PropertyType> > SceneGraphConstraint;
67   typedef const SceneGraph::AnimatableProperty<PropertyType>* ScenePropertyPtr;
68   typedef typename PropertyConstraintPtr<PropertyType>::Type ConstraintFunctionPtr;
69   typedef const SceneGraph::TransformManagerPropertyHandler<PropertyType> TransformManagerProperty;
70
71   /**
72    * Construct a new constraint.
73    * @param[in] object The property-owning object.
74    * @param[in] targetIndex The index of the property to constrain.
75    * @param[in] sources The sources of the input properties passed to func.
76    * @param[in] func The constraint function.
77    * @return A newly allocated active-constraint.
78    */
79   static ConstraintBase* New( Object& object,
80                               Property::Index targetIndex,
81                               SourceContainer& sources,
82                               ConstraintFunctionPtr func )
83   {
84     return new Constraint< PropertyType >( object, targetIndex, sources, func );
85   }
86
87   /**
88    * @copydoc ConstraintBase::Clone()
89    */
90   virtual ConstraintBase* Clone( Object& object )
91   {
92     DALI_ASSERT_ALWAYS( !mSourceDestroyed && "An input source object has been destroyed" );
93
94     ConstraintBase* clone( NULL );
95
96     ConstraintFunctionPtr funcPtr( mUserFunction->Clone() );
97
98     clone = new Constraint< PropertyType >( object,
99                                             mTargetIndex,
100                                             mSources,
101                                             funcPtr );
102
103     clone->SetRemoveAction(mRemoveAction);
104     clone->SetTag( mTag );
105
106     return clone;
107   }
108
109
110   /**
111    * Virtual destructor.
112    */
113   virtual ~Constraint()
114   {
115     // This is not responsible for removing constraints.
116   }
117
118 private:
119
120   /**
121    * Private constructor; see also Constraint::New().
122    */
123   Constraint( Object& object,
124               Property::Index targetIndex,
125               SourceContainer& sources,
126               ConstraintFunctionPtr& func )
127   : ConstraintBase( object, targetIndex, sources ),
128     mTargetIndex( targetIndex ),
129     mUserFunction( func )
130   {
131   }
132
133   // Undefined
134   Constraint( const Constraint& );
135
136   // Undefined
137   Constraint& operator=( const Constraint& rhs );
138
139   /**
140    * Create and connect a constraint for a scene-object.
141    */
142   void ConnectConstraint()
143   {
144     // Should not come here if target-object has been destroyed
145     DALI_ASSERT_DEBUG( NULL != mTargetObject );
146
147     // Guard against double connections
148     DALI_ASSERT_DEBUG( NULL == mSceneGraphConstraint );
149
150     // Short-circuit until the target scene-object exists
151     SceneGraph::PropertyOwner* targetObject = const_cast< SceneGraph::PropertyOwner* >( mTargetObject->GetSceneObject() );
152     if ( NULL == targetObject )
153     {
154       return;
155     }
156
157     // Build a container of property-owners, providing the scene-graph properties
158     SceneGraph::PropertyOwnerContainer propertyOwners;
159     propertyOwners.PushBack( targetObject );
160
161     // Build the constraint function; this requires a scene-graph property from each source
162     ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
163
164     if ( func )
165     {
166       // Create the SceneGraphConstraint, and connect to the scene-graph
167
168       const SceneGraph::PropertyBase* targetProperty = mTargetObject->GetSceneObjectAnimatableProperty( mTargetIndex );
169
170       // The targetProperty should exist, when targetObject exists
171       DALI_ASSERT_ALWAYS( NULL != targetProperty && "Constraint target property does not exist" );
172
173       if( targetProperty->IsTransformManagerProperty() )  //It is a property managed by the transform manager
174       {
175         // Connect the constraint
176         mSceneGraphConstraint = SceneGraph::Constraint<PropertyType,TransformManagerPropertyAccessor<PropertyType> >::New( *targetProperty,
177                                                                                                                            propertyOwners,
178                                                                                                                            func,
179                                                                                                                            mRemoveAction );
180       }
181       else  //SceneGraph property
182       {
183         // Connect the constraint
184         mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty,
185                                                            propertyOwners,
186                                                            func,
187                                                            mRemoveAction );
188       }
189       OwnerPointer< SceneGraph::ConstraintBase > transferOwnership( const_cast< SceneGraph::ConstraintBase* >( mSceneGraphConstraint ) );
190       ApplyConstraintMessage( GetEventThreadServices(), *targetObject, transferOwnership );
191     }
192   }
193
194   /**
195    * Helper for ConnectConstraint. Creates a connected constraint-function.
196    * Also populates the property-owner container, for each input connected to the constraint-function.
197    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
198    * @return A connected constraint-function, or NULL if the scene-graph properties are not available.
199    */
200   PropertyConstraint<PropertyType>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
201   {
202     PropertyConstraint<PropertyType>* func = mUserFunction->Clone();
203
204     for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
205     {
206       Source& source = *iter;
207
208       PropertyInputImpl* inputProperty( NULL );
209       int componentIndex( Property::INVALID_COMPONENT_INDEX );
210
211       if ( OBJECT_PROPERTY == source.sourceType )
212       {
213         DALI_ASSERT_ALWAYS( source.object->IsPropertyAConstraintInput( source.propertyIndex ) );
214
215         SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( source.object->GetSceneObject() );
216
217         // The property owner will not exist, if the target object is off-stage
218         if( NULL != owner )
219         {
220           AddUnique( propertyOwners, owner );
221           inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
222           componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
223
224           // The scene-object property should exist, when the property owner exists
225           DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
226         }
227       }
228       else if ( LOCAL_PROPERTY == source.sourceType )
229       {
230         DALI_ASSERT_ALWAYS( mTargetObject->IsPropertyAConstraintInput( source.propertyIndex ) );
231
232         inputProperty = const_cast< PropertyInputImpl* >( mTargetObject->GetSceneObjectInputProperty( source.propertyIndex ) );
233         componentIndex = mTargetObject->GetPropertyComponentIndex( source.propertyIndex );
234
235         // The target scene-object should provide this property
236         DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
237       }
238       else
239       {
240         DALI_ASSERT_ALWAYS( PARENT_PROPERTY == source.sourceType && "Constraint source property type is invalid" );
241
242         Object* objectParent = dynamic_cast< Actor& >( *mTargetObject ).GetParent();
243
244         // This will not exist, if the target object is off-stage
245         if ( NULL != objectParent )
246         {
247           DALI_ASSERT_ALWAYS( objectParent->IsPropertyAConstraintInput( source.propertyIndex ) );
248
249           SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( objectParent->GetSceneObject() );
250
251           // The property owner will not exist, if the parent object is off-stage
252           if ( NULL != owner )
253           {
254             AddUnique( propertyOwners, owner );
255             inputProperty = const_cast< PropertyInputImpl* >( objectParent->GetSceneObjectInputProperty( source.propertyIndex ) );
256             componentIndex = objectParent->GetPropertyComponentIndex( source.propertyIndex );
257
258             // The scene-object property should exist, when the property owner exists
259             DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
260           }
261         }
262       }
263
264       if ( NULL == inputProperty )
265       {
266         delete func;
267         func = NULL;
268
269         // Exit if a scene-graph object is not available from one of the sources
270         break;
271       }
272
273       func->SetInput( ( iter - mSources.begin() ), componentIndex, *inputProperty );
274     }
275
276     return func;
277   }
278
279 protected:
280
281   Property::Index mTargetIndex;
282
283   ConstraintFunctionPtr mUserFunction;
284 };
285
286 /**
287  * Variant which allows float components to be animated individually.
288  */
289 template <>
290 class Constraint<float> : public ConstraintBase
291 {
292 public:
293
294   typedef typename PropertyConstraintPtr<float>::Type ConstraintFunctionPtr;
295
296   /**
297    * Construct a new constraint.
298    * @param[in] object The property-owning object.
299    * @param[in] targetIndex The index of the property to constrain.
300    * @param[in] sources The sources of the input properties passed to func.
301    * @param[in] func The constraint function.
302    * @return A newly allocated constraint.
303    */
304   static ConstraintBase* New( Object& object,
305                               Property::Index targetIndex,
306                               SourceContainer& sources,
307                               ConstraintFunctionPtr func )
308   {
309     return new Constraint< float >( object, targetIndex, sources, func );
310   }
311
312   /**
313    * @copydoc ConstraintBase::Clone()
314    */
315   virtual ConstraintBase* Clone( Object& object )
316   {
317     DALI_ASSERT_ALWAYS( !mSourceDestroyed && "An input source object has been destroyed" );
318
319     ConstraintBase* clone( NULL );
320
321     ConstraintFunctionPtr funcPtr( mUserFunction->Clone() );
322
323     clone = new Constraint< float >( object,
324                                      mTargetIndex,
325                                      mSources,
326                                      funcPtr );
327
328     clone->SetRemoveAction(mRemoveAction);
329     clone->SetTag( mTag );
330
331     return clone;
332   }
333
334   /**
335    * Virtual destructor.
336    */
337   virtual ~Constraint()
338   {
339     // This is not responsible for removing constraints.
340   }
341
342 private:
343
344   /**
345    * Private constructor; see also Constraint::New().
346    */
347   Constraint( Object& object,
348               Property::Index targetIndex,
349               SourceContainer& sources,
350               ConstraintFunctionPtr& func )
351   : ConstraintBase( object, targetIndex, sources ),
352     mTargetIndex( targetIndex ),
353     mUserFunction( func )
354   {
355   }
356
357   // Undefined
358   Constraint( const Constraint& );
359
360   // Undefined
361   Constraint& operator=( const Constraint& rhs );
362
363   /**
364    * Create and connect a constraint for a scene-object.
365    */
366   void ConnectConstraint()
367   {
368     // Should not come here if target-object has been destroyed
369     DALI_ASSERT_DEBUG( NULL != mTargetObject );
370
371     // Guard against double connections
372     DALI_ASSERT_DEBUG( NULL == mSceneGraphConstraint );
373
374     // Short-circuit until the target scene-object exists
375     SceneGraph::PropertyOwner* targetObject = const_cast< SceneGraph::PropertyOwner* >( mTargetObject->GetSceneObject() );
376     if ( NULL == targetObject )
377     {
378       return;
379     }
380
381     // Build a container of property-owners, providing the scene-graph properties
382     SceneGraph::PropertyOwnerContainer propertyOwners;
383     propertyOwners.PushBack( targetObject );
384
385     // Build the constraint function; this requires a scene-graph property from each source
386     ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
387
388     if ( func )
389     {
390       // Create the SceneGraphConstraint, and connect to the scene-graph
391
392       const SceneGraph::PropertyBase* targetProperty = mTargetObject->GetSceneObjectAnimatableProperty( mTargetIndex );
393
394       // The targetProperty should exist, when targetObject exists
395       DALI_ASSERT_ALWAYS( NULL != targetProperty && "Constraint target property does not exist" );
396
397       const int componentIndex = mTargetObject->GetPropertyComponentIndex( mTargetIndex );
398
399       if ( Property::INVALID_COMPONENT_INDEX == componentIndex )
400       {
401         // Not a Vector2, Vector3 or Vector4 component, expecting float type
402         DALI_ASSERT_DEBUG( PropertyTypes::Get< float >() == targetProperty->GetType() );
403
404         typedef SceneGraph::Constraint< float, PropertyAccessor<float> > SceneGraphConstraint;
405
406         mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
407       }
408       else
409       {
410         // Expecting Vector2, Vector3 or Vector4 type
411
412         if ( PropertyTypes::Get< Vector2 >() == targetProperty->GetType() )
413         {
414           // Constrain float component of Vector2 property
415
416           if ( 0 == componentIndex )
417           {
418             typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector2> > SceneGraphConstraint;
419             mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
420           }
421           else if ( 1 == componentIndex )
422           {
423             typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector2> > SceneGraphConstraint;
424             mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
425           }
426         }
427         else if ( PropertyTypes::Get< Vector3 >() == targetProperty->GetType() )
428         {
429           // Constrain float component of Vector3 property
430           if( targetProperty->IsTransformManagerProperty() )
431           {
432             if ( 0 == componentIndex )
433             {
434               typedef SceneGraph::Constraint< float, TransformManagerPropertyComponentAccessor<Vector3,0> > SceneGraphConstraint;
435               mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
436             }
437             else if ( 1 == componentIndex )
438             {
439               typedef SceneGraph::Constraint< float, TransformManagerPropertyComponentAccessor<Vector3,1> > SceneGraphConstraint;
440               mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
441             }
442             else if ( 2 == componentIndex )
443             {
444               typedef SceneGraph::Constraint< float, TransformManagerPropertyComponentAccessor<Vector3,2> > SceneGraphConstraint;
445               mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
446             }
447           }
448           else
449           {
450             if ( 0 == componentIndex )
451             {
452               typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector3> > SceneGraphConstraint;
453               mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
454             }
455             else if ( 1 == componentIndex )
456             {
457               typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector3> > SceneGraphConstraint;
458               mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
459             }
460             else if ( 2 == componentIndex )
461             {
462               typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector3> > SceneGraphConstraint;
463               mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
464             }
465           }
466         }
467         else if ( PropertyTypes::Get< Vector4 >() == targetProperty->GetType() )
468         {
469           // Constrain float component of Vector4 property
470
471           if ( 0 == componentIndex )
472           {
473             typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector4> > SceneGraphConstraint;
474             mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
475           }
476           else if ( 1 == componentIndex )
477           {
478             typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector4> > SceneGraphConstraint;
479             mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
480           }
481           else if ( 2 == componentIndex )
482           {
483             typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector4> > SceneGraphConstraint;
484             mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
485           }
486           else if ( 3 == componentIndex )
487           {
488             typedef SceneGraph::Constraint< float, PropertyComponentAccessorW<Vector4> > SceneGraphConstraint;
489             mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
490           }
491         }
492       }
493
494       if( mSceneGraphConstraint )
495       {
496         OwnerPointer< SceneGraph::ConstraintBase > transferOwnership( const_cast< SceneGraph::ConstraintBase* >( mSceneGraphConstraint ) );
497         ApplyConstraintMessage( GetEventThreadServices(), *targetObject, transferOwnership );
498       }
499     }
500   }
501
502   /**
503    * Helper for ConnectConstraint. Creates a connected constraint-function.
504    * Also populates the property-owner container, for each input connected to the constraint-function.
505    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
506    * @return A connected constraint-function, or NULL if the scene-graph properties are not available.
507    */
508   PropertyConstraint<float>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
509   {
510     PropertyConstraint<float>* func = mUserFunction->Clone();
511
512     for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
513     {
514       Source& source = *iter;
515
516       PropertyInputImpl* inputProperty( NULL );
517       int componentIndex( Property::INVALID_COMPONENT_INDEX );
518
519       if ( OBJECT_PROPERTY == source.sourceType )
520       {
521         DALI_ASSERT_ALWAYS( source.object->IsPropertyAConstraintInput( source.propertyIndex ) );
522
523         SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( source.object->GetSceneObject() );
524
525         // The property owner will not exist, if the target object is off-stage
526         if( NULL != owner )
527         {
528           AddUnique( propertyOwners, owner );
529           inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
530           componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
531
532           // The scene-object property should exist, when the property owner exists
533           DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
534         }
535       }
536       else if ( LOCAL_PROPERTY == source.sourceType )
537       {
538         DALI_ASSERT_ALWAYS( mTargetObject->IsPropertyAConstraintInput( source.propertyIndex ) );
539
540         inputProperty = const_cast< PropertyInputImpl* >( mTargetObject->GetSceneObjectInputProperty( source.propertyIndex ) );
541         componentIndex = mTargetObject->GetPropertyComponentIndex( source.propertyIndex );
542
543         // The target scene-object should provide this property
544         DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
545       }
546       else
547       {
548         DALI_ASSERT_ALWAYS( PARENT_PROPERTY == source.sourceType && "Constraint source property type is invalid" );
549
550         Object* objectParent = dynamic_cast< Actor& >( *mTargetObject ).GetParent();
551
552         // This will not exist, if the target object is off-stage
553         if ( NULL != objectParent )
554         {
555           DALI_ASSERT_ALWAYS( objectParent->IsPropertyAConstraintInput( source.propertyIndex ) );
556
557           SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( objectParent->GetSceneObject() );
558
559           // The property owner will not exist, if the parent object is off-stage
560           if ( NULL != owner )
561           {
562             AddUnique( propertyOwners, owner );
563             inputProperty = const_cast< PropertyInputImpl* >( objectParent->GetSceneObjectInputProperty( source.propertyIndex ) );
564             componentIndex = objectParent->GetPropertyComponentIndex( source.propertyIndex );
565
566             // The scene-object property should exist, when the property owner exists
567             DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
568           }
569         }
570       }
571
572       if ( NULL == inputProperty )
573       {
574         delete func;
575         func = NULL;
576
577         // Exit if a scene-graph object is not available from one of the sources
578         break;
579       }
580
581       func->SetInput( ( iter - mSources.begin() ), componentIndex, *inputProperty );
582     }
583
584     return func;
585   }
586
587 protected:
588
589   Property::Index mTargetIndex;
590
591   ConstraintFunctionPtr mUserFunction;
592 };
593
594 } // namespace Internal
595
596 } // namespace Dali
597
598 #endif // __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__