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