renet 0.1.14 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README +6 -16
- data/ext/renet/callbacks.c +53 -0
- data/ext/renet/compress.c +654 -0
- data/ext/renet/enet/callbacks.h +27 -0
- data/ext/renet/enet/enet.h +592 -0
- data/ext/renet/enet/list.h +43 -0
- data/ext/renet/enet/protocol.h +198 -0
- data/ext/renet/enet/time.h +18 -0
- data/ext/renet/enet/types.h +13 -0
- data/ext/renet/enet/unix.h +47 -0
- data/ext/renet/enet/utility.h +12 -0
- data/ext/renet/enet/win32.h +57 -0
- data/ext/renet/extconf.rb +5 -16
- data/ext/renet/host.c +492 -0
- data/ext/renet/list.c +75 -0
- data/ext/renet/packet.c +165 -0
- data/ext/renet/peer.c +1004 -0
- data/ext/renet/protocol.c +1913 -0
- data/ext/renet/renet.c +1 -0
- data/ext/renet/renet_connection.c +383 -208
- data/ext/renet/renet_connection.h +3 -3
- data/ext/renet/renet_server.c +263 -159
- data/ext/renet/renet_server.h +5 -5
- data/ext/renet/unix.c +557 -0
- data/ext/renet/win32.c +478 -0
- data/lib/renet.rb +1 -16
- metadata +33 -16
data/ext/renet/renet.c
CHANGED
@@ -18,28 +18,31 @@
|
|
18
18
|
|
19
19
|
#include "renet_connection.h"
|
20
20
|
|
21
|
-
VALUE cENetConnection;
|
22
|
-
|
23
21
|
void init_renet_connection()
|
24
22
|
{
|
25
|
-
cENetConnection = rb_define_class_under(mENet, "Connection", rb_cObject);
|
23
|
+
VALUE cENetConnection = rb_define_class_under(mENet, "Connection", rb_cObject);
|
26
24
|
rb_define_alloc_func(cENetConnection, renet_connection_allocate);
|
27
25
|
|
28
|
-
rb_define_method(cENetConnection, "initialize",
|
29
|
-
rb_define_method(cENetConnection, "connect",
|
30
|
-
rb_define_method(cENetConnection, "disconnect",
|
31
|
-
rb_define_method(cENetConnection, "send_packet",
|
26
|
+
rb_define_method(cENetConnection, "initialize", renet_connection_initialize, 5);
|
27
|
+
rb_define_method(cENetConnection, "connect", renet_connection_connect, 1);
|
28
|
+
rb_define_method(cENetConnection, "disconnect", renet_connection_disconnect, 1);
|
29
|
+
rb_define_method(cENetConnection, "send_packet", renet_connection_send_packet, 3);
|
32
30
|
rb_define_method(cENetConnection, "send_queued_packets", renet_connection_send_queued_packets, 0);
|
33
|
-
rb_define_method(cENetConnection, "flush",
|
34
|
-
rb_define_method(cENetConnection, "update",
|
35
|
-
rb_define_method(cENetConnection, "use_compression",
|
31
|
+
rb_define_method(cENetConnection, "flush", renet_connection_send_queued_packets, 0);
|
32
|
+
rb_define_method(cENetConnection, "update", renet_connection_update, 1);
|
33
|
+
rb_define_method(cENetConnection, "use_compression", renet_connection_use_compression, 1);
|
36
34
|
|
37
|
-
rb_define_method(cENetConnection, "on_connection",
|
35
|
+
rb_define_method(cENetConnection, "on_connection", renet_connection_on_connection, 1);
|
38
36
|
rb_define_method(cENetConnection, "on_packet_receive", renet_connection_on_packet_receive, 1);
|
39
|
-
rb_define_method(cENetConnection, "on_disconnection",
|
37
|
+
rb_define_method(cENetConnection, "on_disconnection", renet_connection_on_disconnection, 1);
|
40
38
|
|
41
|
-
rb_define_method(cENetConnection, "online?",
|
39
|
+
rb_define_method(cENetConnection, "online?", renet_connection_online, 0);
|
42
40
|
rb_define_method(cENetConnection, "connected?", renet_connection_online, 0);
|
41
|
+
|
42
|
+
rb_define_attr(cENetConnection, "total_sent_data", 1, 1);
|
43
|
+
rb_define_attr(cENetConnection, "total_received_data", 1, 1);
|
44
|
+
rb_define_attr(cENetConnection, "total_sent_packets", 1, 1);
|
45
|
+
rb_define_attr(cENetConnection, "total_received_packets", 1, 1);
|
43
46
|
}
|
44
47
|
|
45
48
|
VALUE renet_connection_allocate(VALUE self)
|
@@ -53,270 +56,442 @@ VALUE renet_connection_allocate(VALUE self)
|
|
53
56
|
|
54
57
|
void renet_connection_deallocate(void* connection)
|
55
58
|
{
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
59
|
+
free(((Connection*)connection)->event);
|
60
|
+
free(((Connection*)connection)->address);
|
61
|
+
enet_host_destroy(((Connection*)connection)->host);
|
62
|
+
free((Connection*)connection);
|
60
63
|
}
|
61
64
|
|
62
65
|
VALUE renet_connection_initialize(VALUE self, VALUE host, VALUE port, VALUE channels, VALUE download, VALUE upload)
|
63
66
|
{
|
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
|
-
|
67
|
+
rb_funcall(mENet, rb_intern("initialize"), 0);
|
68
|
+
Connection* connection;
|
69
|
+
|
70
|
+
/* Now that we're releasing the GIL while waiting for enet_host_service
|
71
|
+
we need a lock to prevent potential segfaults if another thread tries
|
72
|
+
to do an operation on same connection */
|
73
|
+
VALUE lock = rb_mutex_new();
|
74
|
+
rb_iv_set(self, "@lock", lock);
|
75
|
+
rb_mutex_lock(lock);
|
76
|
+
|
77
|
+
Data_Get_Struct(self, Connection, connection);
|
78
|
+
Check_Type(host, T_STRING);
|
79
|
+
if (enet_address_set_host(connection->address, StringValuePtr(host)) != 0)
|
80
|
+
{
|
81
|
+
rb_raise(rb_eStandardError, "Cannot set address");
|
82
|
+
}
|
83
|
+
connection->address->port = NUM2UINT(port);
|
84
|
+
connection->channels = NUM2UINT(channels);
|
85
|
+
connection->online = 0;
|
86
|
+
connection->host = enet_host_create(NULL, 1, connection->channels, NUM2UINT(download), NUM2UINT(upload));
|
87
|
+
if (connection->host == NULL)
|
88
|
+
{
|
89
|
+
rb_raise(rb_eStandardError, "Cannot create host");
|
90
|
+
}
|
91
|
+
rb_iv_set(self, "@total_sent_data", INT2FIX(0));
|
92
|
+
rb_iv_set(self, "@total_received_data", INT2FIX(0));
|
93
|
+
rb_iv_set(self, "@total_sent_packets", INT2FIX(0));
|
94
|
+
rb_iv_set(self, "@total_received_packets", INT2FIX(0));
|
95
|
+
|
96
|
+
rb_mutex_unlock(lock);
|
97
|
+
return self;
|
91
98
|
}
|
92
99
|
|
100
|
+
|
101
|
+
|
102
|
+
/* These let us release the global interpreter lock if while we're waiting for
|
103
|
+
enet_host_service to finish:
|
104
|
+
|
105
|
+
CallbackData
|
106
|
+
do_service
|
107
|
+
service
|
108
|
+
*/
|
109
|
+
typedef struct
|
110
|
+
{
|
111
|
+
Connection * connection;
|
112
|
+
enet_uint32 timeout;
|
113
|
+
} CallbackData;
|
114
|
+
|
115
|
+
static VALUE do_service(void *data)
|
116
|
+
{
|
117
|
+
CallbackData* temp_data = data;
|
118
|
+
int result = enet_host_service(temp_data->connection->host, temp_data->connection->event, temp_data->timeout);
|
119
|
+
// this will do weird things with the negative numbers but we'll undo it on the other side
|
120
|
+
return (unsigned int)result;
|
121
|
+
}
|
122
|
+
|
123
|
+
static int service(VALUE self, Connection* connection, enet_uint32 timeout)
|
124
|
+
{
|
125
|
+
CallbackData data = {connection, timeout};
|
126
|
+
VALUE result;
|
127
|
+
if (timeout > 0)
|
128
|
+
{
|
129
|
+
result = rb_thread_blocking_region(do_service, &data, RUBY_UBF_IO, 0);
|
130
|
+
}
|
131
|
+
else
|
132
|
+
{
|
133
|
+
result = do_service(&data);
|
134
|
+
}
|
135
|
+
// undo our cast to VALUE in a way that will properly restore negative numbers
|
136
|
+
unsigned int fix_negatives = (unsigned int)result;
|
137
|
+
return (int)fix_negatives;
|
138
|
+
}
|
139
|
+
|
140
|
+
|
141
|
+
/* The core API functions for a connection:
|
142
|
+
renet_connection_connect
|
143
|
+
renet_connection_disconnect
|
144
|
+
renet_connection_send_packet
|
145
|
+
renet_connection_send_queued_packets
|
146
|
+
renet_connection_update
|
147
|
+
renet_connection_use_compression
|
148
|
+
renet_connection_online
|
149
|
+
*/
|
93
150
|
VALUE renet_connection_connect(VALUE self, VALUE timeout)
|
94
151
|
{
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
152
|
+
Connection* connection;
|
153
|
+
Data_Get_Struct(self, Connection, connection);
|
154
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
155
|
+
rb_mutex_lock(lock);
|
156
|
+
|
157
|
+
VALUE rv = Qfalse;
|
158
|
+
|
159
|
+
if (connection->online == 0)
|
160
|
+
{
|
161
|
+
connection->peer = enet_host_connect(connection->host, connection->address, connection->channels, 0);
|
162
|
+
|
103
163
|
if (connection->peer == NULL)
|
104
164
|
{
|
105
|
-
|
165
|
+
rb_raise(rb_eStandardError, "Cannot connect to remote host");
|
106
166
|
}
|
107
167
|
|
108
|
-
if (
|
168
|
+
if (service(self, connection, NUM2UINT(timeout)) > 0 && connection->event->type == ENET_EVENT_TYPE_CONNECT)
|
109
169
|
{
|
110
|
-
|
111
|
-
|
112
|
-
|
170
|
+
connection->online = 1;
|
171
|
+
renet_connection_execute_on_connection(self);
|
172
|
+
rv = Qtrue;
|
113
173
|
}
|
114
174
|
else
|
115
175
|
{
|
116
|
-
|
117
|
-
return Qfalse;
|
176
|
+
enet_peer_reset(connection->peer);
|
118
177
|
}
|
119
|
-
|
178
|
+
}
|
179
|
+
|
180
|
+
rb_mutex_unlock(lock);
|
181
|
+
return rv;
|
120
182
|
}
|
121
183
|
|
122
184
|
VALUE renet_connection_disconnect(VALUE self, VALUE timeout)
|
123
185
|
{
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
186
|
+
Connection* connection;
|
187
|
+
Data_Get_Struct(self, Connection, connection);
|
188
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
189
|
+
rb_mutex_lock(lock);
|
128
190
|
|
129
|
-
|
130
|
-
{
|
131
|
-
switch (connection->event->type)
|
132
|
-
{
|
133
|
-
case ENET_EVENT_TYPE_RECEIVE:
|
134
|
-
enet_packet_destroy (connection->event->packet);
|
135
|
-
break;
|
191
|
+
VALUE rv = Qfalse;
|
136
192
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
193
|
+
if (connection->online == 0)
|
194
|
+
{
|
195
|
+
rv = Qtrue;
|
196
|
+
}
|
197
|
+
else
|
198
|
+
{
|
199
|
+
connection->online = 0;
|
200
|
+
enet_peer_disconnect(connection->peer, 0);
|
201
|
+
|
202
|
+
while (service(self, connection, NUM2UINT(timeout)) > 0)
|
203
|
+
{
|
204
|
+
switch (connection->event->type)
|
205
|
+
{
|
206
|
+
case ENET_EVENT_TYPE_NONE:
|
207
|
+
break;
|
208
|
+
case ENET_EVENT_TYPE_CONNECT:
|
209
|
+
break;
|
210
|
+
case ENET_EVENT_TYPE_RECEIVE:
|
211
|
+
enet_packet_destroy (connection->event->packet);
|
212
|
+
break;
|
213
|
+
case ENET_EVENT_TYPE_DISCONNECT:
|
214
|
+
rv = Qtrue;
|
215
|
+
break;
|
216
|
+
}
|
217
|
+
if (rv == Qtrue)
|
218
|
+
{
|
219
|
+
break;
|
220
|
+
}
|
141
221
|
}
|
142
|
-
enet_peer_disconnect_now(connection->peer, 0);
|
143
|
-
|
144
|
-
|
222
|
+
if (rv != Qtrue) { enet_peer_disconnect_now(connection->peer, 0); }
|
223
|
+
}
|
224
|
+
rb_mutex_unlock(lock);
|
225
|
+
return rv;
|
145
226
|
}
|
146
227
|
|
147
228
|
VALUE renet_connection_send_packet(VALUE self, VALUE data, VALUE flag, VALUE channel)
|
148
229
|
{
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
230
|
+
Connection* connection;
|
231
|
+
Data_Get_Struct(self, Connection, connection);
|
232
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
233
|
+
rb_mutex_lock(lock);
|
234
|
+
|
235
|
+
Check_Type(data, T_STRING);
|
236
|
+
char* cdata = StringValuePtr(data);
|
237
|
+
ENetPacket* packet;
|
238
|
+
if (connection->online != 0)
|
239
|
+
{
|
240
|
+
if (flag == Qtrue)
|
241
|
+
{
|
242
|
+
packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
243
|
+
}
|
244
|
+
else
|
245
|
+
{
|
246
|
+
packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, 0);
|
247
|
+
}
|
162
248
|
enet_peer_send(connection->peer, NUM2UINT(channel), packet);
|
163
|
-
|
249
|
+
}
|
250
|
+
|
251
|
+
rb_mutex_unlock(lock);
|
252
|
+
return Qnil;
|
164
253
|
}
|
165
254
|
|
166
255
|
VALUE renet_connection_send_queued_packets(VALUE self)
|
167
256
|
{
|
168
|
-
|
169
|
-
|
257
|
+
Connection* connection;
|
258
|
+
Data_Get_Struct(self, Connection, connection);
|
259
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
260
|
+
rb_mutex_lock(lock);
|
261
|
+
|
262
|
+
if (connection->online != 0)
|
263
|
+
{
|
170
264
|
enet_host_flush(connection->host);
|
171
|
-
|
265
|
+
}
|
266
|
+
|
267
|
+
rb_mutex_unlock(lock);
|
268
|
+
return Qnil;
|
172
269
|
}
|
173
270
|
|
174
271
|
VALUE renet_connection_update(VALUE self, VALUE timeout)
|
175
272
|
{
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
273
|
+
Connection* connection;
|
274
|
+
Data_Get_Struct(self, Connection, connection);
|
275
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
276
|
+
rb_mutex_lock(lock);
|
277
|
+
|
278
|
+
VALUE rv = Qfalse;
|
279
|
+
|
280
|
+
if (connection->online != 0)
|
281
|
+
{
|
282
|
+
/* wait up to timeout milliseconds for a packet */
|
283
|
+
if (service(self, connection, NUM2UINT(timeout)) > 0)
|
183
284
|
{
|
285
|
+
do
|
286
|
+
{
|
184
287
|
switch (connection->event->type)
|
185
288
|
{
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
break;
|
198
|
-
|
199
|
-
case ENET_EVENT_TYPE_DISCONNECT:
|
200
|
-
connection->online = 0;
|
201
|
-
renet_connection_execute_on_disconnection();
|
289
|
+
case ENET_EVENT_TYPE_NONE:
|
290
|
+
break;
|
291
|
+
case ENET_EVENT_TYPE_CONNECT:
|
292
|
+
break;
|
293
|
+
case ENET_EVENT_TYPE_RECEIVE:
|
294
|
+
renet_connection_execute_on_packet_receive(self, connection->event->packet, connection->event->channelID);
|
295
|
+
break;
|
296
|
+
case ENET_EVENT_TYPE_DISCONNECT:
|
297
|
+
connection->online = 0;
|
298
|
+
renet_connection_execute_on_disconnection(self);
|
299
|
+
break;
|
202
300
|
}
|
301
|
+
}
|
302
|
+
/* Do not use a timeout for subsequent services or we could get stuck
|
303
|
+
here forever */
|
304
|
+
while ((connection->online != 0) && (service(self, connection, 0) > 0));
|
203
305
|
}
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
306
|
+
|
307
|
+
rv = Qtrue;
|
308
|
+
}
|
309
|
+
|
310
|
+
/* we are unlocking now because it's important to unlock before going
|
311
|
+
back into ruby land (which rb_funcall will do). If we don't then an
|
312
|
+
exception can leave the locks in an inconsistent state */
|
313
|
+
rb_mutex_unlock(lock);
|
314
|
+
|
315
|
+
if (rv == Qtrue)
|
316
|
+
{
|
317
|
+
{
|
318
|
+
VALUE total = rb_iv_get(self, "@total_sent_data");
|
319
|
+
VALUE result = rb_funcall( total
|
320
|
+
, rb_intern("+")
|
321
|
+
, 1
|
322
|
+
, UINT2NUM(connection->host->totalSentData));
|
323
|
+
rb_iv_set(self, "@total_sent_data", result);
|
324
|
+
connection->host->totalSentData = 0;
|
325
|
+
}
|
326
|
+
|
327
|
+
{
|
328
|
+
VALUE total = rb_iv_get(self, "@total_received_data");
|
329
|
+
VALUE result = rb_funcall( total
|
330
|
+
, rb_intern("+")
|
331
|
+
, 1
|
332
|
+
, UINT2NUM(connection->host->totalReceivedData));
|
333
|
+
rb_iv_set(self, "@total_received_data", result);
|
334
|
+
connection->host->totalReceivedData = 0;
|
335
|
+
}
|
336
|
+
|
337
|
+
{
|
338
|
+
VALUE total = rb_iv_get(self, "@total_sent_packets");
|
339
|
+
VALUE result = rb_funcall( total
|
340
|
+
, rb_intern("+")
|
341
|
+
, 1
|
342
|
+
, UINT2NUM(connection->host->totalSentPackets));
|
343
|
+
rb_iv_set(self, "@total_sent_packets", result);
|
344
|
+
connection->host->totalSentPackets = 0;
|
345
|
+
}
|
346
|
+
|
347
|
+
{
|
348
|
+
VALUE total = rb_iv_get(self, "@total_received_packets");
|
349
|
+
VALUE result = rb_funcall( total
|
350
|
+
, rb_intern("+")
|
351
|
+
, 1
|
352
|
+
, UINT2NUM(connection->host->totalReceivedPackets));
|
353
|
+
rb_iv_set(self, "@total_received_packets", result);
|
354
|
+
connection->host->totalReceivedPackets = 0;
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
return rv;
|
227
359
|
}
|
228
360
|
|
229
361
|
VALUE renet_connection_use_compression(VALUE self, VALUE flag)
|
230
362
|
{
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
363
|
+
Connection* connection;
|
364
|
+
Data_Get_Struct(self, Connection, connection);
|
365
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
366
|
+
rb_mutex_lock(lock);
|
367
|
+
|
368
|
+
if (flag == Qtrue)
|
369
|
+
{
|
370
|
+
enet_host_compress_with_range_coder(connection->host);
|
371
|
+
}
|
372
|
+
else
|
373
|
+
{
|
374
|
+
enet_host_compress(connection->host, NULL);
|
375
|
+
}
|
376
|
+
|
377
|
+
rb_mutex_unlock(lock);
|
378
|
+
return Qnil;
|
242
379
|
}
|
243
380
|
|
244
|
-
VALUE
|
381
|
+
VALUE renet_connection_online(VALUE self)
|
245
382
|
{
|
246
|
-
|
247
|
-
|
248
|
-
|
383
|
+
Connection* connection;
|
384
|
+
Data_Get_Struct(self, Connection, connection);
|
385
|
+
if (connection->online == 1)
|
386
|
+
{
|
387
|
+
return Qtrue;
|
388
|
+
}
|
389
|
+
else
|
390
|
+
{
|
391
|
+
return Qfalse;
|
392
|
+
}
|
249
393
|
}
|
250
394
|
|
251
|
-
|
395
|
+
/* These call our callbacks and take us back into ruby land.
|
396
|
+
They also unlock the mutex for the duration of our stay. we have to be
|
397
|
+
careful to make this safe. For example if we didn't set connection->online
|
398
|
+
= 1 before calling renet_connection_execute_on_connection we could possibly
|
399
|
+
segfault if we called connect from inside on_connection
|
400
|
+
|
401
|
+
renet_connection_execute_on_connection
|
402
|
+
renet_connection_execute_on_disconnection
|
403
|
+
renet_connection_execute_on_packet_receive
|
404
|
+
*/
|
405
|
+
|
406
|
+
void renet_connection_execute_on_connection(VALUE self)
|
252
407
|
{
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
408
|
+
VALUE method = rb_iv_get(self, "@on_connection");
|
409
|
+
if (method != Qnil)
|
410
|
+
{
|
411
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
412
|
+
rb_mutex_unlock(lock);
|
413
|
+
rb_funcall(method, rb_intern("call"), 0);
|
414
|
+
rb_mutex_lock(lock);
|
415
|
+
}
|
258
416
|
}
|
259
417
|
|
260
|
-
|
418
|
+
void renet_connection_execute_on_disconnection(VALUE self)
|
261
419
|
{
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
420
|
+
VALUE method = rb_iv_get(self, "@on_disconnection");
|
421
|
+
if (method != Qnil)
|
422
|
+
{
|
423
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
424
|
+
rb_mutex_unlock(lock);
|
425
|
+
rb_funcall(method, rb_intern("call"), 0);
|
426
|
+
rb_mutex_lock(lock);
|
427
|
+
}
|
266
428
|
}
|
267
429
|
|
268
|
-
|
430
|
+
void renet_connection_execute_on_packet_receive(VALUE self, ENetPacket * const packet, enet_uint8 channelID)
|
269
431
|
{
|
270
|
-
|
432
|
+
VALUE method = rb_iv_get(self, "@on_packet_receive");
|
433
|
+
VALUE data = rb_str_new((char const *)packet->data, packet->dataLength);
|
434
|
+
/* marshal data and then destroy packet
|
435
|
+
if we don't do this now the packet might become invalid before we get
|
436
|
+
back and we'd get a segfault when we attempt to destroy */
|
437
|
+
enet_packet_destroy(packet);
|
271
438
|
|
272
|
-
|
439
|
+
if (method != Qnil)
|
440
|
+
{
|
441
|
+
VALUE lock = rb_iv_get(self, "@lock");
|
442
|
+
rb_mutex_unlock(lock);
|
443
|
+
rb_funcall(method, rb_intern("call"), 2, data, UINT2NUM(channelID));
|
444
|
+
rb_mutex_lock(lock);
|
445
|
+
}
|
446
|
+
}
|
273
447
|
|
274
|
-
if (RTEST(block))
|
275
|
-
{
|
276
|
-
rb_iv_set(cENetConnection, "@on_packet_receive", block);
|
277
|
-
}
|
278
|
-
else
|
279
|
-
{
|
280
|
-
rb_raise(rb_eArgError, "a block is required");
|
281
|
-
}
|
282
|
-
return Qnil;
|
283
|
-
}*/
|
284
448
|
|
285
|
-
|
449
|
+
/* These set the callbacks to call on important events:
|
450
|
+
renet_connection_on_connection
|
451
|
+
renet_connection_on_packet_receive
|
452
|
+
renet_connection_on_disconnection
|
453
|
+
*/
|
454
|
+
|
455
|
+
VALUE renet_connection_on_connection(VALUE self, VALUE method)
|
286
456
|
{
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
rb_funcall(method, rb_intern("call"), 2, rb_str_new2(data), UINT2NUM(channelID));
|
291
|
-
}
|
457
|
+
/*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
|
458
|
+
rb_iv_set(self, "@on_connection", method);
|
459
|
+
return Qnil;
|
292
460
|
}
|
293
461
|
|
294
|
-
|
462
|
+
|
463
|
+
VALUE renet_connection_on_packet_receive(VALUE self, VALUE method)
|
295
464
|
{
|
296
|
-
|
297
|
-
|
298
|
-
|
465
|
+
|
466
|
+
/*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
|
467
|
+
rb_iv_set(self, "@on_packet_receive", method);
|
468
|
+
return Qnil;
|
299
469
|
}
|
300
470
|
|
301
|
-
|
471
|
+
/*VALUE renet_connection_on_packet_receive(int argc, VALUE *argv, VALUE self)
|
302
472
|
{
|
303
|
-
|
304
|
-
if (method != Qnil)
|
305
|
-
{
|
306
|
-
rb_funcall(method, rb_intern("call"), 0);
|
307
|
-
}
|
308
|
-
}
|
473
|
+
VALUE block = Qnil;
|
309
474
|
|
310
|
-
|
475
|
+
rb_scan_args(argc, argv, "0&", &block);
|
476
|
+
|
477
|
+
if (RTEST(block))
|
478
|
+
{
|
479
|
+
rb_iv_set(cENetConnection, "@on_packet_receive", block);
|
480
|
+
}
|
481
|
+
else
|
482
|
+
{
|
483
|
+
rb_raise(rb_eArgError, "a block is required");
|
484
|
+
}
|
485
|
+
return Qnil;
|
486
|
+
}*/
|
487
|
+
|
488
|
+
VALUE renet_connection_on_disconnection(VALUE self, VALUE method)
|
311
489
|
{
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
{
|
316
|
-
return Qtrue;
|
317
|
-
}
|
318
|
-
else
|
319
|
-
{
|
320
|
-
return Qfalse;
|
321
|
-
}
|
490
|
+
/*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
|
491
|
+
rb_iv_set(self, "@on_disconnection", method);
|
492
|
+
return Qnil;
|
322
493
|
}
|
494
|
+
|
495
|
+
|
496
|
+
|
497
|
+
|