-
Notifications
You must be signed in to change notification settings - Fork 1
/
vrpn_Analog_Output.h
193 lines (162 loc) · 7.93 KB
/
vrpn_Analog_Output.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// vrpn_Analog_Output.h
// David Borland, September 2002
//
// These classes are for setting values for an analog output device. The
// vrpn_Analog was getting overloaded by trying to have functionality for both
// reading and writing in it. If wanting to read analog values from a device, a
// vrpn_Analog should be used, if wanting to write analog values to a device, a
// vrpn_Analog_Output should be used. This is similar to the Tracker/Poser
// dichotomy.
#ifndef VRPN_ANALOG_OUTPUT_H
#define VRPN_ANALOG_OUTPUT_H
#include <stddef.h> // for NULL
#include "vrpn_Analog.h" // for vrpn_CHANNEL_MAX
#include "vrpn_BaseClass.h" // for vrpn_Callback_List, etc
#include "vrpn_Configure.h" // for VRPN_CALLBACK, VRPN_API
#include "vrpn_Connection.h" // for vrpn_CONNECTION_RELIABLE, etc
#include "vrpn_Shared.h" // for timeval
#include "vrpn_Types.h" // for vrpn_int32, vrpn_float64, etc
// Similar to vrpn_Analog, but messages are different
// Members beginning with o_ are also found in vrpn_Analog, the o_ is
// so that you can derive a class from both without getting ambiguities
class VRPN_API vrpn_Analog_Output : public vrpn_BaseClass {
public:
vrpn_Analog_Output(const char* name, vrpn_Connection* c = NULL);
// Print the status of the analog output device
void o_print(void);
vrpn_int32 getNumChannels() const { return o_num_channel; }
protected:
vrpn_float64 o_channel[vrpn_CHANNEL_MAX];
vrpn_int32 o_num_channel;
struct timeval o_timestamp;
vrpn_int32 request_m_id; //< Request to change message from client
vrpn_int32 request_channels_m_id; //< Request to change channels message
// from client
vrpn_int32 report_num_channels_m_id; //< Report of the number of active
// channels, from the server
vrpn_int32 got_connection_m_id; //< new-connection notification
int o_status;
virtual int register_types(void);
};
// A *Sample* Analog output server. Use this, or derive your own server
// from vrpn_Analog_Output with this as a guide. You can remove the
// user-level callback code (both the type before this class and the
// list and the handler register/deregister) if the server is controlling
// a device directly.
class VRPN_API vrpn_Analog_Output_Server : public vrpn_Analog_Output {
public:
vrpn_Analog_Output_Server(const char* name, vrpn_Connection* c,
vrpn_int32 numChannels = vrpn_CHANNEL_MAX);
virtual ~vrpn_Analog_Output_Server(void);
virtual void mainloop() { server_mainloop(); }
/// Sets the size of the array; returns the size actually set.
/// (May be clamped to vrpn_CHANNEL_MAX)
/// This should be used before mainloop is ever called.
vrpn_int32 setNumChannels(vrpn_int32 sizeRequested);
/// Exposes an array of values for the user to read from.
const vrpn_float64* o_channels(void) const { return o_channel; };
protected:
virtual bool report_num_channels(
vrpn_uint32 class_of_service = vrpn_CONNECTION_RELIABLE);
virtual vrpn_int32 encode_num_channels_to(char* buf, vrpn_int32 num);
/// Responds to a request to change one of the values by
/// setting the channel to that value. Derived class must
/// either install handlers for this routine or else make
/// its own routines to handle the request message.
static int VRPN_CALLBACK
handle_request_message(void* userdata, vrpn_HANDLERPARAM p);
/// Responds to a request to change a number of channels
/// Derived class must either install handlers for this
/// routine or else make its own routines to handle the
/// multi-channel request message.
static int VRPN_CALLBACK
handle_request_channels_message(void* userdata, vrpn_HANDLERPARAM p);
/// Used to notify us when a new connection is requested, so that
/// we can let the client know how many channels are active
static int VRPN_CALLBACK
handle_got_connection(void* userdata, vrpn_HANDLERPARAM p);
};
// A more complicated analog server that provides a
// user routine to handle a change in analog values. This is called when
// the analog callback is called (when a message from its counterpart
// across the connection arrives). This callback is called whenever
// EITHER type of change message arrives (either a single-channel change
// or a multiple-channel change.
typedef struct _vrpn_ANALOGOUTPUTCB {
struct timeval msg_time; // Timestamp of analog data
vrpn_int32 num_channel; // how many channels
const vrpn_float64* channel; // analog values (pointer to channels)
} vrpn_ANALOGOUTPUTCB;
typedef void(VRPN_CALLBACK* vrpn_ANALOGOUTPUTCHANGEHANDLER)(
void* userdata, const vrpn_ANALOGOUTPUTCB info);
class VRPN_API vrpn_Analog_Output_Callback_Server
: public vrpn_Analog_Output_Server {
public:
vrpn_Analog_Output_Callback_Server(
const char* name, vrpn_Connection* c,
vrpn_int32 numChannels = vrpn_CHANNEL_MAX);
virtual ~vrpn_Analog_Output_Callback_Server(void);
// (un)Register a callback handler to handle analog value change.
// These will be called whenever EITHER type of change message is
// received, either a single channel or multiple channels. This is
// useful for applications that "have a" server, rather than derive
// from the server.
virtual int register_change_handler(void* userdata,
vrpn_ANALOGOUTPUTCHANGEHANDLER handler)
{
return d_callback_list.register_handler(userdata, handler);
};
virtual int
unregister_change_handler(void* userdata,
vrpn_ANALOGOUTPUTCHANGEHANDLER handler)
{
return d_callback_list.unregister_handler(userdata, handler);
}
protected:
/// Handles BOTH types of changes messages, and will be called
/// after the vrpn_Analog_Output_Server class has already filled
/// in the values. It just calls the user callbacks with the
/// appropriate pointer to the data values.
static int VRPN_CALLBACK
handle_change_message(void* userdata, vrpn_HANDLERPARAM p);
/// List of user-level routines that need to be called back to let
/// them know that the values have changed.
vrpn_Callback_List<vrpn_ANALOGOUTPUTCB> d_callback_list;
};
// Open an analog output device that is on the other end of a connection
// and send updates to it. This is the type of analog output device
// that user code will deal with.
class VRPN_API vrpn_Analog_Output_Remote : public vrpn_Analog_Output {
public:
// The name of the analog device to connect to
// Optional argument to be used when the Remote should listen on
// a connection that is already open.
vrpn_Analog_Output_Remote(const char* name, vrpn_Connection* c = NULL);
virtual ~vrpn_Analog_Output_Remote(void);
// This routine calls the mainloop of the connection it's on
virtual void mainloop();
// Request the analog to change its value to the one specified.
// Returns false on failure.
virtual bool request_change_channel_value(
unsigned int chan, vrpn_float64 val,
vrpn_uint32 class_of_service = vrpn_CONNECTION_RELIABLE);
// Request the analog to change values all at once. If more values are
// given
// than we have channels, the extra values are discarded. If less values
// are
// given than we have channels, the extra channels are set to 0.
// Returns false on failure
virtual bool request_change_channels(
int num, vrpn_float64* vals,
vrpn_uint32 class_of_service = vrpn_CONNECTION_RELIABLE);
protected:
// How we hear about the number of active channels
static int VRPN_CALLBACK
handle_report_num_channels(void* userdata, vrpn_HANDLERPARAM p);
// Routines used to send requests from the client
virtual vrpn_int32 encode_change_to(char* buf, vrpn_int32 chan,
vrpn_float64 val);
virtual vrpn_int32 encode_change_channels_to(char* buf, vrpn_int32 num,
vrpn_float64* vals);
};
#endif