clientproxy.h

00001 /*
00002  *  Player - One Hell of a Robot Server
00003  *  Copyright (C) 2000-2003
00004  *     Brian Gerkey, Kasper Stoy, Richard Vaughan, & Andrew Howard
00005  *
00006  *
00007  *  This program 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 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program 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 this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  */
00022 /********************************************************************
00023  *
00024  *  This library is free software; you can redistribute it and/or
00025  *  modify it under the terms of the GNU Lesser General Public
00026  *  License as published by the Free Software Foundation; either
00027  *  version 2.1 of the License, or (at your option) any later version.
00028  *
00029  *  This library is distributed in the hope that it will be useful,
00030  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00031  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00032  *  Lesser General Public License for more details.
00033  *
00034  *  You should have received a copy of the GNU Lesser General Public
00035  *  License along with this library; if not, write to the Free Software
00036  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00037  *
00038  ********************************************************************/
00039 
00040 /***************************************************************************
00041  * Desc: Player v2.0 C++ client
00042  * Authors: Brad Kratochvil, Toby Collett
00043  *
00044  * Date: 23 Sep 2005
00045  # CVS: $Id: clientproxy.h 6558 2008-06-13 23:37:38Z thjc $
00046  **************************************************************************/
00047 
00048 
00049 #ifndef PLAYERCC_CLIENTPROXY_H
00050 #define PLAYERCC_CLIENTPROXY_H
00051 namespace PlayerCc
00052 {
00053 
00066 class ClientProxy
00067 {
00068   friend class PlayerClient;
00069 
00070   public:
00071 
00072 #ifdef HAVE_BOOST_SIGNALS
00075     typedef boost::signals::connection connection_t;
00076 
00078     typedef boost::mutex::scoped_lock scoped_lock_t;
00079 
00081     typedef boost::signal<void (void)> read_signal_t;
00082 #else
00083     // if we're not using boost, just define them.
00084     typedef int connection_t;
00085     // we redefine boost::mustex::scoped_lock in playerclient.h
00086     typedef boost::mutex::scoped_lock scoped_lock_t;
00087     // if we're not using boost, just define them.
00088     typedef int read_signal_t;
00089 #endif
00090 
00091   protected:
00092 
00093     // The ClientProxy constructor
00094     // @attention Potected, so it can only be instantiated by other clients
00095     //
00096     // @throw PlayerError Throws a PlayerError if unable to connect to the client
00097     ClientProxy(PlayerClient* aPc, uint32_t aIndex);
00098 
00099     // destructor will try to close access to the device
00100     virtual ~ClientProxy();
00101 
00102     // Subscribe to the proxy
00103     // This needs to be defined for every proxy.
00104     // @arg aIndex the index of the devce we want to connect to
00105 
00106     // I wish these could be pure virtual,
00107     // but they're used in the constructor/destructor
00108     virtual void Subscribe(uint32_t /*aIndex*/) {};
00109 
00110     // Unsubscribe from the proxy
00111     // This needs to be defined for every proxy.
00112     virtual void Unsubscribe() {};
00113 
00114     // The controlling client object.
00115     PlayerClient* mPc;
00116 
00117     // A reference to the C client
00118     playerc_client_t* mClient;
00119 
00120     // contains convenience information about the device
00121     playerc_device_t *mInfo;
00122 
00123     // if set to true, the current data is "fresh"
00124     bool mFresh;
00125 
00126     // @brief Get a variable from the client
00127     // All Get functions need to use this when accessing data from the
00128     // c library to make sure the data access is thread safe.
00129     template<typename T>
00130     T GetVar(const T &aV) const
00131     { // these have to be defined here since they're templates
00132       scoped_lock_t lock(mPc->mMutex);
00133       T v = aV;
00134       return v;
00135     }
00136 
00137     // @brief Get a variable from the client by reference
00138     // All Get functions need to use this when accessing data from the
00139     // c library to make sure the data access is thread safe.  In this
00140     // case, a begin, end, and destination pointer must be given (similar
00141     // to C++ copy).  It is up to the user to ensure there is memory
00142     // allocated at aDest.
00143     template<typename T>
00144     void GetVarByRef(const T aBegin, const T aEnd, T aDest) const
00145     { // these have to be defined here since they're templates
00146       scoped_lock_t lock(mPc->mMutex);
00147       std::copy(aBegin, aEnd, aDest);
00148     }
00149 
00150   private:
00151 
00152     // The last time that data was read by this client in [s].
00153     double mLastTime;
00154 
00155     // A boost::signal which is used for our callbacks.
00156     // The signal will normally be of a type such as:
00157     // - boost::signal<void ()>
00158     // - boost::signal<void (T)>
00159     // where T can be any type.
00160     //
00161     // @attention we currently only use signals that return void because we
00162     // don't have checks to make sure a signal is registered.  If an empty
00163     // signal is called:
00164     //
00165     // @attention "Calling the function call operator may invoke undefined
00166     // behavior if no slots are connected to the signal, depending on the
00167     // combiner used. The default combiner is well-defined for zero slots when
00168     // the return type is void but is undefined when the return type is any
00169     // other type (because there is no way to synthesize a return value)."
00170     //
00171     read_signal_t mReadSignal;
00172 
00173     // Outputs the signal if there is new data
00174     void ReadSignal();
00175 
00176   public:
00177 
00179     bool IsValid() const { return 0!=GetVar(mInfo->datatime); };
00180 
00184     bool IsFresh() const { return GetVar(mFresh); };
00185 
00187     void NotFresh();
00188 
00191     std::string GetDriverName() const { return mInfo->drivername; };
00192 
00194     double GetDataTime() const { return GetVar(mInfo->datatime); };
00195 
00197     double GetElapsedTime() const
00198       { return GetVar(mInfo->datatime) - GetVar(mInfo->lasttime); };
00199 
00201     PlayerClient * GetPlayerClient() const { return mPc;}
00203     uint32_t GetIndex() const { return GetVar(mInfo->addr.index); };
00204 
00206     uint32_t GetInterface() const { return GetVar(mInfo->addr.interf); };
00207 
00209     std::string GetInterfaceStr() const
00210       { return interf_to_str(GetVar(mInfo->addr.interf)); };
00211 
00225     void SetReplaceRule(bool aReplace,
00226                         int aType = -1,
00227                         int aSubtype = -1);
00228 
00233     int HasCapability(uint32_t aType, uint32_t aSubtype);
00234 
00236     int GetIntProp(char *aProperty, int32_t *aValue);
00237 
00239     int SetIntProp(char *aProperty, int32_t aValue);
00240 
00242     int GetDblProp(char *aProperty, double *aValue);
00243 
00245     int SetDblProp(char *aProperty, double aValue);
00246 
00248     int GetStrProp(char *aProperty, char **aValue);
00249 
00251     int SetStrProp(char *aProperty, char *aValue);
00252 
00255     template<typename T>
00256     connection_t ConnectReadSignal(T aSubscriber)
00257       {
00258 #ifdef HAVE_BOOST_SIGNALS
00259         scoped_lock_t lock(mPc->mMutex);
00260         return mReadSignal.connect(aSubscriber);
00261 #else
00262         return -1;
00263 #endif
00264       }
00265 
00267     void DisconnectReadSignal(connection_t aSubscriber)
00268       {
00269 #ifdef HAVE_BOOST_SIGNALS
00270         scoped_lock_t lock(mPc->mMutex);
00271         aSubscriber.disconnect();
00272 #else
00273        // This line is here to prevent compiler warnings of "unused varaibles"
00274        aSubscriber = aSubscriber;
00275 #endif
00276       }
00277 
00278 };
00279 
00280 }// namespace
00281 
00282 #endif

Last updated 12 September 2005 21:38:45