vrpn  07.33
Virtual Reality Peripheral Network
vrpn_SharedObject.h
Go to the documentation of this file.
1 #ifndef VRPN_SHARED_OBJECT
2 #define VRPN_SHARED_OBJECT
3 
4 #include <stddef.h> // for NULL
5 
6 #include "vrpn_Configure.h" // for VRPN_CALLBACK, VRPN_API
7 // This *must* be here to take care of winsock2.h and sys/time.h and other
8 // assorted system-dependent details.
9 #include "vrpn_Shared.h" // for timeval
10 #include "vrpn_Types.h" // for vrpn_int32, vrpn_bool, etc
11 
13 struct timeval;
14 struct vrpn_HANDLERPARAM;
15 
16 class VRPN_API vrpn_LamportClock; // from "vrpn_LamportClock.h"
18 
19 // It's increasingly clear that we could handle all this with
20 // a template, except for the fact that vrpn_Shared_String is
21 // based on char *. All we need is a String base class.
22 // We could try to adopt BCString from nano's libnmb...
23 
24 // I'd like to implement shouldAcceptUpdate/shouldSendUpdate
25 // with the Strategy pattern (Gamma/Helm/Johnson/Vlissides 1995, pg 315).
26 // That would make it far, far easier to extend, but the implementation
27 // looks too unweildy.
28 
32 
33 typedef int(VRPN_CALLBACK *vrpnDeferredUpdateCallback)(void *userdata);
34 
35 typedef int(VRPN_CALLBACK *vrpnSharedIntCallback)(void *userdata,
36  vrpn_int32 newValue,
37  vrpn_bool isLocal);
38 typedef int(VRPN_CALLBACK *vrpnSharedFloatCallback)(void *userdata,
39  vrpn_float64 newValue,
40  vrpn_bool isLocal);
41 typedef int(VRPN_CALLBACK *vrpnSharedStringCallback)(void *userdata,
42  const char *newValue,
43  vrpn_bool isLocal);
44 
45 typedef int(VRPN_CALLBACK *vrpnTimedSharedIntCallback)(void *userdata,
46  vrpn_int32 newValue,
47  timeval when,
48  vrpn_bool isLocal);
49 typedef int(VRPN_CALLBACK *vrpnTimedSharedFloatCallback)(void *userdata,
50  vrpn_float64 newValue,
51  timeval when,
52  vrpn_bool isLocal);
53 typedef int(VRPN_CALLBACK *vrpnTimedSharedStringCallback)(void *userdata,
54  const char *newValue,
55  timeval when,
56  vrpn_bool isLocal);
57 
58 // Update callbacks should return 0 on successful completion,
59 // nonzero on error (which will prevent further update callbacks
60 // from being invoked).
61 
63  void *userdata, vrpn_int32 newValue, timeval when,
64  vrpn_Shared_int32 *object);
66  void *userdata, vrpn_float64 newValue, timeval when,
67  vrpn_Shared_float64 *object);
69  void *userdata, const char *newValue, timeval when,
70  vrpn_Shared_String *object);
71 
72 // Policy callbacks should return 0 if the update should be accepted,
73 // nonzero if it should be denied.
74 
75 #define VRPN_SO_DEFAULT 0x00
76 #define VRPN_SO_IGNORE_IDEMPOTENT 0x01
77 #define VRPN_SO_DEFER_UPDATES 0x10
78 #define VRPN_SO_IGNORE_OLD 0x100
79 
80 // Each of these flags can be passed to all vrpn_Shared_* constructors.
81 // If VRPN_SO_IGNORE_IDEMPOTENT is used, calls of operator = (v) or set(v)
82 // are *ignored* if v == d_value. No callbacks are called, no network
83 // traffic takes place.
84 // If VRPN_SO_DEFER_UPDATES is used, calls of operator = (v) or set(v)
85 // on vrpn_Shared_*_Remote are sent to the server but not reflected
86 // locally until an update message is received from the server.
87 // If VRPN_SO_IGNORE_OLD is set, calls of set(v, t) are ignored if
88 // t < d_lastUpdate. This includes messages propagated over the network.
89 
90 // A vrpn_Shared_*_Server/Remote pair using VRPN_SO_IGNORE_OLD are
91 // guaranteed to reach the same final state - after quiescence (all messages
92 // sent on the network are delivered) they will yield the same value(),
93 // but they are *not* guaranteed to go through the same sequence of
94 // callbacks.
95 
96 // Using VRPN_SO_DEFER_UPDATES serializes all changes to d_value and
97 // all callbacks, so it guarantees that all instances of the shared
98 // variable see the same sequence of callbacks.
99 
100 // setSerializerPolicy() can be used to change the way VRPN_SO_DEFER_UPDATES
101 // operates. The default value described above is equivalent to calling
102 // setSerializerPolicy(vrpn_ACCEPT). Also possible are vrpn_DENY_REMOTE,
103 // which causes the serializer to ignore all updates from its peers,
104 // vrpn_DENY_LOCAL, which accepts updates from peers but ignores local
105 // updates,
106 // and vrpn_CALLBACK, which passes the update to a callback which can
107 // return zero for vrpn_ACCEPT or nonzero for vrpn_DENY.
108 
114 };
115 
116 // Separated out vrpn_SharedObject from common behavior of 3 classes
117 // on 14 Feb 2000. Now all we need is permission to use templates to
118 // collapse them all together; *all* the functions remaining on the
119 // other classes are type-dependent and should be templatable.
120 // (One exception: the string that names the type. This could probably
121 // be cut.)
122 
124 
125 public:
126  vrpn_SharedObject(const char *name, const char *tname, vrpn_int32 mode);
127  virtual ~vrpn_SharedObject(void);
128 
129  // ACCESSORS
130 
131  const char *name(void) const;
132  vrpn_bool isSerializer(void) const;
133 
134  // MANIPULATORS
135 
136  virtual void bindConnection(vrpn_Connection *);
140 
141  void useLamportClock(vrpn_LamportClock *);
146 
147  void becomeSerializer(void);
155 
156  void registerDeferredUpdateCallback(vrpnDeferredUpdateCallback,
157  void *userdata);
164 
165 protected:
166  char *d_name;
167  vrpn_int32 d_mode;
168  timeval d_lastUpdate;
169  char *d_typename; // currently int32, float64, or String
170 
172  // vrpn_int32 d_updateFromServer_type;
173  // vrpn_int32 d_updateFromRemote_type;
174  // vrpn_int32 d_myUpdate_type; // fragile
175  vrpn_int32 d_serverId;
176  vrpn_int32 d_remoteId;
177  vrpn_int32 d_myId; // fragile
178  vrpn_int32 d_peerId; // fragile
179  vrpn_int32 d_update_type;
180 
188 
189  // vrpn_int32 d_updateFromServerLamport_type;
190  // vrpn_int32 d_updateFromRemoteLamport_type;
192 
193  vrpn_bool d_isSerializer;
198 
199  virtual vrpn_bool shouldSendUpdate(vrpn_bool isLocalSet,
200  vrpn_bool acceptedUpdate);
201 
202  int yankCallbacks(vrpn_bool isLocal);
204 
205  static int VRPN_CALLBACK
206  handle_requestSerializer(void *, vrpn_HANDLERPARAM);
207  static int VRPN_CALLBACK handle_grantSerializer(void *, vrpn_HANDLERPARAM);
208  static int VRPN_CALLBACK handle_assumeSerializer(void *, vrpn_HANDLERPARAM);
209 
210  vrpn_bool d_queueSets;
214 
217 
220  void *userdata;
222  };
224 
225  int yankDeferredUpdateCallbacks(void);
227 
228  void serverPostBindCleanup(void);
229  void remotePostBindCleanup(void);
230 
231  virtual void sendUpdate(void) = 0;
233  virtual int handleUpdate(vrpn_HANDLERPARAM) = 0;
234 
235  static int VRPN_CALLBACK handle_gotConnection(void *, vrpn_HANDLERPARAM);
239  static int VRPN_CALLBACK handle_update(void *, vrpn_HANDLERPARAM);
242 
243 private:
244  void postBindCleanup(void);
245 };
246 
248 
249 public:
250  vrpn_Shared_int32(const char *name, vrpn_int32 defaultValue = 0,
251  vrpn_int32 mode = VRPN_SO_DEFAULT);
252  virtual ~vrpn_Shared_int32(void);
253 
254  // ACCESSORS
255 
256  vrpn_int32 value(void) const;
257  operator vrpn_int32() const;
258 
259  // MANIPULATORS
260 
261  vrpn_Shared_int32 &operator=(vrpn_int32 newValue);
262  // calls set(newValue, now);
263 
264  vrpn_Shared_int32 &set(vrpn_int32 newValue, timeval when);
265  // calls protected set (newValue, when, vrpn_TRUE);
266 
267  void register_handler(vrpnSharedIntCallback, void *);
268  void unregister_handler(vrpnSharedIntCallback, void *);
269  void register_handler(vrpnTimedSharedIntCallback, void *);
270  void unregister_handler(vrpnTimedSharedIntCallback, void *);
271  // Callbacks are (currently) called *AFTER* the assignment
272  // has been made, so any check of the value of their shared int
273  // will return newValue
274 
275  void setSerializerPolicy(vrpn_SerializerPolicy policy = vrpn_ACCEPT,
277  void *userdata = NULL);
278 
279 protected:
280  vrpn_int32 d_value;
281 
282  // callback code
283  // Could generalize this by making a class that gets passed
284  // a vrpn_HANDLERPARAM and passes whatever is needed to its callback,
285  // but it's not worth doing that unless we need a third or fourth
286  // kind of callback.
287  struct callbackEntry {
289  void *userdata;
291  };
295  void *userdata;
297  };
299 
300  vrpn_Shared_int32 &set(vrpn_int32, timeval, vrpn_bool isLocalSet,
301  vrpn_LamportTimestamp * = NULL);
302 
303  virtual vrpn_bool shouldAcceptUpdate(vrpn_int32 newValue, timeval when,
304  vrpn_bool isLocalSet,
306 
307  virtual void sendUpdate(void);
308  void sendUpdate(vrpn_int32 newValue, timeval when);
309 
310  void encode(char **buffer, vrpn_int32 *len, vrpn_int32 newValue,
311  timeval when) const;
312  void encodeLamport(char **buffer, vrpn_int32 *len, vrpn_int32 newValue,
313  timeval when, vrpn_LamportTimestamp *t) const;
314  // We used to have sendUpdate() and encode() just read off of
315  // d_value and d_lastUpdate, but that doesn't work when we're
316  // serializing (VRPN_SO_DEFER_UPDATES), because we don't want
317  // to change the local values but do want to send the new values
318  // to the serializer.
319  void decode(const char **buffer, vrpn_int32 *len, vrpn_int32 *newValue,
320  timeval *when) const;
321  void decodeLamport(const char **buffer, vrpn_int32 *len,
322  vrpn_int32 *newValue, timeval *when,
323  vrpn_LamportTimestamp **t) const;
324 
325  int yankCallbacks(vrpn_bool isLocal);
326  // must set d_lastUpdate BEFORE calling yankCallbacks()
327 
328  // serializer policy code
329  vrpn_SerializerPolicy d_policy; // default to vrpn_ACCEPT
332 
334 
335  static int VRPN_CALLBACK handle_lamportUpdate(void *, vrpn_HANDLERPARAM);
336 };
337 
338 // I don't think the derived classes should have to have operator = ()
339 // defined (they didn't in the last version??), but both SGI and HP
340 // compilers seem to insist on it.
341 
343 
344 public:
345  vrpn_Shared_int32_Server(const char *name, vrpn_int32 defaultValue = 0,
346  vrpn_int32 defaultMode = VRPN_SO_DEFAULT);
347  virtual ~vrpn_Shared_int32_Server(void);
348 
349  vrpn_Shared_int32_Server &operator=(vrpn_int32 newValue);
350 
351  virtual void bindConnection(vrpn_Connection *);
352 
353 protected:
354 };
355 
357 
358 public:
359  vrpn_Shared_int32_Remote(const char *name, vrpn_int32 defaultValue = 0,
360  vrpn_int32 defaultMode = VRPN_SO_DEFAULT);
361  virtual ~vrpn_Shared_int32_Remote(void);
362 
363  vrpn_Shared_int32_Remote &operator=(vrpn_int32 newValue);
364 
365  virtual void bindConnection(vrpn_Connection *);
366 };
367 
369 
370 public:
371  vrpn_Shared_float64(const char *name, vrpn_float64 defaultValue = 0.0,
372  vrpn_int32 mode = VRPN_SO_DEFAULT);
373  virtual ~vrpn_Shared_float64(void);
374 
375  // ACCESSORS
376 
377  vrpn_float64 value(void) const;
378  operator vrpn_float64() const;
379 
380  // MANIPULATORS
381 
382  vrpn_Shared_float64 &operator=(vrpn_float64 newValue);
383  // calls set(newValue, now);
384 
385  virtual vrpn_Shared_float64 &set(vrpn_float64 newValue, timeval when);
386  // calls protected set (newValue, when, vrpn_TRUE);
387 
388  void register_handler(vrpnSharedFloatCallback, void *);
389  void unregister_handler(vrpnSharedFloatCallback, void *);
390  void register_handler(vrpnTimedSharedFloatCallback, void *);
391  void unregister_handler(vrpnTimedSharedFloatCallback, void *);
392  // Callbacks are (currently) called *AFTER* the assignment
393  // has been made, so any check of the value of their shared int
394  // will return newValue
395 
396  void setSerializerPolicy(vrpn_SerializerPolicy policy = vrpn_ACCEPT,
398  void *userdata = NULL);
399 
400 protected:
401  vrpn_float64 d_value;
402 
403  // callback code
404  // Could generalize this by making a class that gets passed
405  // a vrpn_HANDLERPARAM and passes whatever is needed to its callback,
406  // but it's not worth doing that unless we need a third or fourth
407  // kind of callback.
408  struct callbackEntry {
410  void *userdata;
412  };
416  void *userdata;
418  };
420 
421  vrpn_SerializerPolicy d_policy; // default to vrpn_ACCEPT
424 
425  vrpn_Shared_float64 &set(vrpn_float64, timeval, vrpn_bool isLocalSet);
426 
427  virtual vrpn_bool shouldAcceptUpdate(vrpn_float64 newValue, timeval when,
428  vrpn_bool isLocalSet);
429 
430  virtual void sendUpdate(void);
431  void sendUpdate(vrpn_float64 newValue, timeval when);
432  void encode(char **buffer, vrpn_int32 *len, vrpn_float64 newValue,
433  timeval when) const;
434  void decode(const char **buffer, vrpn_int32 *len, vrpn_float64 *newValue,
435  timeval *when) const;
436 
437  int yankCallbacks(vrpn_bool isLocal);
438  // must set d_lastUpdate BEFORE calling yankCallbacks()
439 
441  static int VRPN_CALLBACK handle_lamportUpdate(void *, vrpn_HANDLERPARAM);
442 };
443 
445 
446 public:
447  vrpn_Shared_float64_Server(const char *name, vrpn_float64 defaultValue = 0,
448  vrpn_int32 defaultMode = VRPN_SO_DEFAULT);
449  virtual ~vrpn_Shared_float64_Server(void);
450 
451  vrpn_Shared_float64_Server &operator=(vrpn_float64 newValue);
452 
453  virtual void bindConnection(vrpn_Connection *);
454 
455 protected:
456 };
457 
459 
460 public:
461  vrpn_Shared_float64_Remote(const char *name, vrpn_float64 defaultValue = 0,
462  vrpn_int32 defaultMode = VRPN_SO_DEFAULT);
463  virtual ~vrpn_Shared_float64_Remote(void);
464 
465  vrpn_Shared_float64_Remote &operator=(vrpn_float64 newValue);
466 
467  virtual void bindConnection(vrpn_Connection *);
468 };
469 
471 
472 public:
473  vrpn_Shared_String(const char *name, const char *defaultValue = NULL,
474  vrpn_int32 mode = VRPN_SO_DEFAULT);
475  virtual ~vrpn_Shared_String(void);
476 
477  // ACCESSORS
478 
479  const char *value(void) const;
480  operator const char *() const;
481 
482  // MANIPULATORS
483 
484  vrpn_Shared_String &operator=(const char *newValue);
485  // calls set(newValue, now);
486 
487  virtual vrpn_Shared_String &set(const char *newValue, timeval when);
488  // calls protected set (newValue, when, vrpn_TRUE);
489 
490  void register_handler(vrpnSharedStringCallback, void *);
491  void unregister_handler(vrpnSharedStringCallback, void *);
492  void register_handler(vrpnTimedSharedStringCallback, void *);
493  void unregister_handler(vrpnTimedSharedStringCallback, void *);
494  // Callbacks are (currently) called *AFTER* the assignment
495  // has been made, so any check of the value of their shared int
496  // will return newValue
497 
498  void setSerializerPolicy(vrpn_SerializerPolicy policy = vrpn_ACCEPT,
500  void *userdata = NULL);
501 
502 protected:
503  char *d_value;
504 
505  // callback code
506  // Could generalize this by making a class that gets passed
507  // a vrpn_HANDLERPARAM and passes whatever is needed to its callback,
508  // but it's not worth doing that unless we need a third or fourth
509  // kind of callback.
510  struct callbackEntry {
512  void *userdata;
514  };
518  void *userdata;
520  };
522 
523  vrpn_SerializerPolicy d_policy; // default to vrpn_ACCEPT
526 
527  vrpn_Shared_String &set(const char *, timeval, vrpn_bool isLocalSet);
528 
529  virtual vrpn_bool shouldAcceptUpdate(const char *newValue, timeval when,
530  vrpn_bool isLocalSet);
531 
532  virtual void sendUpdate(void);
533  void sendUpdate(const char *newValue, timeval when);
534  void encode(char **buffer, vrpn_int32 *len, const char *newValue,
535  timeval when) const;
536  void decode(const char **buffer, vrpn_int32 *len, char *newValue,
537  timeval *when) const;
538 
539  int yankCallbacks(vrpn_bool isLocal);
540  // must set d_lastUpdate BEFORE calling yankCallbacks()
541 
543  static int VRPN_CALLBACK handle_lamportUpdate(void *, vrpn_HANDLERPARAM);
544 };
545 
547 
548 public:
549  vrpn_Shared_String_Server(const char *name, const char *defaultValue = NULL,
550  vrpn_int32 defaultMode = VRPN_SO_DEFAULT);
551  virtual ~vrpn_Shared_String_Server(void);
552 
553  vrpn_Shared_String_Server &operator=(const char *);
554 
555  virtual void bindConnection(vrpn_Connection *);
556 
557 protected:
558 };
559 
561 
562 public:
563  vrpn_Shared_String_Remote(const char *name, const char *defaultValue = NULL,
564  vrpn_int32 defaultMode = VRPN_SO_DEFAULT);
565  virtual ~vrpn_Shared_String_Remote(void);
566 
567  vrpn_Shared_String_Remote &operator=(const char *);
568 
569  virtual void bindConnection(vrpn_Connection *);
570 };
571 
572 #endif // VRPN_SHARED_OBJECT
virtual void sendUpdate(void)=0
Should invoke default sendUpdate() for this derived type.
int(VRPN_CALLBACK * vrpnTimedSharedStringCallback)(void *userdata, const char *newValue, timeval when, vrpn_bool isLocal)
vrpn_Shared_String & operator=(const char *newValue)
Implements a distributed event clock as defined by Leslie Lamport in some seminal papers I can&#39;t find...
class VRPN_API vrpn_Shared_String
vrpn_bool d_isSerializer
default to vrpn_TRUE for servers, FALSE for remotes
int(VRPN_CALLBACK * vrpnSharedIntCallback)(void *userdata, vrpn_int32 newValue, vrpn_bool isLocal)
vrpnTimedSharedIntCallback handler
class VRPN_API vrpn_Shared_int32
int(VRPN_CALLBACK * vrpnSharedFloatSerializerPolicy)(void *userdata, vrpn_float64 newValue, timeval when, vrpn_Shared_float64 *object)
int(VRPN_CALLBACK * vrpnTimedSharedFloatCallback)(void *userdata, vrpn_float64 newValue, timeval when, vrpn_bool isLocal)
#define VRPN_SO_DEFAULT
vrpn_SerializerPolicy d_policy
vrpn_LamportClock * d_lClock
vrpn_Shared_float64 & operator=(vrpn_float64 newValue)
vrpn_int32 d_grantSerializer_type
Sent by the serializer to grant a request.
callbackEntry * d_callbacks
int(VRPN_CALLBACK * vrpnSharedFloatCallback)(void *userdata, vrpn_float64 newValue, vrpn_bool isLocal)
vrpn_bool d_isNegotiatingSerializer
As long as we have inorder delivery, this should be sufficient to keep us from getting many at once...
Generic connection class not specific to the transport mechanism.
class VRPN_API vrpn_Shared_float64
vrpn_bool d_queueSets
If this is true, no set()s are processed; instead, they are queued for later execution. NOT IMPLEMENTED.
vrpnTimedSharedStringCallback handler
#define VRPN_CALLBACK
vrpn_SerializerPolicy
#define VRPN_API
vrpnSharedIntSerializerPolicy d_policyCallback
vrpn_Connection * d_connection
int(VRPN_CALLBACK * vrpnSharedIntSerializerPolicy)(void *userdata, vrpn_int32 newValue, timeval when, vrpn_Shared_int32 *object)
Timestamp for a single event, produced by a vrpn_LamportClock and hopefully generally usable in place...
vrpnSharedStringCallback handler
deferredUpdateCallbackEntry * d_deferredUpdateCallbacks
int yankCallbacks(vrpn_bool isLocal)
must set d_lastUpdate BEFORE calling yankCallbacks()
This structure is what is passed to a vrpn_Connection message callback.
int(VRPN_CALLBACK * vrpnSharedStringSerializerPolicy)(void *userdata, const char *newValue, timeval when, vrpn_Shared_String *object)
timedCallbackEntry * d_timedCallbacks
timedCallbackEntry * d_timedCallbacks
vrpn_LamportTimestamp * d_lastLamportUpdate
vrpn_int32 d_assumeSerializer_type
Sent by a new serializer once it has been notified that its request has been granted.
vrpn_SerializerPolicy d_policy
vrpnSharedFloatSerializerPolicy d_policyCallback
virtual int handleUpdate(vrpn_HANDLERPARAM)=0
int(VRPN_CALLBACK * vrpnDeferredUpdateCallback)(void *userdata)
vrpn_int32 d_requestSerializer_type
Sent to the serializer to assume its duties.
vrpnTimedSharedFloatCallback handler
vrpnSharedStringSerializerPolicy d_policyCallback
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
int(VRPN_CALLBACK * vrpnSharedStringCallback)(void *userdata, const char *newValue, vrpn_bool isLocal)
vrpn_SerializerPolicy d_policy
vrpn_int32 d_lamportUpdate_type
timedCallbackEntry * d_timedCallbacks
vrpn_Shared_int32 & operator=(vrpn_int32 newValue)
int(VRPN_CALLBACK * vrpnTimedSharedIntCallback)(void *userdata, vrpn_int32 newValue, timeval when, vrpn_bool isLocal)
callbackEntry * d_callbacks
callbackEntry * d_callbacks