vrpn  07.33
Virtual Reality Peripheral Network
vrpn_SharedObject.C
Go to the documentation of this file.
1 #include <stdio.h> // for fprintf, stderr, sprintf
2 #include <string.h> // for NULL, strcpy, strlen, etc
3 
4 #include "vrpn_Connection.h" // for vrpn_Connection, etc
5 #include "vrpn_LamportClock.h" // for vrpn_LamportTimestamp, etc
6 #include "vrpn_SharedObject.h"
7 
8 struct timeval;
9 
10 // We can't put d_lastUpdate in the message header timestamps; it must
11 // go in the body.
12 // This is because we're (probably) using a synchronized connection,
13 // and VRPN clock sync munges these timestamps.
14 // If we send a message from A to B and it gets sent back to A, attempting
15 // to preserve the timestamp at both ends, but sending it over a synchronized
16 // connection, its timestamp will end up equal to the original timestamp
17 // PLUS the network RTT (round-trip time).
18 // The original design intent of a vrpn_SharedObject was to be able to use
19 // timestamps as message identifiers/sequencers, so they need to be invariant
20 // over several network hops.
21 
22 // Note on Lamport clocks: the implementation was never completed
23 // (see vrpn_LamportClock.[C,h]), so it's use here has been disabled in the
24 // following ways. First, the code that considers the Lamport clock
25 // in vrpn_Shared_int32::shouldAcceptUpdates(...) is commented out
26 // (the other shared objects, float64 and String, never had code to
27 // consider the Lamport clock). Second, the body of the method
28 // vrpn_SharedObject::useLamportClock is commented out so that a
29 // Lamport clock is never started.
30 
31 vrpn_SharedObject::vrpn_SharedObject(const char *name, const char *tname,
32  vrpn_int32 mode)
33  : d_name(name ? new char[1 + strlen(name)] : NULL)
34  , d_mode(mode)
35  , d_typename(tname ? new char[1 + strlen(tname)] : NULL)
36  , d_connection(NULL)
37  , d_serverId(-1)
38  , d_remoteId(-1)
39  , d_myId(-1)
40  , d_peerId(-1)
41  , d_update_type(-1)
42  , d_requestSerializer_type(-1)
43  , d_grantSerializer_type(-1)
44  , d_assumeSerializer_type(-1)
45  , d_lamportUpdate_type(-1)
46  , d_isSerializer(vrpn_TRUE)
47  , d_isNegotiatingSerializer(vrpn_FALSE)
48  , d_queueSets(vrpn_FALSE)
49  , d_lClock(NULL)
50  , d_lastLamportUpdate(NULL)
51  , d_deferredUpdateCallbacks(NULL)
52 {
53 
54  if (name) {
55  strcpy(d_name, name);
56  }
57  if (tname) {
58  strcpy(d_typename, tname);
59  }
61 }
62 
63 // virtual
65 {
66  vrpn_int32 gotConnection_type;
67 
68  if (d_name) {
69  delete[] d_name;
70  }
71  if (d_typename) {
72  delete[] d_typename;
73  }
74  if (d_connection) {
76  d_peerId);
83 
84  gotConnection_type =
86  d_connection->unregister_handler(gotConnection_type,
88 
90  }
91 }
92 
93 const char *vrpn_SharedObject::name(void) const { return d_name; }
94 
95 vrpn_bool vrpn_SharedObject::isSerializer(void) const { return VRPN_TRUE; }
96 
97 // virtual
99 {
100  char buffer[101];
101  if (c == NULL) {
102  // unbind the connection
103  if (d_connection) {
105  }
106  d_connection = NULL;
107  return;
108  }
109 
110  if (c && d_connection) {
111  fprintf(stderr, "vrpn_SharedObject::bindConnection: "
112  "Tried to rebind a connection to %s.\n",
113  d_name);
114  return;
115  }
116 
117  d_connection = c;
118  c->addReference();
119  sprintf(buffer, "vrpn Shared server %s %s", d_typename, d_name);
120  d_serverId = c->register_sender(buffer);
121  sprintf(buffer, "vrpn Shared peer %s %s", d_typename, d_name);
122  d_remoteId = c->register_sender(buffer);
123  // d_updateFromServer_type = c->register_message_type
124  //("vrpn_Shared update_from_server");
125  // d_updateFromRemote_type = c->register_message_type
126  //("vrpn_Shared update_from_remote");
127  d_update_type = c->register_message_type("vrpn_Shared update");
128 
129  // fprintf (stderr, "My name is %s; myId %d, ufs type %d, ufr type %d.\n",
130  // buffer, d_myId, d_updateFromServer_type, d_updateFromRemote_type);
131 
133  c->register_message_type("vrpn_Shared request_serializer");
135  c->register_message_type("vrpn_Shared grant_serializer");
137  c->register_message_type("vrpn_Shared assume_serializer");
138 }
139 
141 {
142 
143  // NOTE: this is disabled
144  // d_lClock = l;
145 }
146 
148 {
149  timeval now;
150 
151  // Make sure only one request is outstanding
152 
154  return;
155  }
156 
157  d_isNegotiatingSerializer = vrpn_TRUE;
158 
159  // send requestSerializer
160 
161  if (d_connection) {
162  vrpn_gettimeofday(&now, NULL);
165  }
166 
167  // fprintf(stderr, "sent requestSerializer\n");
168 }
169 
171  vrpnDeferredUpdateCallback cb, void *userdata)
172 {
174 
176  if (!x) {
177  fprintf(stderr, "vrpn_SharedObject::registerDeferredUpdateCallback: "
178  "Out of memory!\n");
179  return;
180  }
181 
182  x->handler = cb;
183  x->userdata = userdata;
186 }
187 
188 // virtual
189 vrpn_bool vrpn_SharedObject::shouldSendUpdate(vrpn_bool isLocalSet,
190  vrpn_bool acceptedUpdate)
191 {
192 
193  // fprintf(stderr, "In vrpn_SharedObject::shouldSendUpdate(%s).\n", d_name);
194 
195  // Should handle all modes other than VRPN_SO_DEFER_UPDATES.
196  if (acceptedUpdate && isLocalSet) {
197  // fprintf(stderr, "..... accepted; local set => broadcast it.\n");
198  return vrpn_TRUE;
199  }
200 
201  // Not a local set or (not accepted and not serializing)
202  if (!(d_mode & VRPN_SO_DEFER_UPDATES)) {
203  // fprintf(stderr, "..... rejected (NOT serialized).\n");
204  return vrpn_FALSE;
205  }
206 
207  if (!d_isSerializer && isLocalSet) {
208  // fprintf(stderr, "..... not serializer; local set "
209  //"=> send it to the serializer.\n");
210  return vrpn_TRUE;
211  }
212 
213  if (d_isSerializer && !isLocalSet && acceptedUpdate) {
214  // fprintf(stderr, "..... serializer; remote set; accepted =>
215  // broadcast it.\n");
216  return vrpn_TRUE;
217  }
218 
219  // fprintf(stderr,"..... rejected (under serialization).\n");
220  return vrpn_FALSE;
221 }
222 
223 // static
226 {
227  vrpn_SharedObject *s = (vrpn_SharedObject *)userdata;
228  timeval now;
229 
230  if (!s->isSerializer() || s->d_isNegotiatingSerializer) {
231  // ignore this
232  // we should probably return failure or error?
233  return 0;
234  }
235 
236  s->d_isNegotiatingSerializer = vrpn_TRUE;
237 
238  if (s->d_connection) {
239 
240  // Don't set d_isSerializer to FALSE until they've assumed it.
241  // Until then, retain the serializer status but queue all of our
242  // messages; when they finish becoming the serializer, we
243  // set our flag to false and send the queue of set()s we've
244  // received to them.
245 
246  // send grantSerializer
247 
248  vrpn_gettimeofday(&now, NULL);
252  }
253 
254  // start queueing set()s
255 
256  s->d_queueSets = vrpn_TRUE;
257 
258  // fprintf(stderr, "sent grantSerializer\n");
259  return 0;
260 }
261 
262 // static
264 {
265  vrpn_SharedObject *s = (vrpn_SharedObject *)userdata;
266  timeval now;
267 
268  s->d_isSerializer = vrpn_TRUE;
269  s->d_isNegotiatingSerializer = vrpn_FALSE;
270 
271  // send assumeSerializer
272 
273  if (s->d_connection) {
274  vrpn_gettimeofday(&now, NULL);
278  }
279 
280  // fprintf(stderr, "sent assumeSerializer\n");
281  return 0;
282 }
283 
284 // static
287 {
288  vrpn_SharedObject *s = (vrpn_SharedObject *)userdata;
289 
290  s->d_isSerializer = vrpn_FALSE;
291  s->d_isNegotiatingSerializer = vrpn_FALSE;
292 
293  // TODO: send queued set()s
294 
295  return 0;
296 }
297 
299 {
301 
302  for (x = d_deferredUpdateCallbacks; x; x = x->next) {
303  if ((x->handler)(x->userdata)) {
304  return -1;
305  }
306  }
307 
308  return 0;
309 }
310 
312 {
313  d_myId = d_serverId;
315  postBindCleanup();
316 }
317 
319 {
320  d_myId = d_remoteId;
322  postBindCleanup();
323 }
324 
325 // static
327 {
328  vrpn_SharedObject *s = (vrpn_SharedObject *)userdata;
329 
330  // Send an update to the remote so that they have the correct
331  // initial value for our state. Otherwise an attempt to synchronize
332  // something will assume we're at our initial value until our value
333  // changes, which is an error.
334 
335  if (s->d_isSerializer) {
336  s->sendUpdate();
337  // fprintf(stderr, "%s: set client's value.\n", s->d_name);
338  }
339  else if (!(s->d_mode & VRPN_SO_DEFER_UPDATES) &&
340  (s->d_myId == s->d_serverId)) {
341  s->sendUpdate();
342  // fprintf(stderr, "%s: set remote's value.\n", s->d_name);
343  }
344 
345  return 0;
346 }
347 
348 // static
350 {
351  vrpn_SharedObject *s = (vrpn_SharedObject *)userdata;
352 
353  return s->handleUpdate(p);
354 }
355 
356 void vrpn_SharedObject::postBindCleanup(void)
357 {
358  vrpn_int32 gotConnection_type;
359 
360  if (!d_connection) {
361  return;
362  }
363 
364  // listen for update
365 
367  d_peerId);
368 
369  // listen for request/grant/assumeSerializer
370 
377 
378  gotConnection_type =
381  this, d_myId);
382 }
383 
384 vrpn_Shared_int32::vrpn_Shared_int32(const char *name, vrpn_int32 defaultValue,
385  vrpn_int32 mode)
386  : vrpn_SharedObject(name, "int32", mode)
387  , d_value(defaultValue)
388  , d_callbacks(NULL)
389  , d_timedCallbacks(NULL)
390  , d_policy(vrpn_ACCEPT)
391  , d_policyCallback(NULL)
392  , d_policyUserdata(NULL)
393 {
394 }
395 
396 // virtual
398 {
399  // if (d_connection) {
400  // d_connection->unregister_handler(d_becomeSerializer_type,
401  // handle_becomeSerializer, this, d_myId);
402  //}
403 }
404 
405 vrpn_int32 vrpn_Shared_int32::value(void) const { return d_value; }
406 
407 vrpn_Shared_int32::operator vrpn_int32() const { return value(); }
408 
410 {
411  struct timeval now;
412  vrpn_gettimeofday(&now, NULL);
413  return set(newValue, now);
414 }
415 
416 vrpn_Shared_int32 &vrpn_Shared_int32::set(vrpn_int32 newValue, timeval when)
417 {
418  return set(newValue, when, vrpn_TRUE);
419 }
421  void *userdata)
422 {
423  callbackEntry *e = new callbackEntry;
424  if (!e) {
425  fprintf(stderr, "vrpn_Shared_int32::register_handler: "
426  "Out of memory.\n");
427  return;
428  }
429  e->handler = cb;
430  e->userdata = userdata;
431  e->next = d_callbacks;
432  d_callbacks = e;
433 }
434 
436  void *userdata)
437 {
438  callbackEntry *e, **snitch;
439 
440  snitch = &d_callbacks;
441  e = *snitch;
442  while (e && (e->handler != cb) && (e->userdata != userdata)) {
443  snitch = &(e->next);
444  e = *snitch;
445  }
446  if (!e) {
447  fprintf(stderr, "vrpn_Shared_int32::unregister_handler: "
448  "Handler not found.\n");
449  return;
450  }
451 
452  *snitch = e->next;
453  delete e;
454 }
455 
457  void *userdata)
458 {
460  if (!e) {
461  fprintf(stderr, "vrpn_Shared_int32::register_handler: "
462  "Out of memory.\n");
463  return;
464  }
465  e->handler = cb;
466  e->userdata = userdata;
467  e->next = d_timedCallbacks;
468  d_timedCallbacks = e;
469 }
470 
472  void *userdata)
473 {
474  timedCallbackEntry *e, **snitch;
475 
476  snitch = &d_timedCallbacks;
477  e = *snitch;
478  while (e && (e->handler != cb) && (e->userdata != userdata)) {
479  snitch = &(e->next);
480  e = *snitch;
481  }
482  if (!e) {
483  fprintf(stderr, "vrpn_Shared_int32::unregister_handler: "
484  "Handler not found.\n");
485  return;
486  }
487 
488  *snitch = e->next;
489  delete e;
490 }
491 
494  void *userdata)
495 {
496  d_policy = policy;
497  d_policyCallback = f;
498  d_policyUserdata = userdata;
499 }
500 
501 vrpn_Shared_int32 &vrpn_Shared_int32::set(vrpn_int32 newValue, timeval when,
502  vrpn_bool isLocalSet,
504 {
505  vrpn_bool acceptedUpdate;
506 
507  acceptedUpdate = shouldAcceptUpdate(newValue, when, isLocalSet, t);
508  if (acceptedUpdate) {
509  d_value = newValue;
510  d_lastUpdate = when;
511  // yankCallbacks(isLocalSet);
512  }
513 
514  if (shouldSendUpdate(isLocalSet, acceptedUpdate)) {
515  sendUpdate(newValue, when);
516  }
517 
518  // yankCallbacks is placed after sendUpdate so that the update goes on the
519  // network before the updates due to local callbacks.
520  if (acceptedUpdate) yankCallbacks(isLocalSet);
521 
522  return *this;
523 }
524 
525 // virtual
526 vrpn_bool vrpn_Shared_int32::shouldAcceptUpdate(vrpn_int32 newValue,
527  timeval when,
528  vrpn_bool isLocalSet,
530 {
531 
532  // fprintf(stderr, "In vrpn_Shared_int32::shouldAcceptUpdate(%s).\n",
533  // d_name);
534 
535  /*
536  // this commented-out code uses Lamport logical clocks, and is
537  // disabled now b/c the implementation of Lamport clocks was
538  // never complete. We use standard timestamps instead.
539  vrpn_bool old, equal;
540  if (t) {
541  old = d_lastLamportUpdate && (*t < *d_lastLamportUpdate);
542  equal = d_lastLamportUpdate && (*t == *d_lastLamportUpdate);
543  } else {
544  old = !vrpn_TimevalGreater(when, d_lastUpdate);
545  equal = vrpn_TimevalEqual( when, d_lastUpdate );
546  }
547  */
548  vrpn_bool old = !vrpn_TimevalGreater(when, d_lastUpdate);
549  vrpn_bool equal = vrpn_TimevalEqual(when, d_lastUpdate);
550 
551  // Is this "new" change idempotent?
552  if ((d_mode & VRPN_SO_IGNORE_IDEMPOTENT) && (newValue == d_value)) {
553  // fprintf(stderr, "... was idempotent.\n");
554  return vrpn_FALSE;
555  }
556 
557  // Is this "new" change older than the previous change?
558  if ((d_mode & VRPN_SO_IGNORE_OLD) && old) {
559  // fprintf(stderr, "... was outdated.\n");
560  return vrpn_FALSE;
561  }
562  // Is this "new" change older than the previous change?
563  if ((d_mode & VRPN_SO_IGNORE_OLD) && old) {
564 
565  // If the timestamps of the new & previous changes are equal:
566  // - if we are the serializer, we can accept the local change
567  // - if we are not the serializer, local updates are to be rejected
568  if (equal) {
569  if (!d_isSerializer && isLocalSet) {
570  return vrpn_FALSE;
571  }
572  }
573  else
574  return vrpn_FALSE;
575  }
576 
577  // All other clauses of shouldAcceptUpdate depend on serialization
578  if (!(d_mode & VRPN_SO_DEFER_UPDATES)) {
579  return vrpn_TRUE;
580  }
581 
582  // fprintf(stderr, "... serializing: ");
583 
584  // If we're not the serializer, don't accept local set() calls -
585  // forward those to the serializer. Non-local set() calls are
586  // messages from the serializer that we should accept.
587  if (!d_isSerializer) {
588  if (isLocalSet) {
589  // fprintf(stderr, "local update, not serializer, so reject.\n");
591  return vrpn_FALSE;
592  }
593  else {
594  // fprintf(stderr, "remote update, not serializer, so accept.\n");
595  return vrpn_TRUE;
596  }
597  }
598 
599  // We are the serializer.
600  // fprintf(stderr, "serializer: ");
601 
602  if (isLocalSet) {
603  // fprintf(stderr, "local update.\n");
604  if (d_policy == vrpn_DENY_LOCAL) {
605  return vrpn_FALSE;
606  }
607  else {
608  return vrpn_TRUE;
609  }
610  }
611 
612  // Are we accepting all updates?
613  if (d_policy == vrpn_ACCEPT) {
614  // fprintf(stderr, "policy is to accept.\n");
615  return vrpn_TRUE;
616  }
617 
618  // Does the user want to accept this one?
620  (*d_policyCallback)(d_policyUserdata, newValue, when, this)) {
621  // fprintf(stderr, "user callback accepts.\n");
622  return vrpn_TRUE;
623  }
624 
625  // fprintf(stderr, "rejected.\n");
626  return vrpn_FALSE;
627 }
628 
629 void vrpn_Shared_int32::encode(char **buffer, vrpn_int32 *len,
630  vrpn_int32 newValue, timeval when) const
631 {
632  vrpn_buffer(buffer, len, newValue);
633  vrpn_buffer(buffer, len, when);
634 }
635 void vrpn_Shared_int32::encodeLamport(char **buffer, vrpn_int32 *len,
636  vrpn_int32 newValue, timeval when,
637  vrpn_LamportTimestamp *t) const
638 {
639  int i;
640  vrpn_buffer(buffer, len, newValue);
641  vrpn_buffer(buffer, len, when);
642  vrpn_buffer(buffer, len, t->size());
643  for (i = 0; i < t->size(); i++) {
644  vrpn_buffer(buffer, len, (*t)[i]);
645  }
646 }
647 
648 void vrpn_Shared_int32::decode(const char **buffer, vrpn_int32 *,
649  vrpn_int32 *newValue, timeval *when) const
650 {
651  vrpn_unbuffer(buffer, newValue);
652  vrpn_unbuffer(buffer, when);
653 }
654 void vrpn_Shared_int32::decodeLamport(const char **buffer, vrpn_int32 *,
655  vrpn_int32 *newValue, timeval *when,
656  vrpn_LamportTimestamp **t) const
657 {
658  vrpn_uint32 size;
659  vrpn_uint32 *array;
660  unsigned int i;
661 
662  vrpn_unbuffer(buffer, newValue);
663  vrpn_unbuffer(buffer, when);
664  vrpn_unbuffer(buffer, &size);
665  array = new vrpn_uint32[size];
666  for (i = 0; i < size; i++) {
667  vrpn_unbuffer(buffer, &array[i]);
668  }
669  *t = new vrpn_LamportTimestamp(size, array);
670  delete[] array;
671 }
672 
674 
675 void vrpn_Shared_int32::sendUpdate(vrpn_int32 newValue, timeval when)
676 {
677  char buffer[32];
678  vrpn_int32 buflen = 32;
679  char *bp = buffer;
681 
682  if (d_connection) {
683  if (d_lClock) {
685  encodeLamport(&bp, &buflen, newValue, when, t);
686  }
687  else {
688  encode(&bp, &buflen, newValue, when);
689  }
692  // fprintf(stderr, "vrpn_Shared_int32::sendUpdate: packed message of %d
693  // "
694  //"at %d:%d.\n", d_value, d_lastUpdate.tv_sec, d_lastUpdate.tv_usec);
695  }
696 }
697 
698 int vrpn_Shared_int32::yankCallbacks(vrpn_bool isLocal)
699 {
700  callbackEntry *e;
701  timedCallbackEntry *te;
702 
703  for (e = d_callbacks; e; e = e->next) {
704  if ((*e->handler)(e->userdata, d_value, isLocal)) {
705  return -1;
706  }
707  }
708  for (te = d_timedCallbacks; te; te = te->next) {
709  if ((*te->handler)(te->userdata, d_value, d_lastUpdate, isLocal)) {
710  return -1;
711  }
712  }
713 
714  return 0;
715 }
716 
718 {
719  vrpn_int32 newValue;
720  timeval when;
721 
722  decode(&p.buffer, &p.payload_len, &newValue, &when);
723 
724  // fprintf(stderr, "%s::handleUpdate to %d at %d:%d.\n",
725  // d_name, newValue, when.tv_sec, when.tv_usec);
726 
727  set(newValue, when, vrpn_FALSE);
728 
729  // fprintf(stderr, "vrpn_Shared_int32::handleUpdate done\n");
730  return 0;
731 }
732 
733 // static
735 {
738  vrpn_int32 newValue;
739  timeval when;
740 
741  s->decodeLamport(&p.buffer, &p.payload_len, &newValue, &when, &t);
742 
743  // fprintf(stderr, "vrpn_Shared_int32::handleUpdate to %d at %d:%d.\n",
744  // newValue, when.tv_sec, when.tv_usec);
745 
746  s->d_lClock->receive(*t);
747 
748  s->set(newValue, when, vrpn_FALSE, t);
749 
750  if (s->d_lastLamportUpdate) {
751  delete s->d_lastLamportUpdate;
752  }
753  s->d_lastLamportUpdate = t;
754 
755  // fprintf(stderr, "vrpn_Shared_int32::handleUpdate done\n");
756  return 0;
757 }
758 
760  vrpn_int32 defaultValue,
761  vrpn_int32 defaultMode)
762  : vrpn_Shared_int32(name, defaultValue, defaultMode)
763 {
764 
765  d_isSerializer = vrpn_TRUE;
766 }
767 
768 // virtual
770 
772 {
774  return *this;
775 }
776 
777 // virtual
779 {
781 
783 }
784 
786  vrpn_int32 defaultValue,
787  vrpn_int32 defaultMode)
788  : vrpn_Shared_int32(name, defaultValue, defaultMode)
789 {
790 }
791 
792 // virtual
794 
796 {
798  return *this;
799 }
800 
802 {
803 
805 
807 }
808 
810  vrpn_float64 defaultValue,
811  vrpn_int32 mode)
812  : vrpn_SharedObject(name, "float64", mode)
813  , d_value(defaultValue)
814  , d_callbacks(NULL)
815  , d_timedCallbacks(NULL)
816  , d_policy(vrpn_ACCEPT)
817  , d_policyCallback(NULL)
818  , d_policyUserdata(NULL)
819 {
820 
821  if (name) {
822  strcpy(d_name, name);
823  }
825 }
826 
827 // virtual
829 {
830  // if (d_connection) {
831  // d_connection->unregister_handler(d_becomeSerializer_type,
832  // handle_becomeSerializer, this, d_myId);
833  //}
834 }
835 
836 vrpn_float64 vrpn_Shared_float64::value(void) const { return d_value; }
837 
838 vrpn_Shared_float64::operator vrpn_float64() const { return value(); }
839 
841 {
842  struct timeval now;
843  vrpn_gettimeofday(&now, NULL);
844  return set(newValue, now);
845 }
846 
848  timeval when)
849 {
850  return set(newValue, when, vrpn_TRUE);
851 }
852 
854  void *userdata)
855 {
856  callbackEntry *e = new callbackEntry;
857  if (!e) {
858  fprintf(stderr, "vrpn_Shared_float64::register_handler: "
859  "Out of memory.\n");
860  return;
861  }
862  e->handler = cb;
863  e->userdata = userdata;
864  e->next = d_callbacks;
865  d_callbacks = e;
866 }
867 
869  void *userdata)
870 {
871  callbackEntry *e, **snitch;
872 
873  snitch = &d_callbacks;
874  e = *snitch;
875  while (e && (e->handler != cb) && (e->userdata != userdata)) {
876  snitch = &(e->next);
877  e = *snitch;
878  }
879  if (!e) {
880  fprintf(stderr, "vrpn_Shared_float64::unregister_handler: "
881  "Handler not found.\n");
882  return;
883  }
884 
885  *snitch = e->next;
886  delete e;
887 }
888 
890  void *userdata)
891 {
893  if (!e) {
894  fprintf(stderr, "vrpn_Shared_float64::register_handler: "
895  "Out of memory.\n");
896  return;
897  }
898  e->handler = cb;
899  e->userdata = userdata;
900  e->next = d_timedCallbacks;
901  d_timedCallbacks = e;
902 }
903 
905  void *userdata)
906 {
907  timedCallbackEntry *e, **snitch;
908 
909  snitch = &d_timedCallbacks;
910  e = *snitch;
911  while (e && (e->handler != cb) && (e->userdata != userdata)) {
912  snitch = &(e->next);
913  e = *snitch;
914  }
915  if (!e) {
916  fprintf(stderr, "vrpn_Shared_float64::unregister_handler: "
917  "Handler not found.\n");
918  return;
919  }
920 
921  *snitch = e->next;
922  delete e;
923 }
924 
927  void *userdata)
928 {
929  d_policy = policy;
930  d_policyCallback = f;
931  d_policyUserdata = userdata;
932 }
933 
935  timeval when,
936  vrpn_bool isLocalSet)
937 {
938  vrpn_bool acceptedUpdate;
939 
940  acceptedUpdate = shouldAcceptUpdate(newValue, when, isLocalSet);
941  if (acceptedUpdate) {
942  d_value = newValue;
943  d_lastUpdate = when;
944  // yankCallbacks(isLocalSet);
945  }
946 
947  if (shouldSendUpdate(isLocalSet, acceptedUpdate)) {
948  sendUpdate(newValue, when);
949  }
950 
951  // yankCallbacks is placed after sendUpdate so that the update goes on the
952  // network before the updates due to local callbacks.
953  if (acceptedUpdate) yankCallbacks(isLocalSet);
954 
955  return *this;
956 }
957 
958 // virtual
959 vrpn_bool vrpn_Shared_float64::shouldAcceptUpdate(vrpn_float64 newValue,
960  timeval when,
961  vrpn_bool isLocalSet)
962 {
963 
964  // Is this "new" change idempotent?
965  if ((d_mode & VRPN_SO_IGNORE_IDEMPOTENT) && (newValue == d_value)) {
966  return vrpn_FALSE;
967  }
968 
969  // Is this "new" change older than the previous change?
970  if ((d_mode & VRPN_SO_IGNORE_OLD) &&
972 
973  // If the timestamps of the new & previous changes are equal:
974  // - if we are the serializer, we can accept the local change
975  // - if we are not the serializer, local updates are to be rejected
976  if (vrpn_TimevalEqual(when, d_lastUpdate)) {
977  if (!d_isSerializer && isLocalSet) {
978  return vrpn_FALSE;
979  }
980  }
981  else
982  return vrpn_FALSE;
983  }
984 
985  // All other clauses of shouldAcceptUpdate depend on serialization
986  if (!(d_mode & VRPN_SO_DEFER_UPDATES)) {
987  return vrpn_TRUE;
988  }
989 
990  // If we're not the serializer, don't accept local set() calls -
991  // forward those to the serializer. Non-local set() calls are
992  // messages from the serializer that we should accept.
993  if (!d_isSerializer) {
994  if (isLocalSet) {
996  return vrpn_FALSE;
997  }
998  else {
999  return vrpn_TRUE;
1000  }
1001  }
1002 
1003  // We are the serializer.
1004 
1005  if (isLocalSet) {
1006  if (d_policy == vrpn_DENY_LOCAL) {
1007  return vrpn_FALSE;
1008  }
1009  else {
1010  return vrpn_TRUE;
1011  }
1012  }
1013 
1014  // Are we accepting all updates?
1015  if (d_policy == vrpn_ACCEPT) {
1016  return vrpn_TRUE;
1017  }
1018 
1019  // Does the user want to accept this one?
1020  if ((d_policy == vrpn_CALLBACK) && d_policyCallback &&
1021  (*d_policyCallback)(d_policyUserdata, newValue, when, this)) {
1022  return vrpn_TRUE;
1023  }
1024 
1025  return vrpn_FALSE;
1026 }
1027 
1028 void vrpn_Shared_float64::encode(char **buffer, vrpn_int32 *len,
1029  vrpn_float64 newValue, timeval when) const
1030 {
1031  vrpn_buffer(buffer, len, newValue);
1032  vrpn_buffer(buffer, len, when);
1033 }
1034 void vrpn_Shared_float64::decode(const char **buffer, vrpn_int32 *,
1035  vrpn_float64 *newValue, timeval *when) const
1036 {
1037  vrpn_unbuffer(buffer, newValue);
1038  vrpn_unbuffer(buffer, when);
1039 }
1040 
1042 {
1044 }
1045 
1046 void vrpn_Shared_float64::sendUpdate(vrpn_float64 newValue, timeval when)
1047 {
1048  char buffer[32];
1049  vrpn_int32 buflen = 32;
1050  char *bp = buffer;
1051 
1052  if (d_connection) {
1053  encode(&bp, &buflen, newValue, when);
1055  d_myId, buffer, vrpn_CONNECTION_RELIABLE);
1056  // fprintf(stderr, "vrpn_Shared_float64::sendUpdate: packed
1057  // message\n");
1058  }
1059 }
1060 
1062 {
1063  callbackEntry *e;
1064  timedCallbackEntry *te;
1065 
1066  for (e = d_callbacks; e; e = e->next) {
1067  if ((*e->handler)(e->userdata, d_value, isLocal)) {
1068  return -1;
1069  }
1070  }
1071  for (te = d_timedCallbacks; te; te = te->next) {
1072  if ((*te->handler)(te->userdata, d_value, d_lastUpdate, isLocal)) {
1073  return -1;
1074  }
1075  }
1076 
1077  return 0;
1078 }
1079 
1081 {
1082  vrpn_float64 newValue;
1083  timeval when;
1084 
1085  decode(&p.buffer, &p.payload_len, &newValue, &when);
1086 
1087  set(newValue, when, vrpn_FALSE);
1088 
1089  return 0;
1090 }
1091 
1093  const char *name, vrpn_float64 defaultValue, vrpn_int32 defaultMode)
1094  : vrpn_Shared_float64(name, defaultValue, defaultMode)
1095 {
1096 
1097  d_isSerializer = vrpn_TRUE;
1098 }
1099 
1100 // virtual
1102 
1104 operator=(vrpn_float64 c)
1105 {
1107  return *this;
1108 }
1109 
1110 // virtual
1112 {
1114 
1116 }
1117 
1119  const char *name, vrpn_float64 defaultValue, vrpn_int32 defaultMode)
1120  : vrpn_Shared_float64(name, defaultValue, defaultMode)
1121 {
1122 }
1123 
1124 // virtual
1126 
1128 operator=(vrpn_float64 c)
1129 {
1131  return *this;
1132 }
1133 
1134 // virtual
1136 {
1137 
1139 
1141 }
1142 
1144  const char *defaultValue,
1145  vrpn_int32 mode)
1146  : vrpn_SharedObject(name, "String", mode)
1147  , d_value(defaultValue ? new char[1 + strlen(defaultValue)] : NULL)
1148  , d_callbacks(NULL)
1149  , d_timedCallbacks(NULL)
1150  , d_policy(vrpn_ACCEPT)
1151  , d_policyCallback(NULL)
1152  , d_policyUserdata(NULL)
1153 {
1154 
1155  if (defaultValue) {
1156  strcpy(d_value, defaultValue);
1157  }
1158  if (name) {
1159  strcpy(d_name, name);
1160  }
1162 }
1163 
1164 // virtual
1166 {
1167  if (d_value) {
1168  delete[] d_value;
1169  }
1170  // if (d_connection) {
1171  // d_connection->unregister_handler(d_becomeSerializer_type,
1172  // handle_becomeSerializer, this, d_myId);
1173  //}
1174 }
1175 
1176 const char *vrpn_Shared_String::value(void) const { return d_value; }
1177 
1178 vrpn_Shared_String::operator const char *() const { return value(); }
1179 
1181 {
1182  struct timeval now;
1183  vrpn_gettimeofday(&now, NULL);
1184  return set(newValue, now);
1185 }
1186 
1187 vrpn_Shared_String &vrpn_Shared_String::set(const char *newValue, timeval when)
1188 {
1189  return set(newValue, when, vrpn_TRUE);
1190 }
1191 
1193  void *userdata)
1194 {
1195  callbackEntry *e = new callbackEntry;
1196  if (!e) {
1197  fprintf(stderr, "vrpn_Shared_String::register_handler: "
1198  "Out of memory.\n");
1199  return;
1200  }
1201  e->handler = cb;
1202  e->userdata = userdata;
1203  e->next = d_callbacks;
1204  d_callbacks = e;
1205 }
1206 
1208  void *userdata)
1209 {
1210  callbackEntry *e, **snitch;
1211 
1212  snitch = &d_callbacks;
1213  e = *snitch;
1214  while (e && (e->handler != cb) && (e->userdata != userdata)) {
1215  snitch = &(e->next);
1216  e = *snitch;
1217  }
1218  if (!e) {
1219  fprintf(stderr, "vrpn_Shared_String::unregister_handler: "
1220  "Handler not found.\n");
1221  return;
1222  }
1223 
1224  *snitch = e->next;
1225  delete e;
1226 }
1227 
1229  void *userdata)
1230 {
1232  if (!e) {
1233  fprintf(stderr, "vrpn_Shared_String::register_handler: "
1234  "Out of memory.\n");
1235  return;
1236  }
1237  e->handler = cb;
1238  e->userdata = userdata;
1239  e->next = d_timedCallbacks;
1240  d_timedCallbacks = e;
1241 }
1242 
1244  void *userdata)
1245 {
1246  timedCallbackEntry *e, **snitch;
1247 
1248  snitch = &d_timedCallbacks;
1249  e = *snitch;
1250  while (e && (e->handler != cb) && (e->userdata != userdata)) {
1251  snitch = &(e->next);
1252  e = *snitch;
1253  }
1254  if (!e) {
1255  fprintf(stderr, "vrpn_Shared_String::unregister_handler: "
1256  "Handler not found.\n");
1257  return;
1258  }
1259 
1260  *snitch = e->next;
1261  delete e;
1262 }
1263 
1266  void *userdata)
1267 {
1268  d_policy = policy;
1269  d_policyCallback = f;
1270  d_policyUserdata = userdata;
1271 }
1272 
1273 vrpn_Shared_String &vrpn_Shared_String::set(const char *newValue, timeval when,
1274  vrpn_bool isLocalSet)
1275 {
1276  vrpn_bool acceptedUpdate;
1277 
1278  acceptedUpdate = shouldAcceptUpdate(newValue, when, isLocalSet);
1279  if (acceptedUpdate) {
1280 
1281  if ((d_value == NULL) || (strcmp(d_value, newValue) != 0)) {
1282  if (d_value) {
1283  delete[] d_value;
1284  }
1285  d_value = new char[1 + strlen(newValue)];
1286  if (!d_value) {
1287  fprintf(stderr, "vrpn_Shared_String::set: Out of memory.\n");
1288  return *this;
1289  }
1290  strcpy(d_value, newValue);
1291  }
1292 
1293  // fprintf(stderr, "vrpn_Shared_String::set: %s to \"%s\".\n", name(),
1294  // value());
1295 
1296  d_lastUpdate = when;
1297  }
1298 
1299  if (shouldSendUpdate(isLocalSet, acceptedUpdate)) {
1300  sendUpdate(newValue, when);
1301  }
1302 
1303  // yankCallbacks is placed after sendUpdate so that the update goes on the
1304  // network before the updates due to local callbacks.
1305  if (acceptedUpdate) yankCallbacks(isLocalSet);
1306 
1307  return *this;
1308 }
1309 
1310 // virtual
1311 vrpn_bool vrpn_Shared_String::shouldAcceptUpdate(const char *newValue,
1312  timeval when,
1313  vrpn_bool isLocalSet)
1314 {
1315 
1316  // Is this "new" change idempotent?
1317  if ((d_mode & VRPN_SO_IGNORE_IDEMPOTENT) && (newValue == d_value)) {
1318  return vrpn_FALSE;
1319  }
1320 
1321  // Is this "new" change older than the previous change?
1322  if ((d_mode & VRPN_SO_IGNORE_OLD) &&
1324 
1325  // If the timestamps of the new & previous changes are equal:
1326  // - if we are the serializer, we can accept the local change
1327  // - if we are not the serializer, local updates are to be rejected
1328  if (vrpn_TimevalEqual(when, d_lastUpdate)) {
1329  if (!d_isSerializer && isLocalSet) {
1330  return vrpn_FALSE;
1331  }
1332  }
1333  else
1334  return vrpn_FALSE;
1335  }
1336 
1337  // All other clauses of shouldAcceptUpdate depend on serialization
1338  if (!(d_mode & VRPN_SO_DEFER_UPDATES)) {
1339  return vrpn_TRUE;
1340  }
1341 
1342  // If we're not the serializer, don't accept local set() calls -
1343  // forward those to the serializer. Non-local set() calls are
1344  // messages from the serializer that we should accept.
1345  if (!d_isSerializer) {
1346  if (isLocalSet) {
1348  return vrpn_FALSE;
1349  }
1350  else {
1351  return vrpn_TRUE;
1352  }
1353  }
1354 
1355  // We are the serializer.
1356 
1357  if (isLocalSet) {
1358  if (d_policy == vrpn_DENY_LOCAL) {
1359  return vrpn_FALSE;
1360  }
1361  else {
1362  return vrpn_TRUE;
1363  }
1364  }
1365 
1366  // Are we accepting all updates?
1367  if (d_policy == vrpn_ACCEPT) {
1368  return vrpn_TRUE;
1369  }
1370 
1371  // Does the user want to accept this one?
1372  if ((d_policy == vrpn_CALLBACK) && d_policyCallback &&
1373  (*d_policyCallback)(d_policyUserdata, newValue, when, this)) {
1374  return vrpn_TRUE;
1375  }
1376 
1377  return vrpn_FALSE;
1378 }
1379 
1380 void vrpn_Shared_String::encode(char **buffer, vrpn_int32 *len,
1381  const char *newValue, timeval when) const
1382 {
1383  // We reverse ordering from the other vrpn_SharedObject classes
1384  // so that the time value is guaranteed to be aligned.
1385  vrpn_buffer(buffer, len, when);
1386  vrpn_buffer(buffer, len, newValue,
1387  static_cast<vrpn_int32>(strlen(newValue)));
1388 }
1389 void vrpn_Shared_String::decode(const char **buffer, vrpn_int32 *len,
1390  char *newValue, timeval *when) const
1391 {
1392  vrpn_unbuffer(buffer, when);
1393  vrpn_unbuffer(buffer, newValue, *len - sizeof(*when));
1394  newValue[*len - sizeof(*when)] = 0;
1395 }
1396 
1398 
1399 void vrpn_Shared_String::sendUpdate(const char *newValue, timeval when)
1400 {
1401  char buffer[1024]; // HACK
1402  vrpn_int32 buflen = 1024;
1403  char *bp = buffer;
1404 
1405  if (d_connection) {
1406  encode(&bp, &buflen, newValue, when);
1408  d_myId, buffer, vrpn_CONNECTION_RELIABLE);
1409  // fprintf(stderr, "vrpn_Shared_String::sendUpdate: packed message\n");
1410  }
1411 }
1412 
1414 {
1415  callbackEntry *e;
1416  timedCallbackEntry *te;
1417 
1418  for (e = d_callbacks; e; e = e->next) {
1419  if ((*e->handler)(e->userdata, d_value, isLocal)) {
1420  return -1;
1421  }
1422  }
1423  for (te = d_timedCallbacks; te; te = te->next) {
1424  if ((*te->handler)(te->userdata, d_value, d_lastUpdate, isLocal)) {
1425  return -1;
1426  }
1427  }
1428 
1429  return 0;
1430 }
1431 
1432 // static
1434 {
1435  char newValue[1024]; // HACK
1436  timeval when;
1437 
1438  decode(&p.buffer, &p.payload_len, newValue, &when);
1439 
1440  set(newValue, when, vrpn_FALSE);
1441 
1442  return 0;
1443 }
1444 
1446  const char *defaultValue,
1447  vrpn_int32 defaultMode)
1448  : vrpn_Shared_String(name, defaultValue, defaultMode)
1449 {
1450 
1451  d_isSerializer = vrpn_TRUE;
1452 }
1453 
1454 // virtual
1456 
1458 {
1460  return *this;
1461 }
1462 
1463 // virtual
1465 {
1467 
1469 }
1470 
1472  const char *defaultValue,
1473  vrpn_int32 defaultMode)
1474  : vrpn_Shared_String(name, defaultValue, defaultMode)
1475 {
1476 }
1477 
1478 // virtual
1480 
1482 {
1484  return *this;
1485 }
1486 
1487 // virtual
1489 {
1490 
1492 
1494 }
virtual int unregister_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
virtual ~vrpn_Shared_String_Remote(void)
virtual void sendUpdate(void)=0
Should invoke default sendUpdate() for this derived type.
void decode(const char **buffer, vrpn_int32 *len, vrpn_int32 *newValue, timeval *when) const
virtual ~vrpn_Shared_int32_Remote(void)
void remotePostBindCleanup(void)
vrpn_int32 value(void) const
static int VRPN_CALLBACK handle_update(void *, vrpn_HANDLERPARAM)
Passes arguments to handleUpdate() for this type; registered in postBindCleanup();.
void register_handler(vrpnSharedFloatCallback, void *)
vrpn_Shared_float64_Remote(const char *name, vrpn_float64 defaultValue=0, vrpn_int32 defaultMode=VRPN_SO_DEFAULT)
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
Definition: vrpn_Shared.C:312
int(VRPN_CALLBACK * vrpnTimedSharedStringCallback)(void *userdata, const char *newValue, timeval when, vrpn_bool isLocal)
vrpn_Shared_String & operator=(const char *newValue)
void setSerializerPolicy(vrpn_SerializerPolicy policy=vrpn_ACCEPT, vrpnSharedIntSerializerPolicy f=NULL, void *userdata=NULL)
Implements a distributed event clock as defined by Leslie Lamport in some seminal papers I can&#39;t find...
int size(void) const
Returns the number of hosts participating in the timestamp.
virtual vrpn_bool shouldAcceptUpdate(vrpn_int32 newValue, timeval when, vrpn_bool isLocalSet, vrpn_LamportTimestamp *)
vrpn_Shared_float64_Remote & operator=(vrpn_float64 newValue)
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
virtual void sendUpdate(void)
Should invoke default sendUpdate() for this derived type.
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
void encode(char **buffer, vrpn_int32 *len, const char *newValue, timeval when) const
vrpn_int32 payload_len
virtual vrpn_int32 register_sender(const char *name)
Get a token to use for the string name of the sender or type. Remember to check for -1 meaning failur...
vrpn_bool isSerializer(void) const
vrpn_Shared_String_Server & operator=(const char *)
virtual ~vrpn_Shared_float64(void)
void unregister_handler(vrpnSharedIntCallback, void *)
static int VRPN_CALLBACK handle_gotConnection(void *, vrpn_HANDLERPARAM)
Register this handler in postBindCleanup(); it calls sendUpdate() to make sure the remote has the cor...
vrpn_Shared_String_Remote & operator=(const char *)
int(VRPN_CALLBACK * vrpnSharedFloatSerializerPolicy)(void *userdata, vrpn_float64 newValue, timeval when, vrpn_Shared_float64 *object)
static int VRPN_CALLBACK handle_requestSerializer(void *, vrpn_HANDLERPARAM)
int(VRPN_CALLBACK * vrpnTimedSharedFloatCallback)(void *userdata, vrpn_float64 newValue, timeval when, vrpn_bool isLocal)
#define VRPN_SO_IGNORE_IDEMPOTENT
void becomeSerializer(void)
Requests that this instance of the shared object becomes the serializer (i.e. lock-arbitrator), and we can then use setSerializerPolicy to imitate a complete lock. Does nothing if we already are the serializer (isSerializer() returns true); otherwise initiates a 3-phase request protocol with the current serializer. There currently isn&#39;t any provision for notification of success (or failure).
class VRPN_API vrpn_LamportTimestamp
const char * buffer
void decodeLamport(const char **buffer, vrpn_int32 *len, vrpn_int32 *newValue, timeval *when, vrpn_LamportTimestamp **t) const
virtual ~vrpn_Shared_String(void)
vrpn_SerializerPolicy d_policy
vrpn_LamportClock * d_lClock
virtual ~vrpn_SharedObject(void)
vrpn_Shared_float64 & operator=(vrpn_float64 newValue)
vrpn_int32 d_grantSerializer_type
Sent by the serializer to grant a request.
callbackEntry * d_callbacks
vrpn_Shared_String_Server(const char *name, const char *defaultValue=NULL, vrpn_int32 defaultMode=VRPN_SO_DEFAULT)
int handleUpdate(vrpn_HANDLERPARAM)
vrpn_Shared_int32_Remote & operator=(vrpn_int32 newValue)
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...
vrpn_SharedObject(const char *name, const char *tname, vrpn_int32 mode)
void serverPostBindCleanup(void)
Generic connection class not specific to the transport mechanism.
vrpn_Shared_int32 & set(vrpn_int32 newValue, timeval when)
int yankDeferredUpdateCallbacks(void)
returns -1 on error (i.e. nonzero return by a callback)
vrpn_bool d_queueSets
If this is true, no set()s are processed; instead, they are queued for later execution. NOT IMPLEMENTED.
vrpnTimedSharedStringCallback handler
virtual vrpn_Shared_String & set(const char *newValue, timeval when)
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
vrpn_Shared_float64_Server(const char *name, vrpn_float64 defaultValue=0, vrpn_int32 defaultMode=VRPN_SO_DEFAULT)
vrpn_Shared_String_Remote(const char *name, const char *defaultValue=NULL, vrpn_int32 defaultMode=VRPN_SO_DEFAULT)
void unregister_handler(vrpnSharedFloatCallback, void *)
vrpn_SerializerPolicy
void registerDeferredUpdateCallback(vrpnDeferredUpdateCallback, void *userdata)
The specified function will be passed userdata when this particular shared object defers an update (r...
virtual int register_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Set up (or remove) a handler for a message of a given type. Optionally, specify which sender to handl...
vrpnSharedIntSerializerPolicy d_policyCallback
vrpn_Connection * d_connection
int(VRPN_CALLBACK * vrpnSharedIntSerializerPolicy)(void *userdata, vrpn_int32 newValue, timeval when, vrpn_Shared_int32 *object)
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
Timestamp for a single event, produced by a vrpn_LamportClock and hopefully generally usable in place...
vrpnSharedStringCallback handler
deferredUpdateCallbackEntry * d_deferredUpdateCallbacks
void receive(const vrpn_LamportTimestamp &)
Updates this clock to reflect a timestamp received from another clock/host.
This structure is what is passed to a vrpn_Connection message callback.
void encode(char **buffer, vrpn_int32 *len, vrpn_int32 newValue, timeval when) const
int(VRPN_CALLBACK * vrpnSharedStringSerializerPolicy)(void *userdata, const char *newValue, timeval when, vrpn_Shared_String *object)
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
virtual vrpn_bool shouldAcceptUpdate(const char *newValue, timeval when, vrpn_bool isLocalSet)
vrpn_Shared_int32_Server & operator=(vrpn_int32 newValue)
virtual vrpn_bool shouldAcceptUpdate(vrpn_float64 newValue, timeval when, vrpn_bool isLocalSet)
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.
virtual ~vrpn_Shared_String_Server(void)
vrpn_SerializerPolicy d_policy
int yankCallbacks(vrpn_bool isLocal)
vrpnSharedFloatSerializerPolicy d_policyCallback
void useLamportClock(vrpn_LamportClock *)
Lamport Clocks are NOT currently integrated. They should provide serialization (virtual timestamps) t...
void unregister_handler(vrpnSharedStringCallback, void *)
virtual int handleUpdate(vrpn_HANDLERPARAM)=0
bool vrpn_TimevalGreater(const timeval &tv1, const timeval &tv2)
Definition: vrpn_Shared.C:113
const char * vrpn_got_connection
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
virtual vrpn_Shared_float64 & set(vrpn_float64 newValue, timeval when)
void setSerializerPolicy(vrpn_SerializerPolicy policy=vrpn_ACCEPT, vrpnSharedFloatSerializerPolicy f=NULL, void *userdata=NULL)
virtual vrpn_bool shouldSendUpdate(vrpn_bool isLocalSet, vrpn_bool acceptedUpdate)
vrpn_Shared_String(const char *name, const char *defaultValue=NULL, vrpn_int32 mode=VRPN_SO_DEFAULT)
void setSerializerPolicy(vrpn_SerializerPolicy policy=vrpn_ACCEPT, vrpnSharedStringSerializerPolicy f=NULL, void *userdata=NULL)
bool vrpn_TimevalEqual(const timeval &tv1, const timeval &tv2)
Definition: vrpn_Shared.C:121
vrpn_Shared_int32_Server(const char *name, vrpn_int32 defaultValue=0, vrpn_int32 defaultMode=VRPN_SO_DEFAULT)
virtual void sendUpdate(void)
Should invoke default sendUpdate() for this derived type.
int(VRPN_CALLBACK * vrpnDeferredUpdateCallback)(void *userdata)
void encode(char **buffer, vrpn_int32 *len, vrpn_float64 newValue, timeval when) const
const char * value(void) const
virtual ~vrpn_Shared_int32_Server(void)
vrpn_Shared_float64(const char *name, vrpn_float64 defaultValue=0.0, vrpn_int32 mode=VRPN_SO_DEFAULT)
static int VRPN_CALLBACK handle_lamportUpdate(void *, vrpn_HANDLERPARAM)
void decode(const char **buffer, vrpn_int32 *len, char *newValue, timeval *when) const
void encodeLamport(char **buffer, vrpn_int32 *len, vrpn_int32 newValue, timeval when, vrpn_LamportTimestamp *t) const
virtual ~vrpn_Shared_float64_Remote(void)
vrpn_int32 d_requestSerializer_type
Sent to the serializer to assume its duties.
static int VRPN_CALLBACK handle_grantSerializer(void *, vrpn_HANDLERPARAM)
vrpn_LamportTimestamp * getTimestampAndAdvance(void)
Increments the current timestamp and returns it.
virtual void sendUpdate(void)
Should invoke default sendUpdate() for this derived type.
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpnTimedSharedFloatCallback handler
virtual ~vrpn_Shared_float64_Server(void)
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message...
Definition: vrpn_Shared.C:241
vrpn_Shared_float64_Server & operator=(vrpn_float64 newValue)
int yankCallbacks(vrpn_bool isLocal)
vrpnSharedStringSerializerPolicy d_policyCallback
int handleUpdate(vrpn_HANDLERPARAM)
vrpn_float64 value(void) const
int handleUpdate(vrpn_HANDLERPARAM)
int yankCallbacks(vrpn_bool isLocal)
void register_handler(vrpnSharedIntCallback, void *)
int(VRPN_CALLBACK * vrpnSharedStringCallback)(void *userdata, const char *newValue, vrpn_bool isLocal)
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
void decode(const char **buffer, vrpn_int32 *len, vrpn_float64 *newValue, timeval *when) const
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
#define VRPN_SO_DEFER_UPDATES
vrpn_SerializerPolicy d_policy
static int VRPN_CALLBACK handle_assumeSerializer(void *, vrpn_HANDLERPARAM)
vrpn_Shared_int32_Remote(const char *name, vrpn_int32 defaultValue=0, vrpn_int32 defaultMode=VRPN_SO_DEFAULT)
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
virtual ~vrpn_Shared_int32(void)
const char * name(void) const
void addReference()
Counting references to this connection.
vrpn_Shared_int32(const char *name, vrpn_int32 defaultValue=0, vrpn_int32 mode=VRPN_SO_DEFAULT)
void register_handler(vrpnSharedStringCallback, void *)
virtual vrpn_int32 register_message_type(const char *name)
virtual void bindConnection(vrpn_Connection *)
Every derived class should call this, do what it needs to, and ALSO call {server,remote}PostBindClean...
timedCallbackEntry * d_timedCallbacks
vrpn_Shared_int32 & operator=(vrpn_int32 newValue)
int(VRPN_CALLBACK * vrpnTimedSharedIntCallback)(void *userdata, vrpn_int32 newValue, timeval when, vrpn_bool isLocal)
#define VRPN_SO_IGNORE_OLD
callbackEntry * d_callbacks
callbackEntry * d_callbacks