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 8022 2009-07-15 03:59:24Z gbiggs $
00046  **************************************************************************/
00047 
00048 
00049 #ifndef PLAYERCC_CLIENTPROXY_H
00050 #define PLAYERCC_CLIENTPROXY_H
00051 
00052 #if defined (WIN32)
00053   #if defined (PLAYER_STATIC)
00054     #define PLAYERCC_EXPORT
00055   #elif defined (playerc___EXPORTS)
00056     #define PLAYERCC_EXPORT    __declspec (dllexport)
00057   #else
00058     #define PLAYERCC_EXPORT    __declspec (dllimport)
00059   #endif
00060 #else
00061   #define PLAYERCC_EXPORT
00062 #endif
00063 
00064 namespace PlayerCc
00065 {
00066 
00079 class PLAYERCC_EXPORT ClientProxy
00080 {
00081   friend class PlayerClient;
00082 
00083   public:
00084 
00085 #ifdef HAVE_BOOST_SIGNALS
00086 
00087 
00088     typedef boost::signals::connection connection_t;
00089 
00091     typedef boost::mutex::scoped_lock scoped_lock_t;
00092 
00094     typedef boost::signal<void (void)> read_signal_t;
00095 #else
00096     // if we're not using boost, just define them.
00097     typedef int connection_t;
00098     // we redefine boost::mustex::scoped_lock in playerclient.h
00099     typedef boost::mutex::scoped_lock scoped_lock_t;
00100     // if we're not using boost, just define them.
00101     typedef int read_signal_t;
00102 #endif
00103 
00104   protected:
00105 
00106     // The ClientProxy constructor
00107     // @attention Potected, so it can only be instantiated by other clients
00108     //
00109     // @throw PlayerError Throws a PlayerError if unable to connect to the client
00110     ClientProxy(PlayerClient* aPc, uint32_t aIndex);
00111 
00112     // destructor will try to close access to the device
00113     virtual ~ClientProxy();
00114 
00115     // Subscribe to the proxy
00116     // This needs to be defined for every proxy.
00117     // @arg aIndex the index of the devce we want to connect to
00118 
00119     // I wish these could be pure virtual,
00120     // but they're used in the constructor/destructor
00121     virtual void Subscribe(uint32_t /*aIndex*/) {};
00122 
00123     // Unsubscribe from the proxy
00124     // This needs to be defined for every proxy.
00125     virtual void Unsubscribe() {};
00126 
00127     // The controlling client object.
00128     PlayerClient* mPc;
00129 
00130     // A reference to the C client
00131     playerc_client_t* mClient;
00132 
00133     // contains convenience information about the device
00134     playerc_device_t *mInfo;
00135 
00136     // if set to true, the current data is "fresh"
00137     bool mFresh;
00138 
00139     // @brief Get a variable from the client
00140     // All Get functions need to use this when accessing data from the
00141     // c library to make sure the data access is thread safe.
00142     template<typename T>
00143     T GetVar(const T &aV) const
00144     { // these have to be defined here since they're templates
00145       scoped_lock_t lock(mPc->mMutex);
00146       T v = aV;
00147       return v;
00148     }
00149 
00150     // @brief Get a variable from the client by reference
00151     // All Get functions need to use this when accessing data from the
00152     // c library to make sure the data access is thread safe.  In this
00153     // case, a begin, end, and destination pointer must be given (similar
00154     // to C++ copy).  It is up to the user to ensure there is memory
00155     // allocated at aDest.
00156     template<typename T>
00157     void GetVarByRef(const T aBegin, const T aEnd, T aDest) const
00158     { // these have to be defined here since they're templates
00159       scoped_lock_t lock(mPc->mMutex);
00160       std::copy(aBegin, aEnd, aDest);
00161     }
00162 
00163   private:
00164 
00165     // The last time that data was read by this client in [s].
00166     double mLastTime;
00167 
00168     // A boost::signal which is used for our callbacks.
00169     // The signal will normally be of a type such as:
00170     // - boost::signal<void ()>
00171     // - boost::signal<void (T)>
00172     // where T can be any type.
00173     //
00174     // @attention we currently only use signals that return void because we
00175     // don't have checks to make sure a signal is registered.  If an empty
00176     // signal is called:
00177     //
00178     // @attention "Calling the function call operator may invoke undefined
00179     // behavior if no slots are connected to the signal, depending on the
00180     // combiner used. The default combiner is well-defined for zero slots when
00181     // the return type is void but is undefined when the return type is any
00182     // other type (because there is no way to synthesize a return value)."
00183     //
00184     read_signal_t mReadSignal;
00185 
00186     // Outputs the signal if there is new data
00187     void ReadSignal();
00188 
00189   public:
00190 
00192     bool IsValid() const { return 0!=GetVar(mInfo->datatime); };
00193 
00197     bool IsFresh() const { return GetVar(mFresh); };
00198 
00200     void NotFresh();
00201 
00204     std::string GetDriverName() const { return mInfo->drivername; };
00205 
00207     double GetDataTime() const { return GetVar(mInfo->datatime); };
00208 
00210     double GetElapsedTime() const
00211       { return GetVar(mInfo->datatime) - GetVar(mInfo->lasttime); };
00212 
00214     PlayerClient * GetPlayerClient() const { return mPc;}
00216     uint32_t GetIndex() const { return GetVar(mInfo->addr.index); };
00217 
00219     uint32_t GetInterface() const { return GetVar(mInfo->addr.interf); };
00220 
00222     std::string GetInterfaceStr() const
00223       { return interf_to_str(GetVar(mInfo->addr.interf)); };
00224 
00238     void SetReplaceRule(bool aReplace,
00239                         int aType = -1,
00240                         int aSubtype = -1);
00241 
00246     int HasCapability(uint32_t aType, uint32_t aSubtype);
00247 
00249     int GetBoolProp(char *aProperty, bool *aValue);
00250 
00252     int SetBoolProp(char *aProperty, bool aValue);
00253 
00255     int GetIntProp(char *aProperty, int32_t *aValue);
00256 
00258     int SetIntProp(char *aProperty, int32_t aValue);
00259 
00261     int GetDblProp(char *aProperty, double *aValue);
00262 
00264     int SetDblProp(char *aProperty, double aValue);
00265 
00267     int GetStrProp(char *aProperty, char **aValue);
00268 
00270     int SetStrProp(char *aProperty, char *aValue);
00271 
00274     template<typename T>
00275     connection_t ConnectReadSignal(T aSubscriber)
00276       {
00277 #ifdef HAVE_BOOST_SIGNALS
00278         scoped_lock_t lock(mPc->mMutex);
00279         return mReadSignal.connect(aSubscriber);
00280 #else
00281         return -1;
00282 #endif
00283       }
00284 
00286     void DisconnectReadSignal(connection_t aSubscriber)
00287       {
00288 #ifdef HAVE_BOOST_SIGNALS
00289         scoped_lock_t lock(mPc->mMutex);
00290         aSubscriber.disconnect();
00291 #else
00292        // This line is here to prevent compiler warnings of "unused varaibles"
00293        aSubscriber = aSubscriber;
00294 #endif
00295       }
00296 
00297 };
00298 
00299 }// namespace
00300 
00301 #endif