00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _GLASS_PLUGIN_REMOTE_VAR_HH_
00022 #define _GLASS_PLUGIN_REMOVE_VAR_HH_
00023
00024 #include "exception.h"
00025 #include "packager.h"
00026 #include "types.h"
00027 #include "plugin.h"
00028 #include <boost/thread.hpp>
00029 #include <map>
00030 #include <set>
00031
00032 namespace libglass {
00033
00034 class _Remote;
00035
00043 class RemoteBase : public PluginBase {
00044 PLUGIN(RemoteBase);
00045 private:
00046 std::map<const string *, _Remote *, StringPointerCompare>
00047 vars;
00049 protected:
00050 friend class _Remote;
00051
00058 bool registerRemote(_Remote *v);
00059
00066 bool unregisterRemote(_Remote *v);
00067
00068
00069
00070
00071
00072
00073
00074
00075 #if defined(_MSC_VER) && (_MSC_VER < 1300) // earlier than .NET compiler (VC 7.0)
00076 public:
00077 #else
00078 protected:
00079 #endif
00080
00084 virtual ~RemoteBase();
00085
00086
00087 public:
00088 };
00089
00090
00091 #if defined(_MSC_VER)
00092
00093 IMP_TEMPLATE_STL_SET(nodeId);
00094 #endif // _MSC_VER
00095
00101 class LIBGLASS_API _Remote : public PluginInterface {
00102 protected:
00103 friend class RemoteBase;
00104 friend class RemoteVarPacket;
00105
00106 RemoteBase *rb;
00107 string name;
00109
00110 boost::mutex mutex;
00112
00113 std::set<nodeId> owners;
00120 _Remote(const char *name) throw(Exception);
00121
00125 virtual ~_Remote();
00126
00131 virtual chain pack(void);
00132
00139 virtual bool unpack(chain &s, unsigned int &used);
00140
00149 bool _setValue(chain &c, nodeId id);
00150
00159 bool _getValue(chain &c, nodeId id);
00160
00161 public:
00162
00170 bool setValue(nodeId id);
00171
00178 bool getValue(nodeId id);
00179 };
00180
00185 template<typename T,
00186 Serializer(*packf, T) = rawPack<T>,
00187 Unserializer(*unpackf, T) = rawUnpack<T> >
00188 class Remote : public _Remote {
00189 protected:
00190 T data;
00191
00192 chain pack(void) {
00193 chain c;
00194 packf(c, data, 1, NULL);
00195 return c;
00196 }
00197
00198 bool unpack(chain &c, unsigned int &used) {
00199 unsigned int initial;
00200 bool b;
00201
00202
00203
00204 initial = c.find('\0');
00205 if (initial == chain::npos) {
00206 return false;
00207 }
00208 initial++;
00209
00210 mutex.lock();
00211 try {
00212 b = unpackf(c, initial, data, used, 1, NULL);
00213 }
00214 catch (...) {
00215 mutex.unlock();
00216 throw;
00217 }
00218 mutex.unlock();
00219 return b;
00220 }
00221
00222 public:
00228 Remote(const char *name, T data = T()) throw(Exception) : _Remote(name),
00229 data(data) {
00230
00231 }
00232
00239 bool setData(T &b, nodeId id = nobodyId) {
00240 if (id == nobodyId) {
00241 data = b;
00242 return true;
00243 }
00244 else {
00245 chain c;
00246 packf(c, b);
00247 return _setValue(c, id);
00248 }
00249 }
00250
00258 const T &getData(nodeId id = nobodyId) const throw(Exception) {
00259 if (id == nobodyId) {
00260 return data;
00261 }
00262 else {
00263 chain c;
00264 unsigned int used;
00265
00266 if (!_getValue(c, id)) {
00267 throw Exception("Could not get remote value.");
00268 }
00269 return unpack(c, used);
00270 }
00271 }
00272
00277 T &operator*(void) const {
00278 return data;
00279 }
00280
00287 void lock(void) {
00288 mutex.lock();
00289 }
00290
00294 void unlock(void) {
00295 mutex.unlock();
00296 }
00297 };
00298
00299 }
00300
00301
00302
00303 #endif // _GLASS_PLUGIN_REMOTE_VAR_HH_