vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Dial.C
Go to the documentation of this file.
1 #include <stdio.h> // for fprintf, stderr, NULL
2 
3 #include "vrpn_Connection.h" // for vrpn_Connection, etc
4 #include "vrpn_Dial.h"
5 
6 //#define VERBOSE
7 
8 vrpn_Dial::vrpn_Dial(const char *name, vrpn_Connection *c)
9  : vrpn_BaseClass(name, c)
10 {
12 
13  num_dials = 0;
14  // Set the time to 0 just to have something there.
15  timestamp.tv_usec = timestamp.tv_sec = 0;
16 }
17 
19 {
20  if (d_connection == NULL) {
21  return 0;
22  }
23  change_m_id = d_connection->register_message_type("vrpn_Dial update");
24  if (change_m_id == -1) {
25  fprintf(stderr, "vrpn_Dial: Can't register type IDs\n");
26  d_connection = NULL;
27  }
28  return 0;
29 }
30 
31 vrpn_int32 vrpn_Dial::encode_to(char *buf, vrpn_int32 buflen, vrpn_int32 dial,
32  vrpn_float64 delta)
33 {
34  vrpn_int32 buflensofar = buflen;
35 
36  // Message includes: vrpn_int32 dialNum, vrpn_float64 delta
37  // We pack them with the delta first, so that everything is aligned
38  // on the proper boundary.
39 
40  if (vrpn_buffer(&buf, &buflensofar, delta)) {
41  fprintf(stderr, "vrpn_Dial::encode_to: Can't buffer delta\n");
42  return -1;
43  }
44  if (vrpn_buffer(&buf, &buflensofar, dial)) {
45  fprintf(stderr, "vrpn_Dial::encode_to: Can't buffer dial\n");
46  return -1;
47  }
48  return sizeof(vrpn_float64) + sizeof(vrpn_int32);
49 }
50 
51 // This will report any changes that have appeared in the dial values,
52 // and then clear the dials back to 0. It only sends dials that have
53 // changed (nonzero values)
55 {
56 
57  char msgbuf[1000];
58  vrpn_int32 i;
59  vrpn_int32 len;
60 
61  if (d_connection) {
62  for (i = 0; i < num_dials; i++) {
63  if (dials[i] != 0) {
64  len = encode_to(msgbuf, sizeof(msgbuf), i, dials[i]);
66  d_sender_id, msgbuf,
68  fprintf(stderr,
69  "vrpn_Dial: can't write message: tossing\n");
70  }
71  dials[i] = 0; // We've reported it the change.
72  }
73  }
74  }
75 }
76 
77 // This will report the dials whether they have changed or not; this
78 // will result in some 0 dial values being sent. Normally, code will
79 // use the report_changes method to avoid flooding the system with
80 // un-needed messages.
81 // It then clears the dials back to 0.
83 {
84 
85  char msgbuf[1000];
86  vrpn_int32 i;
87  vrpn_int32 len;
88 
89  if (d_connection) {
90  for (i = 0; i < num_dials; i++) {
91  len = encode_to(msgbuf, sizeof(msgbuf), i, dials[i]);
93  d_sender_id, msgbuf,
95  fprintf(stderr, "vrpn_Dial: can't write message: tossing\n");
96  }
97  dials[i] = 0; // We've reported it the change.
98  }
99  }
100 }
101 
102 // ************* EXAMPLE SERVER ROUTINES ****************************
103 
105  vrpn_Connection *c,
106  vrpn_int32 numdials,
107  vrpn_float64 spin_rate,
108  vrpn_float64 update_rate)
109  : vrpn_Dial(name, c)
110  , // Construct the base class, which registers message/sender
111  _spin_rate(spin_rate)
112  , // Set the rate at which the dials will spin
113  _update_rate(update_rate) // Set the rate at which to generate reports
114 {
115  // Make sure we asked for a legal number of dials
116  if (num_dials > vrpn_DIAL_MAX) {
117  fprintf(stderr, "vrpn_Dial_Example_Server: Only using %d dials\n",
118  vrpn_DIAL_MAX);
120  }
121  else {
122  num_dials = numdials;
123  }
124 
125  // IN A REAL SERVER, open the device that will service the dials here
126 }
127 
129 {
130  struct timeval current_time;
131  int i;
132 
133  // Call the generic server mainloop, since we are a server
134  server_mainloop();
135 
136  // See if its time to generate a new report
137  // IN A REAL SERVER, this check would not be done; although the
138  // time of the report would be updated to the current time so
139  // that the correct timestamp would be issued on the report.
140  vrpn_gettimeofday(&current_time, NULL);
141  if (vrpn_TimevalDuration(current_time, timestamp) >=
142  1000000.0 / _update_rate) {
143 
144  // Update the time
145  timestamp.tv_sec = current_time.tv_sec;
146  timestamp.tv_usec = current_time.tv_usec;
147 
148  // Update the values for the dials, to say that each one has
149  // moved the appropriate rotation (spin rate is revolutions per
150  // second, update rate is report/second, the quotient is the number
151  // of revolutions since the last report). When the changes are
152  // reported, these values are set back to zero.
153 
154  // THIS CODE WILL BE REPLACED by the user code that tells how
155  // many revolutions each dial has changed since the last report.
156  for (i = 0; i < num_dials; i++) {
158  }
159 
160  // Send reports. Stays the same in a real server.
161  report_changes();
162  }
163 }
164 
165 // ************* CLIENT ROUTINES ****************************
166 
168  : vrpn_Dial(name, c)
169 {
170  vrpn_int32 i;
171 
172  // Register a handler for the change callback from this device,
173  // if we got a connection.
174  if (d_connection) {
176  this, d_sender_id)) {
177  fprintf(stderr, "vrpn_Dial_Remote: can't register handler\n");
178  d_connection = NULL;
179  }
180  }
181  else {
182  fprintf(stderr, "vrpn_Dial_Remote: Can't get connection!\n");
183  }
184 
185  // At the start, as far as the client knows, the device could have
186  // max channels -- the number of channels is specified in each
187  // message.
189  for (i = 0; i < vrpn_DIAL_MAX; i++) {
190  dials[i] = 0.0;
191  }
193 }
194 
196 
198 {
199  client_mainloop();
200  if (d_connection) {
202  }
203 }
204 
206 {
208  vrpn_DIALCB cp;
209  const char *bufptr = p.buffer;
210 
211  cp.msg_time = p.msg_time;
212  vrpn_unbuffer(&bufptr, &cp.change);
213  vrpn_unbuffer(&bufptr, &cp.dial);
214 
215  // Go down the list of callbacks that have been registered.
216  // Fill in the parameter and call each.
218 
219  return 0;
220 }
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
struct timeval msg_time
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
virtual void report_changes(void)
Definition: vrpn_Dial.C:54
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
void client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
const char * buffer
vrpn_int32 change_m_id
Definition: vrpn_Dial.h:29
struct timeval timestamp
Definition: vrpn_Dial.h:28
Generic connection class not specific to the transport mechanism.
vrpn_int32 num_dials
Definition: vrpn_Dial.h:27
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Dial.C:128
struct timeval msg_time
Definition: vrpn_Dial.h:74
vrpn_float64 change
Definition: vrpn_Dial.h:76
vrpn_Dial(const char *name, vrpn_Connection *c=NULL)
Definition: vrpn_Dial.C:8
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Dial.C:197
virtual void report(void)
Definition: vrpn_Dial.C:82
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
vrpn_Dial_Example_Server(const char *name, vrpn_Connection *c, vrpn_int32 numdials=1, vrpn_float64 spin_rate=1.0, vrpn_float64 update_rate=10.0)
Definition: vrpn_Dial.C:104
vrpn_Connection * d_connection
Connection that this object talks to.
This structure is what is passed to a vrpn_Connection message callback.
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...
const int vrpn_DIAL_MAX
Definition: vrpn_Dial.h:9
vrpn_float64 _update_rate
Definition: vrpn_Dial.h:59
virtual vrpn_int32 encode_to(char *buf, vrpn_int32 buflen, vrpn_int32 dial, vrpn_float64 delta)
Definition: vrpn_Dial.C:31
vrpn_float64 _spin_rate
Definition: vrpn_Dial.h:58
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
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
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
vrpn_int32 d_sender_id
Sender ID registered with the connection.
virtual int register_types(void)
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
Definition: vrpn_Dial.C:18
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
Definition: vrpn_Shared.C:129
vrpn_Callback_List< vrpn_DIALCB > d_callback_list
Definition: vrpn_Dial.h:110
virtual vrpn_int32 register_message_type(const char *name)
static int VRPN_CALLBACK handle_change_message(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Dial.C:205
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
vrpn_Dial_Remote(const char *name, vrpn_Connection *c=NULL)
Definition: vrpn_Dial.C:167
vrpn_int32 dial
Definition: vrpn_Dial.h:75
vrpn_float64 dials[vrpn_DIAL_MAX]
Definition: vrpn_Dial.h:26