vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
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
13struct timeval;
15
16class 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
33typedef int(VRPN_CALLBACK *vrpnDeferredUpdateCallback)(void *userdata);
34
35typedef int(VRPN_CALLBACK *vrpnSharedIntCallback)(void *userdata,
36 vrpn_int32 newValue,
37 vrpn_bool isLocal);
38typedef int(VRPN_CALLBACK *vrpnSharedFloatCallback)(void *userdata,
39 vrpn_float64 newValue,
40 vrpn_bool isLocal);
41typedef int(VRPN_CALLBACK *vrpnSharedStringCallback)(void *userdata,
42 const char *newValue,
43 vrpn_bool isLocal);
44
45typedef int(VRPN_CALLBACK *vrpnTimedSharedIntCallback)(void *userdata,
46 vrpn_int32 newValue,
47 timeval when,
48 vrpn_bool isLocal);
49typedef int(VRPN_CALLBACK *vrpnTimedSharedFloatCallback)(void *userdata,
50 vrpn_float64 newValue,
51 timeval when,
52 vrpn_bool isLocal);
53typedef 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
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
125public:
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 vrpn_bool registerDeferredUpdateCallback(vrpnDeferredUpdateCallback,
157 void *userdata);
164
165protected:
166 char *d_name;
167 vrpn_int32 d_mode;
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;
234
235 static int VRPN_CALLBACK handle_gotConnection(void *, vrpn_HANDLERPARAM);
239 static int VRPN_CALLBACK handle_update(void *, vrpn_HANDLERPARAM);
242
243private:
244 void postBindCleanup(void);
245};
246
248
249public:
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 vrpn_bool register_handler(vrpnSharedIntCallback, void *);
268 void unregister_handler(vrpnSharedIntCallback, void *);
269 vrpn_bool 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
279protected:
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.
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
333 int handleUpdate(vrpn_HANDLERPARAM);
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
344public:
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
353protected:
354};
355
357
358public:
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
370public:
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
400protected:
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.
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
440 int handleUpdate(vrpn_HANDLERPARAM);
442};
443
445
446public:
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
455protected:
456};
457
459
460public:
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
472public:
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 vrpn_bool register_handler(vrpnSharedStringCallback, void *);
491 void unregister_handler(vrpnSharedStringCallback, void *);
492 vrpn_bool 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
502protected:
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.
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
542 int handleUpdate(vrpn_HANDLERPARAM);
544};
545
547
548public:
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
557protected:
558};
559
561
562public:
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
Generic connection class not specific to the transport mechanism.
Implements a distributed event clock as defined by Leslie Lamport in some seminal papers I can't find...
Timestamp for a single event, produced by a vrpn_LamportClock and hopefully generally usable in place...
int yankCallbacks(vrpn_bool isLocal)
must set d_lastUpdate BEFORE calling yankCallbacks()
deferredUpdateCallbackEntry * d_deferredUpdateCallbacks
vrpn_int32 d_grantSerializer_type
Sent by the serializer to grant a request.
virtual void sendUpdate(void)=0
Should invoke default sendUpdate() for this derived type.
vrpn_bool d_isNegotiatingSerializer
As long as we have inorder delivery, this should be sufficient to keep us from getting many at once.
vrpn_bool d_queueSets
If this is true, no set()s are processed; instead, they are queued for later execution....
vrpn_int32 d_assumeSerializer_type
Sent by a new serializer once it has been notified that its request has been granted.
vrpn_LamportClock * d_lClock
vrpn_LamportTimestamp * d_lastLamportUpdate
vrpn_bool d_isSerializer
default to vrpn_TRUE for servers, FALSE for remotes
vrpn_int32 d_lamportUpdate_type
vrpn_Connection * d_connection
virtual int handleUpdate(vrpn_HANDLERPARAM)=0
vrpn_int32 d_requestSerializer_type
Sent to the serializer to assume its duties.
static int VRPN_CALLBACK handle_lamportUpdate(void *, vrpn_HANDLERPARAM)
timedCallbackEntry * d_timedCallbacks
callbackEntry * d_callbacks
vrpn_SerializerPolicy d_policy
vrpnSharedStringSerializerPolicy d_policyCallback
vrpn_SerializerPolicy d_policy
callbackEntry * d_callbacks
vrpnSharedFloatSerializerPolicy d_policyCallback
static int VRPN_CALLBACK handle_lamportUpdate(void *, vrpn_HANDLERPARAM)
timedCallbackEntry * d_timedCallbacks
callbackEntry * d_callbacks
vrpn_SerializerPolicy d_policy
vrpnSharedIntSerializerPolicy d_policyCallback
timedCallbackEntry * d_timedCallbacks
This structure is what is passed to a vrpn_Connection message callback.
vrpnTimedSharedStringCallback handler
#define VRPN_API
#define VRPN_CALLBACK
int(VRPN_CALLBACK * vrpnTimedSharedStringCallback)(void *userdata, const char *newValue, timeval when, vrpn_bool isLocal)
int(VRPN_CALLBACK * vrpnTimedSharedFloatCallback)(void *userdata, vrpn_float64 newValue, timeval when, vrpn_bool isLocal)
int(VRPN_CALLBACK * vrpnSharedStringCallback)(void *userdata, const char *newValue, vrpn_bool isLocal)
int(VRPN_CALLBACK * vrpnDeferredUpdateCallback)(void *userdata)
int(VRPN_CALLBACK * vrpnSharedFloatCallback)(void *userdata, vrpn_float64 newValue, vrpn_bool isLocal)
int(VRPN_CALLBACK * vrpnSharedStringSerializerPolicy)(void *userdata, const char *newValue, timeval when, vrpn_Shared_String *object)
int(VRPN_CALLBACK * vrpnSharedIntCallback)(void *userdata, vrpn_int32 newValue, vrpn_bool isLocal)
#define VRPN_SO_DEFAULT
int(VRPN_CALLBACK * vrpnSharedFloatSerializerPolicy)(void *userdata, vrpn_float64 newValue, timeval when, vrpn_Shared_float64 *object)
int(VRPN_CALLBACK * vrpnTimedSharedIntCallback)(void *userdata, vrpn_int32 newValue, timeval when, vrpn_bool isLocal)
vrpn_SerializerPolicy
@ vrpn_DENY_LOCAL
@ vrpn_ACCEPT
@ vrpn_CALLBACK
@ vrpn_DENY_REMOTE
int(VRPN_CALLBACK * vrpnSharedIntSerializerPolicy)(void *userdata, vrpn_int32 newValue, timeval when, vrpn_Shared_int32 *object)