Revert "License conversion from Flora to Apache 2.0"
[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) 2014 Samsung Electronics Co., Ltd.
6 //
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // EXTERNAL INCLUDES
21 #include <boost/function.hpp>
22
23 // INTERNAL INCLUDES
24 #include <dali/public-api/animation/active-constraint.h>
25 #include <dali/public-api/animation/alpha-functions.h>
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/internal/event/animation/property-constraint-ptr.h>
28 #include <dali/internal/update/common/animatable-property.h>
29 #include <dali/internal/update/common/property-owner.h>
30 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
31 #include <dali/internal/render/common/performance-monitor.h>
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38
39 namespace SceneGraph
40 {
41
42 /**
43  * Used to constrain a property of a scene-object.
44  * The constraint function takes another scene-object property as an input.
45  */
46 template < class PropertyType, typename PropertyAccessorType >
47 class Constraint : public ConstraintBase
48 {
49 public:
50
51   typedef typename PropertyConstraintPtr< PropertyType >::Type ConstraintFunctionPtr;
52   typedef boost::function< PropertyType (const PropertyType&, const PropertyType&, float progress) > InterpolatorFunc;
53
54   /**
55    * Create a new scene-graph constraint.
56    * @param[in] targetProperty The target property.
57    * @param[in] ownerSet A set of property owners; func is connected to the properties provided by these objects.
58    * @param[in] func The function to calculate the final constrained value.
59    * @param[in] interpolator The function to interpolate between start & final value.
60    * @param[in] customWeight A custom weight property, or NULL if the constraint is using its own.
61    * @return A smart-pointer to a newly allocated constraint.
62    */
63   static ConstraintBase* New( const PropertyBase& targetProperty,
64                               PropertyOwnerSet& ownerSet,
65                               ConstraintFunctionPtr func,
66                               InterpolatorFunc interpolator,
67                               const AnimatableProperty<float>* customWeight )
68   {
69     // Scene-graph thread can edit these objects
70     PropertyBase& property = const_cast< PropertyBase& >( targetProperty );
71
72     return new Constraint< PropertyType, PropertyAccessorType >( property,
73                                                                  ownerSet,
74                                                                  func,
75                                                                  interpolator,
76                                                                  customWeight );
77   }
78
79   /**
80    * Virtual destructor.
81    */
82   virtual ~Constraint()
83   {
84   }
85
86   /**
87    * Query whether the constraint needs to be applied. If a constraint depends on a set of properties,
88    * then it should be applied when any of those properties have changed.
89    */
90   bool ApplyNeeded()
91   {
92     if ( mFirstApply )
93     {
94       mFirstApply = false;
95       return true;
96     }
97
98     if ( ! mTargetProperty.IsClean() ||
99            mFunc->InputsChanged()    ||
100          ! mWeightInput->IsClean() )
101     {
102       return true;
103     }
104
105     // We don't need to reapply constraint if none of the properties changed
106     return false;
107   }
108
109   /**
110    * @copydoc Dali::Internal::SceneGraph::ConstraintBase::Apply()
111    */
112   virtual void Apply( BufferIndex updateBufferIndex )
113   {
114     if ( mDisconnected )
115     {
116       return; // Early-out when property owners have been disconnected
117     }
118
119     if ( mFunc->InputsInitialized() &&
120          ApplyNeeded() )
121     {
122       const PropertyType& current = mTargetProperty.Get( updateBufferIndex );
123
124       // FINAL_WEIGHT means the constraint is fully-applied, unless weight is still being animated
125       if ( ! mWeightInput->IsClean() ||
126            ! Equals( Dali::ActiveConstraint::FINAL_WEIGHT, (*mWeightInput)[updateBufferIndex] ) )
127       {
128         // Constraint is not fully-applied; interpolation between start & final values
129         mTargetProperty.Set( updateBufferIndex,
130                              mInterpolator( current, mFunc->Apply( updateBufferIndex, current ), (*mWeightInput)[updateBufferIndex] ) );
131       }
132       else
133       {
134         // Constraint is fully-applied; optionally bake the final value
135         if ( Dali::Constraint::Bake == mRemoveAction )
136         {
137           mTargetProperty.Bake( updateBufferIndex, mFunc->Apply( updateBufferIndex, current ) );
138         }
139         else
140         {
141           mTargetProperty.Set( updateBufferIndex, mFunc->Apply( updateBufferIndex, current ) );
142         }
143       }
144
145       INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_APPLIED);
146     }
147     else
148     {
149       INCREASE_COUNTER(PerformanceMonitor::CONSTRAINTS_SKIPPED);
150     }
151   }
152
153 private:
154
155   /**
156    * @copydoc Dali::Internal::SceneGraph::Constraint::New()
157    */
158   Constraint( PropertyBase& targetProperty,
159               PropertyOwnerSet& ownerSet,
160               ConstraintFunctionPtr func,
161               InterpolatorFunc interpolator,
162               const AnimatableProperty<float>* customWeight )
163   : ConstraintBase( ownerSet ),
164     mTargetProperty( &targetProperty ),
165     mFunc( func ),
166     mInterpolator( interpolator ),
167     mWeightInput( customWeight ? customWeight : &mWeight)
168   {
169   }
170
171   // Undefined
172   Constraint( const Constraint& constraint );
173
174   // Undefined
175   Constraint& operator=( const Constraint& rhs );
176
177   /**
178    * @copydoc Dali::Internal::SceneGraph::ConstraintBase::OnDisconnect()
179    */
180   virtual void OnDisconnect()
181   {
182     // Discard target object/property pointers
183     mTargetProperty.Reset();
184     mFunc = NULL;
185   }
186
187 protected:
188
189   PropertyAccessorType mTargetProperty; ///< Raw-pointer to the target property. Not owned.
190
191   ConstraintFunctionPtr mFunc;
192
193   InterpolatorFunc mInterpolator;
194
195   const AnimatableProperty<float>* mWeightInput;
196 };
197
198 } // namespace SceneGraph
199
200 } // namespace Internal
201
202 } // namespace Dali
203
204 #endif // __DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_H__