20cba76264102788ce935330bf22793c7255cfe3
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / property-constraint.h
1 #ifndef __DALI_PROPERTY_CONSTRAINT_H__
2 #define __DALI_PROPERTY_CONSTRAINT_H__
3
4 /*
5  * Copyright (c) 2014 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/public-api/animation/constraint.h>
23 #include <dali/public-api/common/dali-vector.h>
24 #include <dali/public-api/common/vector-wrapper.h>
25 #include <dali/internal/event/animation/property-input-accessor.h>
26 #include <dali/internal/event/animation/property-input-indexer.h>
27 #include <dali/internal/event/common/property-input-impl.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 /**
36  * A class for connecting properties to a constraint function.
37  */
38 template < typename PropertyType >
39 class PropertyConstraint
40 {
41 public:
42
43   typedef std::vector < PropertyInputAccessor > InputContainer;
44   typedef typename InputContainer::iterator InputContainerIter;
45   typedef typename InputContainer::const_iterator InputContainerConstIter;
46
47   typedef std::vector< PropertyInputIndexer< PropertyInputAccessor > > InputIndexerContainer;
48
49   typedef Dali::Constraint::Function< PropertyType > ConstraintFunction;
50
51   /**
52    * Create a property constraint.
53    *
54    * @param[in]  func  A constraint function. Ownership of this callback-function is passed to this object.
55    */
56   PropertyConstraint( Dali::Constraint::Function< PropertyType >* func )
57   : mInputsInitialized( false ),
58     mFunction( func ),
59     mInputs()
60   {
61   }
62
63   /**
64    * Constructor.
65    * @param [in]  func    A constraint function. Ownership of this callback-function is passed to this object.
66    * @param [in]  inputs  Property inputs.
67    */
68   PropertyConstraint( Dali::Constraint::Function< PropertyType >* func,
69                       const InputContainer& inputs )
70   : mInputsInitialized( false ),
71     mFunction( func ),
72     mInputs( inputs )
73   {
74   }
75
76   /**
77    * Non virtual destructor.
78    */
79   ~PropertyConstraint()
80   {
81     delete mFunction;
82   }
83
84   /**
85    * Clone a property constraint.
86    *
87    * @return The clone of the property-constraint.
88    *
89    * @note This function will create a copy of the stored constraint function for the clone.
90    */
91   PropertyConstraint< PropertyType >* Clone()
92   {
93     return new PropertyConstraint< PropertyType >( reinterpret_cast< ConstraintFunction* >( mFunction->Clone() ), mInputs );
94   }
95
96   /**
97    * Set the input for one of the property constraint parameters.
98    * @param [in] index The parameter index.
99    * @param [in] input The interface for receiving a property value.
100    */
101   void SetInput( std::size_t index, int componentIndex, const PropertyInputImpl& input )
102   {
103     if ( index >= mInputs.size() )
104     {
105       mInputs.push_back( PropertyInputAccessor() );
106     }
107
108     mInputs[ index ].SetInput( input, componentIndex );
109   }
110
111   /**
112    * Retrieve the input for one of the property constraint parameters.
113    * @param [in] index The parameter index.
114    * @return The property input, or NULL if no input exists with this index.
115    */
116   const PropertyInputImpl* GetInput( unsigned int index ) const
117   {
118     if ( index < mInputs.size() )
119     {
120       return mInputs[ index ].GetInput();
121     }
122
123     return NULL;
124   }
125
126   /**
127    * Query whether all of the inputs have been initialized.
128    * @return True if all of the inputs have been initialized.
129    */
130   bool InputsInitialized()
131   {
132     if ( !mInputsInitialized )
133     {
134       // Check whether the inputs are initialized yet
135       unsigned int index( 0u );
136       for ( const PropertyInputImpl* input = GetInput( index );
137             NULL != input;
138             input = GetInput( ++index ) )
139       {
140         if ( !input->InputInitialized() )
141         {
142           return false;
143         }
144       }
145
146       // All inputs are now initialized
147       mInputsInitialized = true;
148     }
149
150     return true;
151   }
152
153   /**
154    * Query whether any of the inputs have changed
155    * @return True if any of the inputs have changed.
156    */
157   bool InputsChanged()
158   {
159     unsigned int index( 0u );
160     for ( const PropertyInputImpl* input = GetInput( index );
161           NULL != input;
162           input = GetInput( ++index ) )
163     {
164       if ( input->InputChanged() )
165       {
166         // At least one of the inputs has changed
167         return true;
168       }
169     }
170
171     return false;
172   }
173
174   /**
175    * Apply the constraint.
176    * @param [in] bufferIndex The current update buffer index.
177    * @param [in,out] current The current property value, will be set to the constrained value upon return.
178    */
179   void Apply( BufferIndex bufferIndex, PropertyType& current )
180   {
181     InputIndexerContainer mInputIndices;
182     PropertyInputContainer mIndices;
183     const std::size_t noOfInputs = mInputs.size();
184
185     mInputIndices.reserve( noOfInputs );
186     mIndices.Reserve( noOfInputs );
187
188     const InputContainerConstIter endIter = mInputs.end();
189     unsigned int index = 0;
190     for ( InputContainerConstIter iter = mInputs.begin(); iter != endIter; ++iter, ++index )
191     {
192       DALI_ASSERT_DEBUG( NULL != iter->GetInput() );
193       mInputIndices.push_back( PropertyInputIndexer< PropertyInputAccessor >( bufferIndex, &*iter ) );
194       mIndices.PushBack( &mInputIndices[ index ] );
195     }
196
197     CallbackBase::Execute< PropertyType&, const PropertyInputContainer& >( *mFunction, current, mIndices );
198   }
199
200 private:
201
202   // Undefined
203   PropertyConstraint( const PropertyConstraint& );
204
205   // Undefined
206   PropertyConstraint& operator=( const PropertyConstraint& rhs );
207
208 private:
209
210   bool mInputsInitialized;
211
212   ConstraintFunction* mFunction;
213
214   InputContainer mInputs;
215 };
216
217 } // namespace Internal
218
219 } // namespace Dali
220
221 #endif // __DALI_PROPERTY_CONSTRAINT_H__