EventHook.hpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Wed Jan 18 14:11:40 CET 2006  EventHook.hpp
00003 
00004                         EventHook.hpp -  description
00005                            -------------------
00006     begin                : Wed January 18 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.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 EVENT_HOOK_HPP
00040 #define EVENT_HOOK_HPP
00041 
00042 
00043 #include "Event.hpp"
00044 #include "ActivityInterface.hpp"
00045 
00046 #include <boost/bind.hpp>
00047 #include <boost/type_traits.hpp>
00048 
00049 
00050 namespace RTT{
00051 
00052     namespace detail {
00053 
00061         struct RTT_API EventHookBase
00062         {
00063             virtual ~EventHookBase() {}
00064 
00065             Handle setupSyn(boost::function<void(void)> sfunc ) {
00066                 mfunc = sfunc;
00067                 return msetupSyn();
00068             }
00069 
00070             Handle setupAsyn(boost::function<void(void)> afunc, EventProcessor* t,EventProcessor::AsynStorageType s_type ) {
00071                 mfunc = afunc;
00072                 return msetupAsyn(t, s_type);
00073             }
00074 
00075         protected:
00076             boost::function<void(void)> mfunc;
00077 
00078             virtual Handle msetupSyn( ) = 0;
00079 
00080             virtual Handle msetupAsyn( EventProcessor* t,EventProcessor::AsynStorageType s_type ) = 0;
00081 
00082         };
00083 
00084         template<typename EventT>
00085         struct EventHook0 : public EventHookBase
00086         {
00087         protected:
00088             // The default copy constructor is ok for this class,
00089             // a copy is equivalent to the original.
00090             typedef typename EventT::SlotFunction::result_type Ret;
00091             typedef EventHook0<EventT> This;
00092             EventT* msource;
00093 
00094         public:
00095             EventHook0( EventT* source )
00096                 : msource(source) //, seh(this)
00097             {}
00098         protected:
00099             Handle msetupSyn( ) {
00100                 Handle h = msource->setup( boost::bind(&This::synop,boost::shared_ptr<This>(this)) );
00101                 //seh = 0;
00102                 return h;
00103             }
00104 
00105             Handle msetupAsyn( EventProcessor* t,EventProcessor::AsynStorageType s_type ) {
00106                 Handle h = msource->setup( boost::bind(&This::asynop,boost::shared_ptr<This>(this)), t, s_type );
00107                 //seh = 0;
00108                 return h;
00109             }
00110 
00111             Ret synop()
00112             {
00113                 mfunc();
00114                 return Ret();
00115             }
00116 
00117             Ret asynop()
00118             {
00119                 mfunc();
00120                 return Ret();
00121             }
00122         };
00123 
00124         template<typename EventT>
00125         struct EventHook1 : public EventHookBase
00126         {
00127         protected:
00128             // The default copy constructor is ok for this class,
00129             // a copy is equivalent to the original.
00130             typedef typename EventT::SlotFunction::arg1_type A1;
00131             typedef typename EventT::SlotFunction::result_type Ret;
00132             typedef EventHook1<EventT> This;
00133             EventT* msource;
00134             typename AssignableDataSource<A1>::shared_ptr ma1;
00135 
00136             //boost::shared_ptr<EventHookBase> seh;
00137 
00138         public:
00139             EventHook1( EventT* source, typename AssignableDataSource<A1>::shared_ptr a1 )
00140                 : msource(source), ma1(a1) //, seh(this)
00141             {
00142             }
00143         protected:
00144             Handle msetupSyn( ) {
00145                 Handle h = msource->setup( boost::bind(&This::synop,boost::shared_ptr<This>(this),_1) );
00146                 //seh = 0;
00147                 return h;
00148             }
00149 
00150             Handle msetupAsyn( EventProcessor* t,EventProcessor::AsynStorageType s_type ) {
00151                 Handle h = msource->setup( boost::bind(&This::asynop,boost::shared_ptr<This>(this),_1), t, s_type );
00152                 //seh = 0;
00153                 return h;
00154             }
00155 
00156             Ret synop(A1 arg1)
00157             {
00158                 // set the received args.
00159                 ma1->set(arg1);
00160                 mfunc();
00161                 return Ret();
00162             }
00163 
00164             Ret asynop(A1 arg1)
00165             {
00166                 // set the received args.
00167                 ma1->set(arg1);
00168                 mfunc();
00169                 return Ret();
00170             }
00171         };
00172 
00173         template<typename EventT>
00174         struct EventHook2 : public EventHookBase
00175         {
00176         protected:
00177             // The default copy constructor is ok for this class,
00178             // a copy is equivalent to the original.
00179             typedef typename EventT::SlotFunction::arg1_type A1;
00180             typedef typename EventT::SlotFunction::arg2_type A2;
00181             typedef typename EventT::SlotFunction::result_type Ret;
00182             typedef EventHook2<EventT> This;
00183             EventT* msource;
00184             typename AssignableDataSource<A1>::shared_ptr ma1;
00185             typename AssignableDataSource<A2>::shared_ptr ma2;
00186 
00187             //boost::shared_ptr<EventHookBase> seh;
00188 
00189         public:
00190             EventHook2( EventT* source,
00191                         typename AssignableDataSource<A1>::shared_ptr a1,
00192                         typename AssignableDataSource<A2>::shared_ptr a2)
00193                 : msource(source), ma1(a1), ma2(a2) //, seh(this)
00194             {
00195             }
00196         protected:
00197             Handle msetupSyn( ) {
00198                 Handle h = msource->setup( boost::bind(&This::synop,boost::shared_ptr<This>(this),_1,_2) );
00199                 return h;
00200             }
00201 
00202             Handle msetupAsyn( EventProcessor* t, EventProcessor::AsynStorageType s_type ) {
00203                 Handle h = msource->setup( boost::bind(&This::asynop,boost::shared_ptr<This>(this),_1,_2), t, s_type );
00204                 return h;
00205             }
00206 
00207             Ret synop(A1 arg1, A2 arg2)
00208             {
00209                 // set the received args.
00210                 ma1->set(arg1);
00211                 ma2->set(arg2);
00212                 mfunc();
00213                 return Ret();
00214             }
00215             Ret asynop(A1 arg1, A2 arg2)
00216             {
00217                 // set the received args.
00218                 ma1->set(arg1);
00219                 ma2->set(arg2);
00220                 mfunc();
00221                 return Ret();
00222             }
00223         };
00224 
00225         template<typename EventT>
00226         struct EventHook3 : public EventHookBase
00227         {
00228         protected:
00229             // The default copy constructor is ok for this class,
00230             // a copy is equivalent to the original.
00231             typedef typename EventT::SlotFunction::arg1_type A1;
00232             typedef typename EventT::SlotFunction::arg2_type A2;
00233             typedef typename EventT::SlotFunction::arg3_type A3;
00234             typedef typename EventT::SlotFunction::result_type Ret;
00235             typedef EventHook3<EventT> This;
00236 
00237             EventT* msource;
00238             typename AssignableDataSource<A1>::shared_ptr ma1;
00239             typename AssignableDataSource<A2>::shared_ptr ma2;
00240             typename AssignableDataSource<A3>::shared_ptr ma3;
00241 
00242             //boost::shared_ptr<EventHookBase> seh;
00243 
00244         public:
00245             EventHook3( EventT* source,
00246                         typename AssignableDataSource<A1>::shared_ptr a1,
00247                         typename AssignableDataSource<A2>::shared_ptr a2,
00248                         typename AssignableDataSource<A3>::shared_ptr a3)
00249                 : msource(source), ma1(a1), ma2(a2), ma3(a3) //, seh(this)
00250             {
00251             }
00252         protected:
00253             Handle msetupSyn( ) {
00254                 Handle h = msource->setup( boost::bind(&This::synop,boost::shared_ptr<This>(this),_1,_2,_3) );
00255                 return h;
00256             }
00257 
00258             Handle msetupAsyn( EventProcessor* t, EventProcessor::AsynStorageType s_type ) {
00259                 Handle h = msource->setup( boost::bind(&This::asynop,boost::shared_ptr<This>(this),_1,_2,_3), t, s_type );
00260                 return h;
00261             }
00262 
00263             Ret synop(A1 arg1, A2 arg2, A3 arg3)
00264             {
00265                 // set the received args.
00266                 ma1->set(arg1);
00267                 ma2->set(arg2);
00268                 ma3->set(arg3);
00269                 mfunc();
00270                 return Ret();
00271             }
00272             Ret asynop(A1 arg1, A2 arg2, A3 arg3)
00273             {
00274                 // set the received args.
00275                 ma1->set(arg1);
00276                 ma2->set(arg2);
00277                 ma3->set(arg3);
00278                 mfunc();
00279                 return Ret();
00280             }
00281         };
00282 
00286         template<class EventT>
00287         class EventHookGenerator
00288         {
00289             EventT* e;
00290 
00291         public:
00292             typedef boost::function_traits<typename EventT::Signature> traits;
00293 
00294             EventHookGenerator(EventT* event)
00295                 : e(event) {}
00296 
00297             typedef EventHookBase* result_type;
00298 
00299             EventHookBase* create() const {
00300                 return new EventHook0<EventT>(e); // called by TemplateFactoryPart0
00301             }
00302 
00303             template<class Arg1T>
00304             EventHookBase* create( DataSource<Arg1T>* arg1 ) const
00305             {
00306                 // check if we can make an AssignableDS from arg1...
00307                 typename AssignableDataSource<Arg1T>::shared_ptr ma1 = AdaptAssignableDataSource<Arg1T>()( arg1 );
00308                 if ( !ma1 )
00309                     throw non_lvalue_args_exception( 1, arg1->getType() );
00310 
00311                 // ok, deliver part to 'user'.
00312                 return new EventHook1<EventT>(e, ma1); // called by TemplateFactoryPart1
00313             }
00314 
00315             template<class Arg1T, class Arg2T>
00316             EventHookBase* create( DataSource<Arg1T>* arg1,
00317                                    DataSource<Arg2T>* arg2) const
00318             {
00319                 // check if we can make an AssignableDS from arg1...
00320                 typename AssignableDataSource<Arg1T>::shared_ptr ma1 = AdaptAssignableDataSource<Arg1T>()( arg1 );
00321                 if ( !ma1 )
00322                     throw non_lvalue_args_exception( 1, arg1->getType() );
00323                 typename AssignableDataSource<Arg2T>::shared_ptr ma2 = AdaptAssignableDataSource<Arg2T>()( arg2 );
00324                 if ( !ma2 )
00325                     throw non_lvalue_args_exception( 2, arg2->getType() );
00326 
00327                 // ok, deliver part to 'user'.
00328                 return new EventHook2<EventT>(e, ma1, ma2); // called by TemplateFactoryPart2
00329             }
00330 
00331             template<class Arg1T, class Arg2T, class Arg3T>
00332             EventHookBase* create( DataSource<Arg1T>* arg1,
00333                                    DataSource<Arg2T>* arg2,
00334                                    DataSource<Arg3T>* arg3) const
00335             {
00336                 // check if we can make an AssignableDS from arg1...
00337                 typename AssignableDataSource<Arg1T>::shared_ptr ma1 = AdaptAssignableDataSource<Arg1T>()( arg1 );
00338                 if ( !ma1 )
00339                     throw non_lvalue_args_exception( 1, arg1->getType() );
00340                 typename AssignableDataSource<Arg2T>::shared_ptr ma2 = AdaptAssignableDataSource<Arg2T>()( arg2 );
00341                 if ( !ma2 )
00342                     throw non_lvalue_args_exception( 2, arg2->getType() );
00343                 typename AssignableDataSource<Arg3T>::shared_ptr ma3 = AdaptAssignableDataSource<Arg3T>()( arg3 );
00344                 if ( !ma3 )
00345                     throw non_lvalue_args_exception( 3, arg3->getType() );
00346 
00347                 // ok, deliver part to 'user'.
00348                 return new EventHook3<EventT>(e, ma1, ma2,ma3); // called by TemplateFactoryPart3
00349             }
00350         };
00351 
00352     }
00353 }
00354 #endif
Generated on Thu Dec 23 13:22:37 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3