EventCallBack.hpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Fri Feb 24 17:02:57 CET 2006  EventCallBack.hpp
00003 
00004                         EventCallBack.hpp -  description
00005                            -------------------
00006     begin                : Fri February 24 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@fmtc.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 
00039 #ifndef ORO_EXEC_EVENT_CALLBACK_HPP
00040 #define ORO_EXEC_EVENT_CALLBACK_HPP
00041 
00042 #include <vector>
00043 #include <boost/bind.hpp>
00044 #include <boost/type_traits.hpp>
00045 #include <boost/function.hpp>
00046 #include "boost/function_types/function_type_arity.hpp"
00047 #include "boost/function_types/function_type_parameter.hpp"
00048 #include "DataSource.hpp"
00049 #include "DataSources.hpp"
00050 
00051 namespace RTT {
00052     namespace detail {
00053 
00060         struct RTT_API EventCallBack
00061         {
00062             virtual ~EventCallBack() {}
00063             virtual void callback() = 0;
00064             virtual std::vector<DataSourceBase::shared_ptr> args() = 0;
00065         };
00066 
00067         template<class Function, int arity>
00068         struct CallBackWrapperFunction;
00069 
00070         // If we could detect the arity _and_ type type of each argument
00071         // of a boost::bind object, this implementation would suffice.
00072         // See the commented out code in ConnectionC.hpp
00073         template<class Function>
00074         struct CallBackWrapperFunction<Function,0>
00075             :public EventCallBack
00076         {
00077             CallBackWrapperFunction( Function& foo ) : mfoo(foo) {}
00078             Function mfoo;
00079 
00080             virtual void callback()
00081                 {
00082                     mfoo();
00083                 }
00084 
00085             virtual std::vector<DataSourceBase::shared_ptr> args() {
00086                 return std::vector<DataSourceBase::shared_ptr>();
00087             }
00088         };
00089 
00090         template<class Function>
00091         struct CallBackWrapperFunction<Function,1>
00092             :public EventCallBack
00093         {
00094             typedef typename boost::function_types::function_type_parameter_c<Function,0>::type T;
00095             CallBackWrapperFunction( Function& foo )
00096                 : mfoo(foo), marg( new ValueDataSource<T>() ) {}
00097             Function mfoo;
00098             typename AssignableDataSource<T>::shared_ptr marg;
00099 
00100             virtual void callback()
00101                 {
00102                     mfoo( marg->set() );
00103                 }
00104 
00105             virtual std::vector<DataSourceBase::shared_ptr> args() {
00106                 std::vector<DataSourceBase::shared_ptr> a;
00107                 a.push_back( marg );
00108                 return a;
00109             }
00110         };
00111 
00112         template<class Function>
00113         struct CallBackWrapperFunction<Function,2>
00114             :public EventCallBack
00115         {
00116             typedef typename boost::function_types::function_type_parameter_c<Function,0>::type T1;
00117             typedef typename boost::function_types::function_type_parameter_c<Function,1>::type T2;
00118             CallBackWrapperFunction( Function& foo)
00119                 : mfoo(foo),
00120                 marg1( new ValueDataSource<T1>() ),
00121                 marg2( new ValueDataSource<T2>() ) {}
00122 
00123             Function mfoo;
00124             typename AssignableDataSource<T1>::shared_ptr marg1;
00125             typename AssignableDataSource<T2>::shared_ptr marg2;
00126 
00127             virtual void callback()
00128                 {
00129                     mfoo( marg1->set(), marg2->set() );
00130                 }
00131 
00132             virtual std::vector<DataSourceBase::shared_ptr> args() {
00133                 std::vector<DataSourceBase::shared_ptr> a;
00134                 a.push_back( marg1 );
00135                 a.push_back( marg2 );
00136                 return a;
00137             }
00138         };
00139 
00140         template<class Function>
00141         struct CallBackWrapperFunction<Function, 3>
00142             :public EventCallBack
00143         {
00144             typedef typename boost::function_types::function_type_parameter_c<Function,0>::type T1;
00145             typedef typename boost::function_types::function_type_parameter_c<Function,1>::type T2;
00146             typedef typename boost::function_types::function_type_parameter_c<Function,2>::type T3;
00147             CallBackWrapperFunction( Function foo)
00148                 : mfoo(foo),
00149                 marg1( new ValueDataSource<T1>() ),
00150                 marg2( new ValueDataSource<T2>() ),
00151                 marg3( new ValueDataSource<T3>() ) {}
00152             Function mfoo;
00153             typename AssignableDataSource<T1>::shared_ptr marg1;
00154             typename AssignableDataSource<T2>::shared_ptr marg2;
00155             typename AssignableDataSource<T3>::shared_ptr marg3;
00156 
00157             virtual void callback()
00158                 {
00159                     mfoo( marg1->set(), marg2->set(), marg3->set() );
00160                 }
00161 
00162             virtual std::vector<DataSourceBase::shared_ptr> args() {
00163                 std::vector<DataSourceBase::shared_ptr> a;
00164                 a.push_back( marg1 );
00165                 a.push_back( marg2 );
00166                 a.push_back( marg3 );
00167                 return a;
00168             }
00169         };
00170 
00171         template<class Function, int arity>
00172         struct CallBackWrapper;
00173 
00174         // No bind arity detection work around
00175         template<class Function>
00176         struct CallBackWrapper<Function,0>
00177             :public EventCallBack
00178         {
00179             template<class Type>
00180             CallBackWrapper( Type t, Function& foo )
00181                 : mfoo( boost::bind(foo, t) ) {}
00182             boost::function<void(void)> mfoo;
00183 
00184             virtual void callback()
00185                 {
00186                     mfoo();
00187                 }
00188 
00189             virtual std::vector<DataSourceBase::shared_ptr> args() {
00190                 return std::vector<DataSourceBase::shared_ptr>();
00191             }
00192         };
00193 
00194         template<class Function>
00195         struct CallBackWrapper<Function,1>
00196             :public EventCallBack
00197         {
00198             typedef typename boost::function_types::function_type_parameter_c<Function,0>::type T;
00199 
00200             template<class Type>
00201             CallBackWrapper( Type t, Function& foo )
00202                 : mfoo( boost::bind(foo, t, _1) ), marg( new ValueDataSource<T>() )
00203             {}
00204             boost::function<void(T)> mfoo;
00205 
00206             typename AssignableDataSource<T>::shared_ptr marg;
00207 
00208             virtual void callback()
00209                 {
00210                     mfoo( marg->set() );
00211                 }
00212 
00213             virtual std::vector<DataSourceBase::shared_ptr> args() {
00214                 std::vector<DataSourceBase::shared_ptr> a;
00215                 a.push_back( marg );
00216                 return a;
00217             }
00218         };
00219 
00220         template<class Function>
00221         struct CallBackWrapper<Function,2>
00222             :public EventCallBack
00223         {
00224             typedef typename boost::function_types::function_type_parameter_c<Function,0>::type T1;
00225             typedef typename boost::function_types::function_type_parameter_c<Function,1>::type T2;
00226 
00227             boost::function<void(T1,T2)> mfoo;
00228             template<class Type>
00229             CallBackWrapper( Type t, Function& foo )
00230                 : mfoo( boost::bind(foo, t, _1, _2) ),
00231                 marg1( new ValueDataSource<T1>() ),
00232                 marg2( new ValueDataSource<T2>() ) {}
00233 
00234             typename AssignableDataSource<T1>::shared_ptr marg1;
00235             typename AssignableDataSource<T2>::shared_ptr marg2;
00236 
00237             virtual void callback()
00238                 {
00239                     mfoo( marg1->set(), marg2->set() );
00240                 }
00241 
00242             virtual std::vector<DataSourceBase::shared_ptr> args() {
00243                 std::vector<DataSourceBase::shared_ptr> a;
00244                 a.push_back( marg1 );
00245                 a.push_back( marg2 );
00246                 return a;
00247             }
00248         };
00249 
00250         template<class Function>
00251         struct CallBackWrapper<Function, 3>
00252             :public EventCallBack
00253         {
00254             typedef typename boost::function_types::function_type_parameter_c<Function,0>::type T1;
00255             typedef typename boost::function_types::function_type_parameter_c<Function,1>::type T2;
00256             typedef typename boost::function_types::function_type_parameter_c<Function,2>::type T3;
00257 
00258             boost::function<void(T1,T2,T3)> mfoo;
00259             template<class Type>
00260             CallBackWrapper( Type t, Function& foo )
00261                 : mfoo( boost::bind(foo, t, _1, _2, _3) ),
00262                 marg1( new ValueDataSource<T1>() ),
00263                 marg2( new ValueDataSource<T2>() ),
00264                 marg3( new ValueDataSource<T3>() ) {}
00265 
00266             typename AssignableDataSource<T1>::shared_ptr marg1;
00267             typename AssignableDataSource<T2>::shared_ptr marg2;
00268             typename AssignableDataSource<T3>::shared_ptr marg3;
00269 
00270             virtual void callback()
00271                 {
00272                     mfoo( marg1->set(), marg2->set(), marg3->set() );
00273                 }
00274 
00275             virtual std::vector<DataSourceBase::shared_ptr> args() {
00276                 std::vector<DataSourceBase::shared_ptr> a;
00277                 a.push_back( marg1 );
00278                 a.push_back( marg2 );
00279                 a.push_back( marg3 );
00280                 return a;
00281             }
00282         };
00283     }
00284 }
00285 #endif
Generated on Thu Dec 23 13:22:37 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3