+ /**
+ * @brief Template for the Function that is called by the Constraint system.
+ *
+ * Supports:
+ * - C style functions
+ * - Static member methods of an object
+ * - Member functions of a particular class
+ * - Functors of a particular class
+ * - If a functor or method is provided, then a copy of the object is made.
+ *
+ * The expected signature of the callback should be:
+ * @code
+ * void Function( P&, const PropertyInputContainer& );
+ * @endcode
+ *
+ * The P& parameter is an in,out parameter which stores the current value of the property. The callback
+ * should change this value to the desired one. The PropertyInputContainer is a const reference to the property inputs
+ * added to the Constraint in the order they were added via AddSource().
+ *
+ * @SINCE_1_0.0
+ * @tparam P The property type to constrain
+ */
+ template< typename P >
+ class DALI_INTERNAL Function : public CallbackBase
+ {
+ public:
+
+ /**
+ * @brief Constructor which connects to the provided C function (or a static member function).
+ *
+ * The expected signature of the function is:
+ * @code
+ * void MyFunction( P&, const PropertyInputContainer& );
+ * @endcode
+ *
+ * @SINCE_1_0.0
+ * @param[in] function The function to call
+ */
+ Function( void( *function )( P&, const PropertyInputContainer& ) )
+ : CallbackBase( reinterpret_cast< CallbackBase::Function >( function ) ),
+ mCopyConstructorDispatcher( NULL )
+ {
+ }
+
+ /**
+ * @brief Constructor which copies a function object and connects to the functor of that object.
+ *
+ * The function object should have a functor with the following signature:
+ * @code
+ * void operator()( P&, const PropertyInputContainer& );
+ * @endcode
+ *
+ * @SINCE_1_0.0
+ * @param[in] object The object to copy
+ * @tparam T The type of the object
+ */
+ template< class T >
+ Function( const T& object )
+ : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
+ NULL, // uses operator() instead of member function
+ reinterpret_cast< CallbackBase::Dispatcher >( &FunctorDispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
+ reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
+ mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
+ {
+ }
+
+ /**
+ * @brief Constructor which copies a function object and allows a connection to a member method.
+ *
+ * The object should have a method with the signature:
+ * @code
+ * void MyObject::MyMethod( P&, const PropertyInputContainer& );
+ * @endcode
+ *
+ * @SINCE_1_0.0
+ * @param[in] object The object to copy
+ * @param[in] memberFunction The member function to call. This has to be a member of the same class
+ * @tparam T The type of the object
+ */
+ template< class T >
+ Function( const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
+ : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
+ reinterpret_cast< CallbackBase::MemberFunction >( memberFunction ),
+ reinterpret_cast< CallbackBase::Dispatcher >( &Dispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
+ reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
+ mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
+ {
+ }
+
+ /**
+ * @brief Clones the Function object.
+ *
+ * The object, if held by this object, is also copied.
+ *
+ * @SINCE_1_0.0
+ * @return A pointer to a newly-allocated Function
+ */
+ CallbackBase* Clone()
+ {
+ CallbackBase* callback = NULL;
+ if ( mImpl && mImpl->mObjectPointer && mCopyConstructorDispatcher )
+ {
+ callback = new Function( mCopyConstructorDispatcher( reinterpret_cast< UndefinedClass* >( mImpl->mObjectPointer ) ) /* Copy the object */,
+ mMemberFunction,
+ mImpl->mMemberFunctionDispatcher,
+ mImpl->mDestructorDispatcher,
+ mCopyConstructorDispatcher );
+ }
+ else
+ {
+ callback = new Function( mFunction );
+ }
+ return callback;
+ }
+
+ private:
+
+ /**
+ * @brief Must not be declared.
+ *
+ * This is used so that no optimisations are done by the compiler when using void*.
+ */
+ class UndefinedClass;
+
+ /**
+ * @brief Used to call the function to copy the stored object.
+ * @SINCE_1_0.0
+ */
+ typedef UndefinedClass* (*CopyConstructorDispatcher) ( UndefinedClass* object );
+
+ /**
+ * @brief Copies the actual object in Constraint::Function.
+ *
+ * @SINCE_1_0.0
+ * @tparam T The type of the object
+ */
+ template< class T >
+ struct ObjectCopyConstructorDispatcher
+ {
+ /**
+ * @brief Copies the object stored in Constraint::Function.
+ *
+ * @SINCE_1_0.0
+ * @param[in] object The object to copy
+ * @return Newly allocated clone of the object
+ */
+ static UndefinedClass* Copy( const UndefinedClass* object )
+ {
+ T* copy = new T( *( reinterpret_cast< const T* >( object ) ) );
+ return reinterpret_cast< UndefinedClass* >( copy );
+ }
+ };
+
+ /**
+ * @brief Undefined copy constructor.
+ * @SINCE_1_0.0
+ */
+ Function( const Function& );
+
+ /**
+ * @brief Undefined assignment operator.
+ * @SINCE_1_0.0
+ */
+ Function& operator=( const Function& );
+
+ /**
+ * @brief Constructor used when copying the stored object.
+ *
+ * @SINCE_1_0.0
+ * @param[in] object A newly copied object
+ * @param[in] memberFunction The member function of the object
+ * @param[in] dispatcher Used to call the actual object
+ * @param[in] destructor Used to delete the owned object
+ * @param[in] copyConstructorDispatcher Used to create a copy of the owned object
+ */
+ Function( void* object,
+ CallbackBase::MemberFunction memberFunction,
+ CallbackBase::Dispatcher dispatcher,
+ CallbackBase::Destructor destructor,
+ CopyConstructorDispatcher copyConstructorDispatcher )
+ : CallbackBase( object, memberFunction, dispatcher, destructor ),
+ mCopyConstructorDispatcher( copyConstructorDispatcher )
+ {
+ }
+
+ /**
+ * @brief Constructor used when copying a simple stored function.
+ *
+ * @SINCE_1_0.0
+ * @param[in] function The function to call
+ */
+ Function( CallbackBase::Function function )
+ : CallbackBase( function ),
+ mCopyConstructorDispatcher( NULL )
+ {
+ }
+
+ // Data
+
+ CopyConstructorDispatcher mCopyConstructorDispatcher; ///< Function to call to copy the stored object
+ };