~hitmuri/vjpirate/trunk

« back to all changes in this revision

Viewing changes to os/win/include/vrpn_RedundantTransmission.h

  • Committer: Florent Berthaut
  • Date: 2014-07-26 18:53:16 UTC
  • mfrom: (5.1.12 mac)
  • Revision ID: flo@localhost.localdomain-20140726185316-c2ucnwmgm5kij4e2
Merged mac branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef VRPN_REDUNDANT_TRANSMISSION_H
 
2
#define VRPN_REDUNDANT_TRANSMISSION_H
 
3
 
 
4
/// @class vrpn_RedundantTransmission
 
5
/// Helper class for vrpn_Connection that automates redundant transmission
 
6
/// for unreliable (low-latency) messages.  Call pack_messages() here instead
 
7
/// of on your connection, and call mainloop() here before calling mainloop()
 
8
/// on your connection.
 
9
 
 
10
#include "vrpn_Shared.h"  // for timeval, types
 
11
#include "vrpn_BaseClass.h"
 
12
#include "vrpn_Connection.h"  // for vrpn_HANDLERPARAM, vrpn_Connection
 
13
 
 
14
class VRPN_API vrpn_RedundantTransmission {
 
15
 
 
16
  public:
 
17
 
 
18
    vrpn_RedundantTransmission (vrpn_Connection * c);
 
19
    ~vrpn_RedundantTransmission (void);
 
20
 
 
21
 
 
22
    // ACCESSORS
 
23
 
 
24
 
 
25
    vrpn_uint32 defaultRetransmissions (void) const;
 
26
    timeval defaultInterval (void) const;
 
27
    vrpn_bool isEnabled (void) const;
 
28
 
 
29
 
 
30
    // MANIPULATORS
 
31
 
 
32
 
 
33
    virtual void mainloop (void);
 
34
      ///< Determines which messages need to be resent and queues
 
35
      ///< them up on the connection for transmission.
 
36
 
 
37
    void enable (vrpn_bool);
 
38
 
 
39
    virtual void setDefaults (vrpn_uint32 numRetransmissions,
 
40
                              timeval transmissionInterval);
 
41
      ///< Set default values for future calls to pack_message().
 
42
 
 
43
    virtual int pack_message
 
44
      (vrpn_uint32 len, timeval time, vrpn_uint32 type,
 
45
       vrpn_uint32 sender, const char * buffer,
 
46
       vrpn_uint32 class_of_service,
 
47
       vrpn_int32 numRetransmissions = -1,
 
48
       timeval * transmissionInterval = NULL);
 
49
      ///< If !isEnabled(), does a normal pack_message(), but if isEnabled()
 
50
      ///< ignores class_of_service and sends it vrpn_CONNECTION_LOW_LATENCY,
 
51
      ///< sending it an additional number of times equal to numRetransmissions
 
52
      ///< at minimum intervals of transmissionInterval.
 
53
      ///< Specify -1 and NULL to use default values.
 
54
 
 
55
  protected:
 
56
 
 
57
    vrpn_Connection * d_connection;
 
58
 
 
59
    struct queuedMessage {
 
60
      vrpn_HANDLERPARAM p;
 
61
      vrpn_uint32 remainingTransmissions;
 
62
      timeval transmissionInterval;
 
63
      timeval nextValidTime;
 
64
      queuedMessage * next;
 
65
    };
 
66
 
 
67
    queuedMessage * d_messageList;
 
68
    vrpn_uint32 d_numMessagesQueued;
 
69
      ///< For debugging, mostly.
 
70
 
 
71
    // Default values.
 
72
 
 
73
    vrpn_uint32 d_numTransmissions;
 
74
    timeval d_transmissionInterval;
 
75
 
 
76
    vrpn_bool d_isEnabled;
 
77
 
 
78
 
 
79
};
 
80
 
 
81
 
 
82
struct vrpn_RedundantController_Protocol {
 
83
 
 
84
  char * encode_set (int * len, vrpn_uint32 num, timeval interval);
 
85
  void decode_set (const char ** buf, vrpn_uint32 * num, timeval * interval);
 
86
 
 
87
  char * encode_enable (int * len, vrpn_bool);
 
88
  void decode_enable (const char ** buf, vrpn_bool *);
 
89
 
 
90
  void register_types (vrpn_Connection *);
 
91
 
 
92
  vrpn_int32 d_set_type;
 
93
  vrpn_int32 d_enable_type;
 
94
};
 
95
 
 
96
 
 
97
/// @class vrpn_RedundantController
 
98
/// Accepts commands over a connection to control a local
 
99
/// vrpn_RedundantTransmission's default parameters.
 
100
  
 
101
class VRPN_API vrpn_RedundantController : public vrpn_BaseClass {
 
102
 
 
103
  public:
 
104
 
 
105
    vrpn_RedundantController (vrpn_RedundantTransmission *, vrpn_Connection *);
 
106
    ~vrpn_RedundantController (void);
 
107
 
 
108
    void mainloop (void);
 
109
      // Do nothing;  vrpn_BaseClass requires this.
 
110
 
 
111
  protected:
 
112
 
 
113
    virtual int register_types (void);
 
114
 
 
115
    vrpn_RedundantController_Protocol d_protocol;
 
116
 
 
117
    static int VRPN_CALLBACK handle_set (void *, vrpn_HANDLERPARAM);
 
118
    static int VRPN_CALLBACK handle_enable (void *, vrpn_HANDLERPARAM);
 
119
 
 
120
    vrpn_RedundantTransmission * d_object;
 
121
};
 
122
 
 
123
 
 
124
 
 
125
/// @class vrpn_RedundantRemote
 
126
/// Sends messages to a vrpn_RedundantController so that a
 
127
/// vrpn_RedundantTransmission on a server can be controlled from a client.
 
128
 
 
129
class VRPN_API vrpn_RedundantRemote : public vrpn_BaseClass {
 
130
 
 
131
  public:
 
132
 
 
133
    vrpn_RedundantRemote (vrpn_Connection *);
 
134
    ~vrpn_RedundantRemote (void);
 
135
 
 
136
    void mainloop (void);
 
137
      // Do nothing;  vrpn_BaseClass requires this.
 
138
 
 
139
    void set (int numRetransmissions, timeval transmissionInterval);
 
140
    void enable (vrpn_bool);
 
141
 
 
142
 
 
143
  protected:
 
144
 
 
145
    int register_types (void);
 
146
 
 
147
    vrpn_RedundantController_Protocol d_protocol;
 
148
};
 
149
 
 
150
 
 
151
 
 
152
 
 
153
/// @class vrpn_RedundantReceiver
 
154
/// Helper class that eliminates duplicates;  only the first instance of
 
155
/// a message is delivered.  Registers a callback on connection for any
 
156
/// type it's told to monitor;  when it gets a message back, checks its
 
157
/// list of recently-seen-timestamps for that type;  if it isn't on the
 
158
/// list, it's dispatched and replaces the oldest item on the list.
 
159
/// List length is limited, so
 
160
/// if too many messages of the same type (more than VRPN_RR_LENGTH) are
 
161
/// interleaved - if transmissionInterval * numRetransmissions >
 
162
/// VRPN_RR_LENGTH * the normal rate of message generation - it will not
 
163
/// detect the redundant messages.
 
164
 
 
165
// A TypeDispatcher insists on too much control of its table for
 
166
// us to use one here - we want to use the same indices as the
 
167
// vrpn_Connection we're attached to, but if we had our own TypeDispatcher
 
168
// we'd have an independent, inconsistent set of type & sender ids.
 
169
 
 
170
#define VRPN_RR_LENGTH 8
 
171
 
 
172
class VRPN_API vrpn_RedundantReceiver {
 
173
 
 
174
  public:
 
175
 
 
176
    vrpn_RedundantReceiver (vrpn_Connection *);
 
177
    ~vrpn_RedundantReceiver (void);
 
178
 
 
179
    virtual int register_handler (vrpn_int32 type,
 
180
                vrpn_MESSAGEHANDLER handler, void * userdata,
 
181
                vrpn_int32 sender = vrpn_ANY_SENDER);
 
182
    virtual int unregister_handler (vrpn_int32 type,
 
183
                vrpn_MESSAGEHANDLER handler, void * userdata,
 
184
                vrpn_int32 sender = vrpn_ANY_SENDER);
 
185
 
 
186
    void record (vrpn_bool);
 
187
      ///< Turns "memory" (tracking statistics of redundant reception)
 
188
      ///< on and off.
 
189
 
 
190
    void writeMemory (const char * filename);
 
191
      ///< Writes statistics to the named file:  timestamp of every message
 
192
      ///< received and number of copies of that message.  Detects partial
 
193
      ///< losses, but not when all copies are lost, since vrpn_RR doesn't
 
194
      ///< expect messages.
 
195
 
 
196
    void clearMemory (void);
 
197
      ///< Throws away / resets statistics.
 
198
 
 
199
  protected:
 
200
 
 
201
    vrpn_Connection * d_connection;
 
202
 
 
203
    struct VRPN_API RRRecord {
 
204
      RRRecord (void);
 
205
 
 
206
      timeval timestampSeen [VRPN_RR_LENGTH];
 
207
      int numSeen [VRPN_RR_LENGTH];
 
208
      int nextTimestampToReplace;
 
209
 
 
210
      vrpnMsgCallbackEntry * cb;
 
211
      vrpn_bool handlerIsRegistered;
 
212
    };
 
213
 
 
214
    RRRecord d_records [vrpn_CONNECTION_MAX_TYPES];
 
215
    RRRecord d_generic;
 
216
 
 
217
    struct RRMemory {
 
218
      timeval timestamp;
 
219
      int numSeen;
 
220
      RRMemory * next;
 
221
    };
 
222
 
 
223
    RRMemory * d_memory;
 
224
    RRMemory * d_lastMemory;
 
225
    vrpn_bool d_record;
 
226
 
 
227
    static int VRPN_CALLBACK handle_possiblyRedundantMessage (void *, vrpn_HANDLERPARAM); 
 
228
};
 
229
 
 
230
 
 
231
#endif  // VRPN_REDUNDANT_TRANSMISSION_H
 
232
 
 
233