GNU Radio 3.7.0 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,double> : public virtual rpcextractor_base<T,double>
00099 {
00100 public:
00101   rpcbasic_extractor(T* source, void (T::*func)(double))
00102     : rpcextractor_base<T,double>(source, func)
00103   {;}
00104 
00105   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00106   {
00107     (rpcextractor_base<T,double>::_source->*rpcextractor_base<T,double>::_func)
00108       (pmt::to_double(msg));
00109   }
00110 };
00111 
00112 template<typename T>
00113 class rpcbasic_extractor<T,float> : public virtual rpcextractor_base<T,float>
00114 {
00115 public:
00116   rpcbasic_extractor(T* source, void (T::*func)(float))
00117     : rpcextractor_base<T,float>(source, func)
00118   {;}
00119 
00120   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00121   {
00122     (rpcextractor_base<T,float>::_source->*rpcextractor_base<T,float>::_func)
00123       (pmt::to_double(msg));
00124   }
00125 };
00126 
00127 template<typename T>
00128 class rpcbasic_extractor<T,long> : public virtual rpcextractor_base<T,long>
00129 {
00130 public:
00131   rpcbasic_extractor(T* source, void (T::*func)(long))
00132     : rpcextractor_base<T,long>(source, func)
00133   {;}
00134 
00135   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00136   {
00137     (rpcextractor_base<T,long>::_source->*rpcextractor_base<T,long>::_func)
00138       (pmt::to_long(msg));
00139   }
00140 };
00141 
00142 template<typename T>
00143 class rpcbasic_extractor<T,int> : public virtual rpcextractor_base<T,int>
00144 {
00145 public:
00146   rpcbasic_extractor(T* source, void (T::*func)(int))
00147     : rpcextractor_base<T,int>(source, func)
00148   {;}
00149 
00150   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00151   {
00152     (rpcextractor_base<T,int>::_source->*rpcextractor_base<T,int>::_func)
00153       (pmt::to_long(msg));
00154   }
00155 };
00156 
00157 template<typename T>
00158 class rpcbasic_extractor<T,bool> : public virtual rpcextractor_base<T,bool>
00159 {
00160 public:
00161   rpcbasic_extractor(T* source, void (T::*func)(bool))
00162     : rpcextractor_base<T,bool>(source, func)
00163   {;}
00164 
00165   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00166   {
00167     (rpcextractor_base<T,bool>::_source->*rpcextractor_base<T,bool>::_func)
00168       (pmt::to_bool(msg));
00169   }
00170 };
00171 
00172 template<typename T>
00173 class rpcbasic_extractor<T,std::complex<float> >
00174   : public virtual rpcextractor_base<T,std::complex<float> >
00175 {
00176 public:
00177   rpcbasic_extractor(T* source, void (T::*func)(std::complex<float>))
00178     : rpcextractor_base<T,std::complex<float> >(source, func)
00179   {;}
00180 
00181   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00182   {
00183     std::complex<float> k = static_cast<std::complex<float> >(pmt::to_complex(msg));
00184     (rpcextractor_base<T,std::complex<float> >::
00185      _source->*rpcextractor_base<T,std::complex<float> >::_func)(k);
00186   }
00187 };
00188 
00189 template<typename T>
00190 class rpcbasic_extractor<T,std::complex<double> >
00191   : public virtual rpcextractor_base<T,std::complex<double> >
00192 {
00193 public:
00194   rpcbasic_extractor(T* source, void (T::*func)(std::complex<double>))
00195     : rpcextractor_base<T,std::complex<double> >(source, func)
00196   {;}
00197 
00198   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00199   {
00200     (rpcextractor_base<T,std::complex<double> >::
00201      _source->*rpcextractor_base<T,std::complex<double> >::_func)(pmt::to_complex(msg));
00202   }
00203 };
00204 
00205 template<typename T>
00206 class rpcbasic_extractor<T,std::string>
00207   : public virtual rpcextractor_base<T,std::string>
00208 {
00209 public:
00210   rpcbasic_extractor(T* source, void (T::*func)(std::string))
00211     : rpcextractor_base<T,std::string>(source, func)
00212   {;}
00213 
00214   void post(pmt::pmt_t which_port, pmt::pmt_t msg)
00215   {
00216     (rpcextractor_base<T,std::string>::
00217      _source->*rpcextractor_base<T,std::string>::_func)(pmt::symbol_to_string(msg)); 
00218   }
00219 };
00220 
00221 template<typename T>
00222 class rpcbasic_inserter<T,uint64_t> : public virtual rpcinserter_base<T,uint64_t>
00223 {
00224 public:
00225   rpcbasic_inserter(T* source, uint64_t (T::*func)() const)
00226     : rpcinserter_base<T,uint64_t>(source, func)
00227   {;}
00228 
00229   rpcbasic_inserter(T* source, uint64_t (T::*func)())
00230     : rpcinserter_base<T,uint64_t>(source, func)
00231   {;}
00232 
00233   pmt::pmt_t retrieve()
00234   {
00235     return pmt::from_uint64((rpcinserter_base<T,uint64_t>::
00236                              _source->*rpcinserter_base<T,uint64_t>::_func)());
00237   }
00238 };
00239 
00240 template<typename T>
00241 class rpcbasic_inserter<T,std::vector< int > >
00242   : public virtual rpcinserter_base<T,std::vector< int > >
00243 {
00244 public:
00245   rpcbasic_inserter(T* source, std::vector<int > (T::*func)() const)
00246     : rpcinserter_base<T,std::vector<int > >(source, func)
00247   {;}
00248 
00249   rpcbasic_inserter(T* source, std::vector<int > (T::*func)())
00250     : rpcinserter_base<T,std::vector<int > >(source, func)
00251   {;}
00252 
00253   pmt::pmt_t retrieve()
00254   {
00255     std::vector< int >
00256       vec((rpcinserter_base<T,std::vector<int > >::
00257            _source->*rpcinserter_base<T,std::vector< int > >::_func)()); 
00258     return pmt::init_s32vector(vec.size(), &vec[0]);
00259   }
00260 };
00261 
00262 template<typename T>
00263 class rpcbasic_inserter<T,std::vector< std::complex<float> > >
00264   : public virtual rpcinserter_base<T,std::vector< std::complex<float> > >
00265 {
00266 public:
00267   rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)() const)
00268     : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func)
00269   {;}
00270 
00271   rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)())
00272     : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func)
00273   {;}
00274 
00275   pmt::pmt_t retrieve()
00276   {
00277     std::vector< std::complex<float> >
00278       vec((rpcinserter_base<T,std::vector<std::complex<float> > >::
00279            _source->*rpcinserter_base<T,std::vector< std::complex<float> > >::_func)()); 
00280     return pmt::init_c32vector(vec.size(), &vec[0]);
00281   }
00282 };
00283 
00284 template<typename T>
00285 class rpcbasic_inserter<T,std::vector< float> >
00286   : public virtual rpcinserter_base<T,std::vector< float > >
00287 {
00288 public:
00289   rpcbasic_inserter(T* source, std::vector<float> (T::*func)() const)
00290     : rpcinserter_base<T,std::vector<float > >(source, func)
00291   {;}
00292   
00293   rpcbasic_inserter(T* source, std::vector<float> (T::*func)())
00294     : rpcinserter_base<T,std::vector<float> >(source, func)
00295   {;}
00296 
00297   pmt::pmt_t retrieve()
00298   {
00299     std::vector< float > vec((rpcinserter_base<T,std::vector<float> >::
00300               _source->*rpcinserter_base<T,std::vector< float> >::_func)()); 
00301     return pmt::init_f32vector(vec.size(), &vec[0]);
00302   }
00303 };
00304 
00305 template<typename T> 
00306 class rpcbasic_inserter<T,std::vector< uint8_t> > 
00307   : public virtual rpcinserter_base<T,std::vector< uint8_t > > {
00308 public:
00309   rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const) 
00310     : rpcinserter_base<T,std::vector<uint8_t > >(source, func) 
00311   {;}
00312 
00313   rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)()) 
00314     : rpcinserter_base<T,std::vector<uint8_t> >(source, func) 
00315   {;}
00316 
00317   pmt::pmt_t retrieve() 
00318   {
00319     std::vector< uint8_t > vec((rpcinserter_base<T,std::vector<uint8_t> >::
00320         _source->*rpcinserter_base<T,std::vector< uint8_t> >::_func)());
00321     return pmt::init_u8vector(vec.size(), &vec[0]); 
00322   }
00323 };
00324 
00325 template<typename T> 
00326 class rpcbasic_inserter<T,std::complex<float> > 
00327   : public virtual rpcinserter_base<T,std::complex<float > > {
00328 public:
00329   rpcbasic_inserter(T* source, std::complex<float> (T::*func)() const) 
00330     : rpcinserter_base<T,std::complex<float> >(source, func) 
00331   {;}
00332 
00333   rpcbasic_inserter(T* source, std::complex<float> (T::*func)()) 
00334     : rpcinserter_base<T,std::complex<float> >(source, func) 
00335   {;}
00336 
00337   pmt::pmt_t retrieve() 
00338   {
00339     std::complex<float > k((rpcinserter_base<T,std::complex<float> >::
00340                              _source->*rpcinserter_base<T,std::complex<float> >::_func)());
00341     return pmt::from_complex(k);
00342   }
00343 };
00344 
00345 template<typename T> 
00346 class rpcbasic_inserter<T,std::complex<double> > 
00347   : public virtual rpcinserter_base<T,std::complex<double > > {
00348 public:
00349   rpcbasic_inserter(T* source, std::complex<double> (T::*func)() const) 
00350     : rpcinserter_base<T,std::complex<double> >(source, func) 
00351   {;}
00352 
00353   rpcbasic_inserter(T* source, std::complex<double> (T::*func)()) 
00354     : rpcinserter_base<T,std::complex<double> >(source, func) 
00355   {;}
00356 
00357   pmt::pmt_t retrieve() 
00358   {
00359     std::complex<double > k((rpcinserter_base<T,std::complex<double> >::
00360                              _source->*rpcinserter_base<T,std::complex<double> >::_func)());
00361     return pmt::from_complex(k);
00362   }
00363 };
00364 
00365 template <typename T>
00366 struct rpc_register_base
00367 {
00368   rpc_register_base() {count++;}
00369 protected: static int count;
00370 };
00371 
00372 // Base class to inherit from and create universal shared pointers.
00373 class rpcbasic_base
00374 {
00375 public:
00376   rpcbasic_base() {}
00377   virtual ~rpcbasic_base() {};
00378 };
00379 
00380 typedef boost::shared_ptr<rpcbasic_base> rpcbasic_sptr;
00381 
00382 template<typename T, typename Tto>
00383 struct rpcbasic_register_set : public rpcbasic_base
00384 {
00385   // Function used to add a 'set' RPC call using a basic_block's alias.
00386   rpcbasic_register_set(const std::string& block_alias,
00387                         const char* functionbase,
00388                         void (T::*function)(Tto), 
00389                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00390                         const char* units_ = "", 
00391                         const char* desc_ = "",
00392                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00393                         DisplayType display_ = DISPNULL)
00394   {
00395     d_min = min;
00396     d_max = max;
00397     d_def = def;
00398     d_units = units_;
00399     d_desc = desc_;
00400     d_minpriv = minpriv_;
00401     d_display = display_;
00402     d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
00403 #ifdef RPCSERVER_ENABLED
00404     callbackregister_base::configureCallback_t
00405       extractor(new rpcbasic_extractor<T,Tto>(d_object, function), 
00406                 minpriv_, std::string(units_),
00407                 display_, std::string(desc_), min, max, def);
00408     std::ostringstream oss(std::ostringstream::out);
00409     oss << block_alias << "::" << functionbase;
00410     d_id = oss.str();
00411     //std::cerr << "REGISTERING SET: " << d_id << "  " << desc_ << std::endl;
00412     rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor);
00413 #endif
00414   }
00415 
00416   // Function used to add a 'set' RPC call using a name and the object
00417   rpcbasic_register_set(const std::string& name,
00418                         const char* functionbase,
00419                         T* obj,
00420                         void (T::*function)(Tto), 
00421                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00422                         const char* units_ = "", 
00423                         const char* desc_ = "",
00424                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00425                         DisplayType display_ = DISPNULL)
00426   {
00427     d_min = min;
00428     d_max = max;
00429     d_def = def;
00430     d_units = units_;
00431     d_desc = desc_;
00432     d_minpriv = minpriv_;
00433     d_display = display_;
00434     d_object = obj;
00435 #ifdef RPCSERVER_ENABLED
00436     callbackregister_base::configureCallback_t
00437       extractor(new rpcbasic_extractor<T,Tto>(d_object, function), 
00438                 minpriv_, std::string(units_),
00439                 display_, std::string(desc_), min, max, def);
00440     std::ostringstream oss(std::ostringstream::out);
00441     oss << name << "::" << functionbase;
00442     d_id = oss.str();
00443     //std::cerr << "REGISTERING SET: " << d_id << "  " << desc_ << std::endl;
00444     rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor);
00445 #endif
00446   }
00447 
00448   ~rpcbasic_register_set()
00449   {
00450 #ifdef RPCSERVER_ENABLED
00451     rpcmanager::get()->i()->unregisterConfigureCallback(d_id);
00452 #endif
00453   }
00454 
00455 
00456   pmt::pmt_t min() const { return d_min; }
00457   pmt::pmt_t max() const { return d_max; }
00458   pmt::pmt_t def() const { return d_def; }
00459   std::string units() const { return d_units; }
00460   std::string description() const { return d_desc; }
00461   priv_lvl_t privilege_level() const { return d_minpriv; }
00462   DisplayType default_display() const { return d_display; }
00463 
00464   void set_min(pmt::pmt_t p) { d_min = p; }
00465   void set_max(pmt::pmt_t p) { d_max = p; }
00466   void set_def(pmt::pmt_t p) { d_def = p; }
00467   void units(std::string u) { d_units = u; }
00468   void description(std::string d) { d_desc = d; }
00469   void privilege_level(priv_lvl_t p) { d_minpriv = p; }
00470   void default_display(DisplayType d) { d_display = d; }
00471 
00472 private:
00473   std::string d_id;
00474   pmt::pmt_t d_min, d_max, d_def;
00475   std::string d_units, d_desc;
00476   priv_lvl_t d_minpriv;
00477   DisplayType d_display;
00478   T *d_object;
00479 };
00480 
00481 
00482 template<typename T, typename Tfrom>
00483 class rpcbasic_register_get : public rpcbasic_base
00484 {
00485 public:
00486   // Function used to add a 'set' RPC call using a basic_block's alias.
00487   // primary constructor to allow for T get() functions
00488   rpcbasic_register_get(const std::string& block_alias,
00489                         const char* functionbase,
00490                         Tfrom (T::*function)(), 
00491                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00492                         const char* units_ = "", 
00493                         const char* desc_ = "",
00494                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00495                         DisplayType display_ = DISPNULL)
00496   {
00497     d_min = min;
00498     d_max = max;
00499     d_def = def;
00500     d_units = units_;
00501     d_desc = desc_;
00502     d_minpriv = minpriv_;
00503     d_display = display_;
00504     d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
00505 #ifdef RPCSERVER_ENABLED
00506     callbackregister_base::queryCallback_t
00507       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), 
00508                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00509     std::ostringstream oss(std::ostringstream::out);
00510     oss << block_alias << "::" << functionbase;
00511     d_id = oss.str();
00512     //std::cerr << "REGISTERING GET: " << d_id << "  " << desc_ << std::endl;
00513     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00514 #endif
00515   }
00516 
00517         
00518   // alternate constructor to allow for T get() const functions
00519   rpcbasic_register_get(const std::string& block_alias,
00520                         const char* functionbase,
00521                         Tfrom (T::*function)() const, 
00522                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00523                         const char* units_ = "", 
00524                         const char* desc_ = "",
00525                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00526                         DisplayType display_ = DISPNULL)
00527   { 
00528     d_min = min;
00529     d_max = max;
00530     d_def = def;
00531     d_units = units_;
00532     d_desc = desc_;
00533     d_minpriv = minpriv_;
00534     d_display = display_;
00535     d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
00536 #ifdef RPCSERVER_ENABLED
00537     callbackregister_base::queryCallback_t
00538       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), 
00539                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00540     std::ostringstream oss(std::ostringstream::out);
00541     oss << block_alias << "::" << functionbase;
00542     d_id = oss.str();
00543     //std::cerr << "REGISTERING GET CONST: " << d_id << "   " << desc_ << "   " << display_ << std::endl;
00544     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00545 #endif
00546   }
00547 
00548   // Function used to add a 'set' RPC call using a name and the object
00549   // primary constructor to allow for T get() functions
00550   rpcbasic_register_get(const std::string& name,
00551                         const char* functionbase,
00552                         T* obj,
00553                         Tfrom (T::*function)(), 
00554                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00555                         const char* units_ = "", 
00556                         const char* desc_ = "",
00557                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00558                         DisplayType display_ = DISPNULL)
00559   {
00560     d_min = min;
00561     d_max = max;
00562     d_def = def;
00563     d_units = units_;
00564     d_desc = desc_;
00565     d_minpriv = minpriv_;
00566     d_display = display_;
00567     d_object = obj;
00568 #ifdef RPCSERVER_ENABLED
00569     callbackregister_base::queryCallback_t
00570       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), 
00571                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00572     std::ostringstream oss(std::ostringstream::out);
00573     oss << name << "::" << functionbase;
00574     d_id = oss.str();
00575     //std::cerr << "REGISTERING GET: " << d_id << "  " << desc_ << std::endl;
00576     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00577 #endif
00578   }
00579 
00580         
00581   // alternate constructor to allow for T get() const functions
00582   rpcbasic_register_get(const std::string& name,
00583                         const char* functionbase,
00584                         T* obj,
00585                         Tfrom (T::*function)() const, 
00586                         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00587                         const char* units_ = "", 
00588                         const char* desc_ = "",
00589                         priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00590                         DisplayType display_ = DISPNULL)
00591   { 
00592     d_min = min;
00593     d_max = max;
00594     d_def = def;
00595     d_units = units_;
00596     d_desc = desc_;
00597     d_minpriv = minpriv_;
00598     d_display = display_;
00599     d_object = obj;
00600 #ifdef RPCSERVER_ENABLED
00601     callbackregister_base::queryCallback_t
00602       inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), 
00603                minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
00604     std::ostringstream oss(std::ostringstream::out);
00605     oss << name << "::" << functionbase;
00606     d_id = oss.str();
00607     //std::cerr << "REGISTERING GET CONST: " << d_id << "   " << desc_ << "   " << display_ << std::endl;
00608     rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
00609 #endif
00610   }
00611 
00612   ~rpcbasic_register_get()
00613   {
00614 #ifdef RPCSERVER_ENABLED
00615     rpcmanager::get()->i()->unregisterQueryCallback(d_id);
00616 #endif
00617   }
00618 
00619   pmt::pmt_t min() const { return d_min; }
00620   pmt::pmt_t max() const { return d_max; }
00621   pmt::pmt_t def() const { return d_def; }
00622   std::string units() const { return d_units; }
00623   std::string description() const { return d_desc; }
00624   priv_lvl_t privilege_level() const { return d_minpriv; }
00625   DisplayType default_display() const { return d_display; }
00626 
00627   void set_min(pmt::pmt_t p) { d_min = p; }
00628   void set_max(pmt::pmt_t p) { d_max = p; }
00629   void set_def(pmt::pmt_t p) { d_def = p; }
00630   void units(std::string u) { d_units = u; }
00631   void description(std::string d) { d_desc = d; }
00632   void privilege_level(priv_lvl_t p) { d_minpriv = p; }
00633   void default_display(DisplayType d) { d_display = d; }
00634 
00635 private:
00636   std::string d_id;
00637   pmt::pmt_t d_min, d_max, d_def;
00638   std::string d_units, d_desc;
00639   priv_lvl_t d_minpriv;
00640   DisplayType d_display;
00641   T *d_object;
00642 };
00643 
00644 /*
00645  * This class can wrap a pre-existing variable type for you
00646  * it will define the getter and rpcregister call for you.
00647  * 
00648  * It should be used for read-only getters.
00649  *
00650  */
00651 template<typename Tfrom>
00652 class rpcbasic_register_variable : public rpcbasic_base
00653 {
00654 protected:
00655   rpcbasic_register_get< rpcbasic_register_variable<Tfrom>, Tfrom > d_rpc_reg;
00656   Tfrom *d_variable;
00657   Tfrom get() { return *d_variable; }
00658 public:
00659   // empty constructor which should never be called but needs to exist for ues in varous STL data structures
00660   void setptr(Tfrom* _variable){  rpcbasic_register_variable<Tfrom>::d_variable = _variable; }
00661   rpcbasic_register_variable() :
00662     d_rpc_reg("FAIL", "FAIL", this, &rpcbasic_register_variable::get,
00663               pmt::PMT_NIL, pmt::PMT_NIL, pmt::PMT_NIL, DISPNULL,
00664               "FAIL", "FAIL", RPC_PRIVLVL_MIN),
00665     d_variable(NULL)
00666   {
00667     throw std::runtime_error("ERROR: rpcbasic_register_variable called with no args. If this happens, someone has tried to use rpcbasic_register_variable incorrectly.");
00668   };
00669 
00670   rpcbasic_register_variable(const std::string& namebase,
00671                              const char* functionbase,
00672                              Tfrom *variable,
00673                              const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00674                              const char* units_ = "",
00675                              const char* desc_ = "",
00676                              priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
00677                              DisplayType display_=DISPNULL) :
00678     d_rpc_reg(namebase, functionbase, this, &rpcbasic_register_variable::get,
00679               min, max, def, units_, desc_, minpriv_, display_),
00680     d_variable(variable)
00681   {
00682     //std::cerr << "REGISTERING VAR: " << " " << desc_ << std::endl;
00683   }
00684 };
00685 
00686 template<typename Tfrom> class rpcbasic_register_variable_rw : public rpcbasic_register_variable<Tfrom> {
00687   private:
00688     rpcbasic_register_set< rpcbasic_register_variable_rw<Tfrom>, Tfrom > d_rpc_regset;
00689   public:
00690     // empty constructor which should never be called but needs to exist for ues in varous STL data structures
00691     rpcbasic_register_variable_rw()  :
00692             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)
00693         {
00694         throw std::runtime_error("ERROR: rpcbasic_register_variable_rw called with no args. if this happens someone used rpcbasic_register_variable_rw incorrectly.\n");
00695         };
00696     void set(Tfrom _variable){  *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; }
00697     rpcbasic_register_variable_rw(
00698         const std::string& namebase,
00699         const char* functionbase,
00700         Tfrom *variable,
00701         const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
00702         const char* units_ = "",
00703         const char* desc_ = "",
00704         priv_lvl_t minpriv = RPC_PRIVLVL_MIN,
00705         DisplayType display_=DISPNULL) :
00706             rpcbasic_register_variable<Tfrom>(namebase,functionbase,variable,min,max,def,units_,desc_),
00707             d_rpc_regset(namebase,functionbase,this,&rpcbasic_register_variable_rw::set,min,max,def,units_,desc_,minpriv,display_)
00708          {
00709         // no action
00710         }
00711 };
00712 
00713 
00714 
00715 
00716 #endif