GNU Radio 3.7.1 C++ API
rpcregisterhelpers.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /* 
00003  * Copyright 2012 Free Software Foundation, Inc.
00004  *
00005  * This file is part of GNU Radio
00006  * 
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  *
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #ifndef RPCREGISTERHELPERS_H
00024 #define RPCREGISTERHELPERS_H
00025 
00026 #include <stdio.h>
00027 #include <sstream>
00028 #include <iostream>
00029 #include <gnuradio/rpcserver_booter_base.h>
00030 #include <gnuradio/rpcmanager.h>
00031 #include <gnuradio/rpcserver_selector.h>
00032 #include <gnuradio/rpcserver_base.h>
00033 #include <gnuradio/block_registry.h>
00034 
00035 // Base classes
00036 template<typename T, typename Tto> class rpcextractor_base
00037   : public virtual gr::messages::msg_accepter
00038 {
00039 public:
00040   rpcextractor_base(T* source, void (T::*func)(Tto)) :
00041     _source(source), _func(func) {;}
00042   ~rpcextractor_base() {;}
00043 
00044   void post(pmt::pmt_t which_port, pmt::pmt_t msg) {
00045     throw std::runtime_error("rpcextractor_base: no post defined for this data type.\n");
00046   }
00047 
00048 protected:
00049   T* _source;
00050   void (T::*_func)(Tto);
00051 };
00052 
00053 template<typename T, typename Tto>
00054 class rpcbasic_extractor : public virtual rpcextractor_base<T,Tto>
00055 {
00056 public:
00057   rpcbasic_extractor(T* source, void (T::*func)(Tto)) :
00058     rpcextractor_base<T,Tto>(source, func) 
00059   {;}
00060 };
00061 
00062 template<typename T, typename Tfrom>
00063 class rpcinserter_base : public virtual gr::messages::msg_producer
00064 {
00065 public:
00066   rpcinserter_base(T* source, Tfrom (T::*func)()) : _source(source), _func(func) {;}
00067   rpcinserter_base() {;}
00068 
00069   pmt::pmt_t retrieve() { assert(0); return pmt::pmt_t(); }
00070 
00071 protected:
00072   T* _source;
00073   Tfrom (T::*_func)();
00074 };
00075 
00076 template<typename T, typename Tfrom>
00077 class rpcbasic_inserter :
00078   public virtual rpcinserter_base<T,Tfrom>
00079 {
00080 public:
00081   rpcbasic_inserter(T* source, Tfrom (T::*func)()const)
00082     : rpcinserter_base<T,Tfrom>(source, func)
00083   {;}
00084 
00085   rpcbasic_inserter(T* source, Tfrom (T::*func)())
00086     : rpcinserter_base<T,Tfrom>(source, func)
00087   {;}
00088 
00089   pmt::pmt_t retrieve() 
00090   {
00091     return pmt::mp((rpcinserter_base<T,Tfrom>::
00092                     _source->*rpcinserter_base<T,Tfrom>::_func)());
00093   }
00094 };
00095 
00096 // Specialized Extractor Templates
00097 template<typename T>
00098 class rpcbasic_extractor<T,char> : public virtual rpcextractor_base<T,char>
00099 {
00100 public:
00101   rpcbasic_extractor(T* source, void (T::*func)(char))
00102     : rpcextractor_base<T,char>(source, func)
00103   {;}
00104 
00105   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00106   {
00107     (rpcextractor_base<T,char>::_source->*rpcextractor_base<T,char>::_func)
00108       (static_cast<char>(pmt::to_long(msg)));
00109   }
00110 };
00111 
00112 template<typename T>
00113 class rpcbasic_extractor<T,short> : public virtual rpcextractor_base<T,short>
00114 {
00115 public:
00116   rpcbasic_extractor(T* source, void (T::*func)(short))
00117     : rpcextractor_base<T,short>(source, func)
00118   {;}
00119 
00120   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00121   {
00122     (rpcextractor_base<T,short>::_source->*rpcextractor_base<T,char>::_func)
00123       (static_cast<short>(pmt::to_long(msg)));
00124   }
00125 };
00126 
00127 template<typename T>
00128 class rpcbasic_extractor<T,double> : public virtual rpcextractor_base<T,double>
00129 {
00130 public:
00131   rpcbasic_extractor(T* source, void (T::*func)(double))
00132     : rpcextractor_base<T,double>(source, func)
00133   {;}
00134 
00135   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00136   {
00137     (rpcextractor_base<T,double>::_source->*rpcextractor_base<T,double>::_func)
00138       (pmt::to_double(msg));
00139   }
00140 };
00141 
00142 template<typename T>
00143 class rpcbasic_extractor<T,float> : public virtual rpcextractor_base<T,float>
00144 {
00145 public:
00146   rpcbasic_extractor(T* source, void (T::*func)(float))
00147     : rpcextractor_base<T,float>(source, func)
00148   {;}
00149 
00150   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00151   {
00152     (rpcextractor_base<T,float>::_source->*rpcextractor_base<T,float>::_func)
00153       (pmt::to_double(msg));
00154   }
00155 };
00156 
00157 template<typename T>
00158 class rpcbasic_extractor<T,long> : public virtual rpcextractor_base<T,long>
00159 {
00160 public:
00161   rpcbasic_extractor(T* source, void (T::*func)(long))
00162     : rpcextractor_base<T,long>(source, func)
00163   {;}
00164 
00165   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00166   {
00167     (rpcextractor_base<T,long>::_source->*rpcextractor_base<T,long>::_func)
00168       (pmt::to_long(msg));
00169   }
00170 };
00171 
00172 template<typename T>
00173 class rpcbasic_extractor<T,int> : public virtual rpcextractor_base<T,int>
00174 {
00175 public:
00176   rpcbasic_extractor(T* source, void (T::*func)(int))
00177     : rpcextractor_base<T,int>(source, func)
00178   {;}
00179 
00180   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00181   {
00182     (rpcextractor_base<T,int>::_source->*rpcextractor_base<T,int>::_func)
00183       (pmt::to_long(msg));
00184   }
00185 };
00186 
00187 template<typename T>
00188 class rpcbasic_extractor<T,bool> : public virtual rpcextractor_base<T,bool>
00189 {
00190 public:
00191   rpcbasic_extractor(T* source, void (T::*func)(bool))
00192     : rpcextractor_base<T,bool>(source, func)
00193   {;}
00194 
00195   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00196   {
00197     (rpcextractor_base<T,bool>::_source->*rpcextractor_base<T,bool>::_func)
00198       (pmt::to_bool(msg));
00199   }
00200 };
00201 
00202 template<typename T>
00203 class rpcbasic_extractor<T,std::complex<float> >
00204   : public virtual rpcextractor_base<T,std::complex<float> >
00205 {
00206 public:
00207   rpcbasic_extractor(T* source, void (T::*func)(std::complex<float>))
00208     : rpcextractor_base<T,std::complex<float> >(source, func)
00209   {;}
00210 
00211   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00212   {
00213     std::complex<float> k = static_cast<std::complex<float> >(pmt::to_complex(msg));
00214     (rpcextractor_base<T,std::complex<float> >::
00215      _source->*rpcextractor_base<T,std::complex<float> >::_func)(k);
00216   }
00217 };
00218 
00219 template<typename T>
00220 class rpcbasic_extractor<T,std::complex<double> >
00221   : public virtual rpcextractor_base<T,std::complex<double> >
00222 {
00223 public:
00224   rpcbasic_extractor(T* source, void (T::*func)(std::complex<double>))
00225     : rpcextractor_base<T,std::complex<double> >(source, func)
00226   {;}
00227 
00228   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00229   {
00230     (rpcextractor_base<T,std::complex<double> >::
00231      _source->*rpcextractor_base<T,std::complex<double> >::_func)(pmt::to_complex(msg));
00232   }
00233 };
00234 
00235 template<typename T>
00236 class rpcbasic_extractor<T,std::string>
00237   : public virtual rpcextractor_base<T,std::string>
00238 {
00239 public:
00240   rpcbasic_extractor(T* source, void (T::*func)(std::string))
00241     : rpcextractor_base<T,std::string>(source, func)
00242   {;}
00243 
00244   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00245   {
00246     (rpcextractor_base<T,std::string>::
00247      _source->*rpcextractor_base<T,std::string>::_func)(pmt::symbol_to_string(msg)); 
00248   }
00249 };
00250 
00251 template<typename T>
00252 class rpcbasic_inserter<T,uint64_t> : public virtual rpcinserter_base<T,uint64_t>
00253 {
00254 public:
00255   rpcbasic_inserter(T* source, uint64_t (T::*func)() const)
00256     : rpcinserter_base<T,uint64_t>(source, func)
00257   {;}
00258 
00259   rpcbasic_inserter(T* source, uint64_t (T::*func)())
00260     : rpcinserter_base<T,uint64_t>(source, func)
00261   {;}
00262 
00263   pmt::pmt_t retrieve()
00264   {
00265     return pmt::from_uint64((rpcinserter_base<T,uint64_t>::
00266                              _source->*rpcinserter_base<T,uint64_t>::_func)());
00267   }
00268 };
00269 
00270 template<typename T>
00271 class rpcbasic_inserter<T,std::vector< signed char > >
00272   : public virtual rpcinserter_base<T,std::vector< signed char > >
00273 {
00274 public:
00275   rpcbasic_inserter(T* source, std::vector< signed char > (T::*func)() const)
00276     : rpcinserter_base<T,std::vector< signed char > >(source, func)
00277   {;}
00278 
00279   rpcbasic_inserter(T* source, std::vector< signed char > (T::*func)())
00280     : rpcinserter_base<T,std::vector< signed char > >(source, func)
00281   {;}
00282 
00283   pmt::pmt_t retrieve()
00284   {
00285     std::vector< signed char >
00286       vec((rpcinserter_base<T,std::vector< signed char > >::
00287            _source->*rpcinserter_base<T,std::vector< signed char > >::_func)()); 
00288     return pmt::init_s8vector(vec.size(), &vec[0]);
00289   }
00290 };
00291 
00292 template<typename T>
00293 class rpcbasic_inserter<T,std::vector< short > >
00294   : public virtual rpcinserter_base<T,std::vector< short > >
00295 {
00296 public:
00297   rpcbasic_inserter(T* source, std::vector< short > (T::*func)() const)
00298     : rpcinserter_base<T,std::vector< short > >(source, func)
00299   {;}
00300 
00301   rpcbasic_inserter(T* source, std::vector< short > (T::*func)())
00302     : rpcinserter_base<T,std::vector< short > >(source, func)
00303   {;}
00304 
00305   pmt::pmt_t retrieve()
00306   {
00307     std::vector< short >
00308       vec((rpcinserter_base<T,std::vector< short > >::
00309            _source->*rpcinserter_base<T,std::vector< short > >::_func)()); 
00310     return pmt::init_s16vector(vec.size(), &vec[0]);
00311   }
00312 };
00313 
00314 template<typename T>
00315 class rpcbasic_inserter<T,std::vector< int > >
00316   : public virtual rpcinserter_base<T,std::vector< int > >
00317 {
00318 public:
00319   rpcbasic_inserter(T* source, std::vector<int > (T::*func)() const)
00320     : rpcinserter_base<T,std::vector<int > >(source, func)
00321   {;}
00322 
00323   rpcbasic_inserter(T* source, std::vector<int > (T::*func)())
00324     : rpcinserter_base<T,std::vector<int > >(source, func)
00325   {;}
00326 
00327   pmt::pmt_t retrieve()
00328   {
00329     std::vector< int >
00330       vec((rpcinserter_base<T,std::vector<int > >::
00331            _source->*rpcinserter_base<T,std::vector< int > >::_func)()); 
00332     return pmt::init_s32vector(vec.size(), &vec[0]);
00333   }
00334 };
00335 
00336 template<typename T>
00337 class rpcbasic_inserter<T,std::vector< std::complex<float> > >
00338   : public virtual rpcinserter_base<T,std::vector< std::complex<float> > >
00339 {
00340 public:
00341   rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)() const)
00342     : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func)
00343   {;}
00344 
00345   rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)())
00346     : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func)
00347   {;}
00348 
00349   pmt::pmt_t retrieve()
00350   {
00351     std::vector< std::complex<float> >
00352       vec((rpcinserter_base<T,std::vector<std::complex<float> > >::
00353            _source->*rpcinserter_base<T,std::vector< std::complex<float> > >::_func)()); 
00354     return pmt::init_c32vector(vec.size(), &vec[0]);
00355   }
00356 };
00357 
00358 template<typename T>
00359 class rpcbasic_inserter<T,std::vector< float> >
00360   : public virtual rpcinserter_base<T,std::vector< float > >
00361 {
00362 public:
00363   rpcbasic_inserter(T* source, std::vector<float> (T::*func)() const)
00364     : rpcinserter_base<T,std::vector<float > >(source, func)
00365   {;}
00366   
00367   rpcbasic_inserter(T* source, std::vector<float> (T::*func)())
00368     : rpcinserter_base<T,std::vector<float> >(source, func)
00369   {;}
00370 
00371   pmt::pmt_t retrieve()
00372   {
00373     std::vector< float > vec((rpcinserter_base<T,std::vector<float> >::
00374               _source->*rpcinserter_base<T,std::vector< float> >::_func)()); 
00375     return pmt::init_f32vector(vec.size(), &vec[0]);
00376   }
00377 };
00378 
00379 template<typename T> 
00380 class rpcbasic_inserter<T,std::vector< uint8_t> > 
00381   : public virtual rpcinserter_base<T,std::vector< uint8_t > > {
00382 public:
00383   rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const) 
00384     : rpcinserter_base<T,std::vector<uint8_t > >(source, func) 
00385   {;}
00386 
00387   rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)()) 
00388     : rpcinserter_base<T,std::vector<uint8_t> >(source, func) 
00389   {;}
00390 
00391   pmt::pmt_t retrieve() 
00392   {
00393     std::vector< uint8_t > vec((rpcinserter_base<T,std::vector<uint8_t> >::
00394         _source->*rpcinserter_base<T,std::vector< uint8_t> >::_func)());
00395     return pmt::init_u8vector(vec.size(), &vec[0]); 
00396   }
00397 };
00398 
00399 template<typename T> 
00400 class rpcbasic_inserter<T,std::complex<float> > 
00401   : public virtual rpcinserter_base<T,std::complex<float > > {
00402 public:
00403   rpcbasic_inserter(T* source, std::complex<float> (T::*func)() const) 
00404     : rpcinserter_base<T,std::complex<float> >(source, func) 
00405   {;}
00406 
00407   rpcbasic_inserter(T* source, std::complex<float> (T::*func)()) 
00408     : rpcinserter_base<T,std::complex<float> >(source, func) 
00409   {;}
00410 
00411   pmt::pmt_t retrieve() 
00412   {
00413     std::complex<float > k((rpcinserter_base<T,std::complex<float> >::
00414                              _source->*rpcinserter_base<T,std::complex<float> >::_func)());
00415     return pmt::from_complex(k);
00416   }
00417 };
00418 
00419 template<typename T> 
00420 class rpcbasic_inserter<T,std::complex<double> > 
00421   : public virtual rpcinserter_base<T,std::complex<double > > {
00422 public:
00423   rpcbasic_inserter(T* source, std::complex<double> (T::*func)() const) 
00424     : rpcinserter_base<T,std::complex<double> >(source, func) 
00425   {;}
00426 
00427   rpcbasic_inserter(T* source, std::complex<double> (T::*func)()) 
00428     : rpcinserter_base<T,std::complex<double> >(source, func) 
00429   {;}
00430 
00431   pmt::pmt_t retrieve()
00432   {
00433     std::complex<double > k((rpcinserter_base<T,std::complex<double> >::
00434                              _source->*rpcinserter_base<T,std::complex<double> >::_func)());
00435     return pmt::from_complex(k);
00436   }
00437 };
00438 
00439 template <typename T>
00440 struct rpc_register_base
00441 {
00442   rpc_register_base() {count++;}
00443 protected: static int count;
00444 };
00445 
00446 // Base class to inherit from and create universal shared pointers.
00447 class rpcbasic_base
00448 {
00449 public:
00450   rpcbasic_base() {}
00451   virtual ~rpcbasic_base() {};
00452 };
00453 
00454 typedef boost::shared_ptr<rpcbasic_base> rpcbasic_sptr;
00455 
00456 template<typename T, typename Tto>
00457 struct rpcbasic_register_set : public rpcbasic_base
00458 {
00459   // Function used to add a 'set' RPC call using a basic_block's alias.
00460   rpcbasic_register_set(const std::string& block_alias,
00461                         const char* functionbase,
00462                         void (T::*function)(Tto), 
00463                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00464                         const char* units_ = "", 
00465                         const char* desc_ = "",
00466                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00467                         DisplayType display_ = DISPNULL)
00468   {
00469     d_min = min;
00470     d_max = max;
00471     d_def = def;
00472     d_units = units_;
00473     d_desc = desc_;
00474     d_minpriv = minpriv_;
00475     d_display = display_;
00476     d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
00477 #ifdef RPCSERVER_ENABLED
00478     callbackregister_base::configureCallback_t
00479       extractor(new rpcbasic_extractor<T,Tto>(d_object, function), 
00480                 minpriv_, std::string(units_),
00481                 display_, std::string(desc_), min, max, def);
00482     std::ostringstream oss(std::ostringstream::out);
00483     oss << block_alias << "::" << functionbase;
00484     d_id = oss.str();
00485     //std::cerr << "REGISTERING SET: " << d_id << "  " << desc_ << std::endl;
00486     rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor);
00487 #endif
00488   }
00489 
00490   // Function used to add a 'set' RPC call using a name and the object
00491   rpcbasic_register_set(const std::string& name,
00492                         const char* functionbase,
00493                         T* obj,
00494                         void (T::*function)(Tto), 
00495                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00496                         const char* units_ = "", 
00497                         const char* desc_ = "",
00498                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00499                         DisplayType display_ = DISPNULL)
00500   {
00501     d_min = min;
00502     d_max = max;
00503     d_def = def;
00504     d_units = units_;
00505     d_desc = desc_;
00506     d_minpriv = minpriv_;
00507     d_display = display_;
00508     d_object = obj;
00509 #ifdef RPCSERVER_ENABLED
00510     callbackregister_base::configureCallback_t
00511       extractor(new rpcbasic_extractor<T,Tto>(d_object, function), 
00512                 minpriv_, std::string(units_),
00513                 display_, std::string(desc_), min, max, def);
00514     std::ostringstream oss(std::ostringstream::out);
00515     oss << name << "::" << functionbase;
00516     d_id = oss.str();
00517     //std::cerr << "REGISTERING SET: " << d_id << "  " << desc_ << std::endl;
00518     rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor);
00519 #endif
00520   }
00521 
00522   ~rpcbasic_register_set()
00523   {
00524 #ifdef RPCSERVER_ENABLED
00525     rpcmanager::get()->i()->unregisterConfigureCallback(d_id);
00526 #endif
00527   }
00528 
00529 
00530   pmt::pmt_t min() const { return d_min; }
00531   pmt::pmt_t max() const { return d_max; }
00532   pmt::pmt_t def() const { return d_def; }
00533   std::string units() const { return d_units; }
00534   std::string description() const { return d_desc; }
00535   priv_lvl_t privilege_level() const { return d_minpriv; }
00536   DisplayType default_display() const { return d_display; }
00537 
00538   void set_min(pmt::pmt_t p) { d_min = p; }
00539   void set_max(pmt::pmt_t p) { d_max = p; }
00540   void set_def(pmt::pmt_t p) { d_def = p; }
00541   void units(std::string u) { d_units = u; }
00542   void description(std::string d) { d_desc = d; }
00543   void privilege_level(priv_lvl_t p) { d_minpriv = p; }
00544   void default_display(DisplayType d) { d_display = d; }
00545 
00546 private:
00547   std::string d_id;
00548   pmt::pmt_t d_min, d_max, d_def;
00549   std::string d_units, d_desc;
00550   priv_lvl_t d_minpriv;
00551   DisplayType d_display;
00552   T *d_object;
00553 };
00554 
00555 
00556 template<typename T, typename Tfrom>
00557 class rpcbasic_register_get : public rpcbasic_base
00558 {
00559 public:
00560   // Function used to add a 'set' RPC call using a basic_block's alias.
00561   // primary constructor to allow for T get() functions
00562   rpcbasic_register_get(const std::string& block_alias,
00563                         const char* functionbase,
00564                         Tfrom (T::*function)(), 
00565                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00566                         const char* units_ = "", 
00567                         const char* desc_ = "",
00568                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00569                         DisplayType display_ = DISPNULL)
00570   {
00571     d_min = min;
00572     d_max = max;
00573     d_def = def;
00574     d_units = units_;
00575     d_desc = desc_;
00576     d_minpriv = minpriv_;
00577     d_display = display_;
00578     d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
00579 #ifdef RPCSERVER_ENABLED
00580     callbackregister_base::queryCallback_t
00581       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), 
00582                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00583     std::ostringstream oss(std::ostringstream::out);
00584     oss << block_alias << "::" << functionbase;
00585     d_id = oss.str();
00586     //std::cerr << "REGISTERING GET: " << d_id << "  " << desc_ << std::endl;
00587     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00588 #endif
00589   }
00590 
00591         
00592   // alternate constructor to allow for T get() const functions
00593   rpcbasic_register_get(const std::string& block_alias,
00594                         const char* functionbase,
00595                         Tfrom (T::*function)() const, 
00596                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00597                         const char* units_ = "", 
00598                         const char* desc_ = "",
00599                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00600                         DisplayType display_ = DISPNULL)
00601   { 
00602     d_min = min;
00603     d_max = max;
00604     d_def = def;
00605     d_units = units_;
00606     d_desc = desc_;
00607     d_minpriv = minpriv_;
00608     d_display = display_;
00609     d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
00610 #ifdef RPCSERVER_ENABLED
00611     callbackregister_base::queryCallback_t
00612       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), 
00613                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00614     std::ostringstream oss(std::ostringstream::out);
00615     oss << block_alias << "::" << functionbase;
00616     d_id = oss.str();
00617     //std::cerr << "REGISTERING GET CONST: " << d_id << "   " << desc_ << "   " << display_ << std::endl;
00618     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00619 #endif
00620   }
00621 
00622   // Function used to add a 'set' RPC call using a name and the object
00623   // primary constructor to allow for T get() functions
00624   rpcbasic_register_get(const std::string& name,
00625                         const char* functionbase,
00626                         T* obj,
00627                         Tfrom (T::*function)(), 
00628                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00629                         const char* units_ = "", 
00630                         const char* desc_ = "",
00631                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00632                         DisplayType display_ = DISPNULL)
00633   {
00634     d_min = min;
00635     d_max = max;
00636     d_def = def;
00637     d_units = units_;
00638     d_desc = desc_;
00639     d_minpriv = minpriv_;
00640     d_display = display_;
00641     d_object = obj;
00642 #ifdef RPCSERVER_ENABLED
00643     callbackregister_base::queryCallback_t
00644       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), 
00645                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00646     std::ostringstream oss(std::ostringstream::out);
00647     oss << name << "::" << functionbase;
00648     d_id = oss.str();
00649     //std::cerr << "REGISTERING GET: " << d_id << "  " << desc_ << std::endl;
00650     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00651 #endif
00652   }
00653 
00654         
00655   // alternate constructor to allow for T get() const functions
00656   rpcbasic_register_get(const std::string& name,
00657                         const char* functionbase,
00658                         T* obj,
00659                         Tfrom (T::*function)() const, 
00660                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00661                         const char* units_ = "", 
00662                         const char* desc_ = "",
00663                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00664                         DisplayType display_ = DISPNULL)
00665   { 
00666     d_min = min;
00667     d_max = max;
00668     d_def = def;
00669     d_units = units_;
00670     d_desc = desc_;
00671     d_minpriv = minpriv_;
00672     d_display = display_;
00673     d_object = obj;
00674 #ifdef RPCSERVER_ENABLED
00675     callbackregister_base::queryCallback_t
00676       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), 
00677                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00678     std::ostringstream oss(std::ostringstream::out);
00679     oss << name << "::" << functionbase;
00680     d_id = oss.str();
00681     //std::cerr << "REGISTERING GET CONST: " << d_id << "   " << desc_ << "   " << display_ << std::endl;
00682     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00683 #endif
00684   }
00685 
00686   ~rpcbasic_register_get()
00687   {
00688 #ifdef RPCSERVER_ENABLED
00689     rpcmanager::get()->i()->unregisterQueryCallback(d_id);
00690 #endif
00691   }
00692 
00693   pmt::pmt_t min() const { return d_min; }
00694   pmt::pmt_t max() const { return d_max; }
00695   pmt::pmt_t def() const { return d_def; }
00696   std::string units() const { return d_units; }
00697   std::string description() const { return d_desc; }
00698   priv_lvl_t privilege_level() const { return d_minpriv; }
00699   DisplayType default_display() const { return d_display; }
00700 
00701   void set_min(pmt::pmt_t p) { d_min = p; }
00702   void set_max(pmt::pmt_t p) { d_max = p; }
00703   void set_def(pmt::pmt_t p) { d_def = p; }
00704   void units(std::string u) { d_units = u; }
00705   void description(std::string d) { d_desc = d; }
00706   void privilege_level(priv_lvl_t p) { d_minpriv = p; }
00707   void default_display(DisplayType d) { d_display = d; }
00708 
00709 private:
00710   std::string d_id;
00711   pmt::pmt_t d_min, d_max, d_def;
00712   std::string d_units, d_desc;
00713   priv_lvl_t d_minpriv;
00714   DisplayType d_display;
00715   T *d_object;
00716 };
00717 
00718 /*
00719  * This class can wrap a pre-existing variable type for you
00720  * it will define the getter and rpcregister call for you.
00721  * 
00722  * It should be used for read-only getters.
00723  *
00724  */
00725 template<typename Tfrom>
00726 class rpcbasic_register_variable : public rpcbasic_base
00727 {
00728 protected:
00729   rpcbasic_register_get< rpcbasic_register_variable<Tfrom>, Tfrom > d_rpc_reg;
00730   Tfrom *d_variable;
00731   Tfrom get() { return *d_variable; }
00732 public:
00733   // empty constructor which should never be called but needs to exist for ues in varous STL data structures
00734   void setptr(Tfrom* _variable){  rpcbasic_register_variable<Tfrom>::d_variable = _variable; }
00735   rpcbasic_register_variable() :
00736     d_rpc_reg("FAIL", "FAIL", this, &rpcbasic_register_variable::get,
00737               pmt::PMT_NIL, pmt::PMT_NIL, pmt::PMT_NIL, DISPNULL,
00738               "FAIL", "FAIL", RPC_PRIVLVL_MIN),
00739     d_variable(NULL)
00740   {
00741     throw std::runtime_error("ERROR: rpcbasic_register_variable called with no args. If this happens, someone has tried to use rpcbasic_register_variable incorrectly.");
00742   };
00743 
00744   rpcbasic_register_variable(const std::string& namebase,
00745                              const char* functionbase,
00746                              Tfrom *variable,
00747                              const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00748                              const char* units_ = "",
00749                              const char* desc_ = "",
00750                              priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00751                              DisplayType display_=DISPNULL) :
00752     d_rpc_reg(namebase, functionbase, this, &rpcbasic_register_variable::get,
00753               min, max, def, units_, desc_, minpriv_, display_),
00754     d_variable(variable)
00755   {
00756     //std::cerr << "REGISTERING VAR: " << " " << desc_ << std::endl;
00757   }
00758 };
00759 
00760 template<typename Tfrom> class rpcbasic_register_variable_rw : public rpcbasic_register_variable<Tfrom> {
00761   private:
00762     rpcbasic_register_set< rpcbasic_register_variable_rw<Tfrom>, Tfrom > d_rpc_regset;
00763   public:
00764     // empty constructor which should never be called but needs to exist for ues in varous STL data structures
00765     rpcbasic_register_variable_rw()  :
00766             d_rpc_regset("FAIL","FAIL",this,&rpcbasic_register_variable<Tfrom>::get,pmt::PMT_NIL,pmt::PMT_NIL,pmt::PMT_NIL,DISPNULL,"FAIL","FAIL",RPC_PRIVLVL_MIN)
00767         {
00768         throw std::runtime_error("ERROR: rpcbasic_register_variable_rw called with no args. if this happens someone used rpcbasic_register_variable_rw incorrectly.\n");
00769         };
00770     void set(Tfrom _variable){  *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; }
00771     rpcbasic_register_variable_rw(
00772         const std::string& namebase,
00773         const char* functionbase,
00774         Tfrom *variable,
00775         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00776         const char* units_ = "",
00777         const char* desc_ = "",
00778         priv_lvl_t minpriv = RPC_PRIVLVL_MIN,
00779         DisplayType display_=DISPNULL) :
00780             rpcbasic_register_variable<Tfrom>(namebase,functionbase,variable,min,max,def,units_,desc_),
00781             d_rpc_regset(namebase,functionbase,this,&rpcbasic_register_variable_rw::set,min,max,def,units_,desc_,minpriv,display_)
00782          {
00783         // no action
00784         }
00785 };
00786 
00787 
00788 
00789 
00790 #endif