renet 0.1.14 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,6 +44,7 @@ VALUE renet_main_initialize(VALUE self)
44
44
  rb_cv_set(mENet, "@@initialized", Qtrue);
45
45
  return Qtrue;
46
46
  }
47
+ return Qtrue;
47
48
  }
48
49
 
49
50
  VALUE renet_main_deinitialize(VALUE self)
@@ -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", renet_connection_initialize, 5);
29
- rb_define_method(cENetConnection, "connect", renet_connection_connect, 1);
30
- rb_define_method(cENetConnection, "disconnect", renet_connection_disconnect, 1);
31
- rb_define_method(cENetConnection, "send_packet", renet_connection_send_packet, 3);
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", renet_connection_send_queued_packets, 0);
34
- rb_define_method(cENetConnection, "update", renet_connection_update, 1);
35
- rb_define_method(cENetConnection, "use_compression", renet_connection_use_compression, 1);
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", renet_connection_on_connection, 1);
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", renet_connection_on_disconnection, 1);
37
+ rb_define_method(cENetConnection, "on_disconnection", renet_connection_on_disconnection, 1);
40
38
 
41
- rb_define_method(cENetConnection, "online?", renet_connection_online, 0);
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
- free(((Connection*)connection)->event);
57
- free(((Connection*)connection)->address);
58
- enet_host_destroy(((Connection*)connection)->host);
59
- free((Connection*)connection);
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
- rb_funcall(mENet, rb_intern("initialize"), 0);
65
- Connection* connection;
66
- Data_Get_Struct(self, Connection, connection);
67
- Check_Type(host, T_STRING);
68
- if (enet_address_set_host(connection->address, StringValuePtr(host)) != 0)
69
- {
70
- rb_raise(rb_eStandardError, "Cannot set address");
71
- }
72
- connection->address->port = NUM2UINT(port);
73
- connection->channels = NUM2UINT(channels);
74
- connection->online = 0;
75
- connection->host = enet_host_create(NULL, 1, connection->channels, NUM2UINT(download), NUM2UINT(upload));
76
- if (connection->host == NULL)
77
- {
78
- rb_raise(rb_eStandardError, "Cannot create host");
79
- }
80
- rb_iv_set(self, "@total_sent_data", INT2FIX(0));
81
- rb_iv_set(self, "@total_received_data", INT2FIX(0));
82
- rb_iv_set(self, "@total_sent_packets", INT2FIX(0));
83
- rb_iv_set(self, "@total_received_packets", INT2FIX(0));
84
-
85
- rb_define_attr(cENetConnection, "total_sent_data", 1, 1);
86
- rb_define_attr(cENetConnection, "total_received_data", 1, 1);
87
- rb_define_attr(cENetConnection, "total_sent_packets", 1, 1);
88
- rb_define_attr(cENetConnection, "total_received_packets", 1, 1);
89
-
90
- return self;
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
- Connection* connection;
96
- Data_Get_Struct(self, Connection, connection);
97
- if (connection->online == 1)
98
- {
99
- return Qfalse;
100
- }
101
- connection->peer = enet_host_connect(connection->host, connection->address, connection->channels, 0);
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
- rb_raise(rb_eStandardError, "Cannot connect to remote host");
165
+ rb_raise(rb_eStandardError, "Cannot connect to remote host");
106
166
  }
107
167
 
108
- if (enet_host_service(connection->host, connection->event, NUM2UINT(timeout)) > 0 && connection->event->type == ENET_EVENT_TYPE_CONNECT)
168
+ if (service(self, connection, NUM2UINT(timeout)) > 0 && connection->event->type == ENET_EVENT_TYPE_CONNECT)
109
169
  {
110
- connection->online = 1;
111
- renet_connection_execute_on_connection();
112
- return Qtrue;
170
+ connection->online = 1;
171
+ renet_connection_execute_on_connection(self);
172
+ rv = Qtrue;
113
173
  }
114
174
  else
115
175
  {
116
- enet_peer_reset(connection->peer);
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
- Connection* connection;
125
- Data_Get_Struct(self, Connection, connection);
126
-
127
- enet_peer_disconnect(connection->peer, 0);
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
- while (enet_host_service(connection->host, connection->event, NUM2UINT(timeout)) > 0)
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
- case ENET_EVENT_TYPE_DISCONNECT:
138
- connection->online = 0;
139
- return Qtrue;
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
- connection->online = 0;
144
- return Qfalse;
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
- Connection* connection;
150
- Data_Get_Struct(self, Connection, connection);
151
- Check_Type(data, T_STRING);
152
- char* cdata = StringValuePtr(data);
153
- ENetPacket* packet;
154
- if (flag == Qtrue)
155
- {
156
- packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, ENET_PACKET_FLAG_RELIABLE);
157
- }
158
- else
159
- {
160
- packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, 0);
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
- return Qnil;
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
- Connection* connection;
169
- Data_Get_Struct(self, Connection, connection);
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
- return Qnil;
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
- Connection* connection;
177
- Data_Get_Struct(self, Connection, connection);
178
- if (connection->online == 0)
179
- {
180
- return Qfalse;
181
- }
182
- while (enet_host_service(connection->host, connection->event, NUM2UINT(timeout)) > 0)
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
- case ENET_EVENT_TYPE_NONE:
187
-
188
- break;
189
-
190
- case ENET_EVENT_TYPE_CONNECT:
191
-
192
- break;
193
-
194
- case ENET_EVENT_TYPE_RECEIVE:
195
- renet_connection_execute_on_packet_receive(connection->event->packet->data, connection->event->channelID);
196
- enet_packet_destroy(connection->event->packet);
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
- int tmp;
206
- tmp = NUM2INT(rb_iv_get(self, "@total_sent_data"));
207
- tmp = tmp + connection->host->totalSentData;
208
- connection->host->totalSentData = 0;
209
- rb_iv_set(self, "@total_sent_data", UINT2NUM(tmp));
210
-
211
- tmp = NUM2INT(rb_iv_get(self, "@total_received_data"));
212
- tmp = tmp + connection->host->totalReceivedData;
213
- connection->host->totalReceivedData = 0;
214
- rb_iv_set(self, "@total_received_data", UINT2NUM(tmp));
215
-
216
- tmp = NUM2INT(rb_iv_get(self, "@total_sent_packets"));
217
- tmp = tmp + connection->host->totalSentPackets;
218
- connection->host->totalSentPackets = 0;
219
- rb_iv_set(self, "@total_sent_packets", UINT2NUM(tmp));
220
-
221
- tmp = NUM2INT(rb_iv_get(self, "@total_received_packets"));
222
- tmp = tmp + connection->host->totalReceivedPackets;
223
- connection->host->totalReceivedPackets = 0;
224
- rb_iv_set(self, "@total_received_packets", UINT2NUM(tmp));
225
-
226
- return Qtrue;
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
- Connection* connection;
232
- Data_Get_Struct(self, Connection, connection);
233
- if (flag == Qtrue)
234
- {
235
- enet_host_compress_with_range_coder(connection->host);
236
- }
237
- else
238
- {
239
- enet_host_compress(connection->host, NULL);
240
- }
241
- return Qnil;
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 renet_connection_on_connection(VALUE self, VALUE method)
381
+ VALUE renet_connection_online(VALUE self)
245
382
  {
246
- /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
247
- rb_iv_set(cENetConnection, "@on_connection", method);
248
- return Qnil;
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
- void renet_connection_execute_on_connection()
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
- VALUE method = rb_iv_get(cENetConnection, "@on_connection");
254
- if (method != Qnil)
255
- {
256
- rb_funcall(method, rb_intern("call"), 0);
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
- VALUE renet_connection_on_packet_receive(VALUE self, VALUE method)
418
+ void renet_connection_execute_on_disconnection(VALUE self)
261
419
  {
262
-
263
- /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
264
- rb_iv_set(cENetConnection, "@on_packet_receive", method);
265
- return Qnil;
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
- /*VALUE renet_connection_on_packet_receive(int argc, VALUE *argv, VALUE self)
430
+ void renet_connection_execute_on_packet_receive(VALUE self, ENetPacket * const packet, enet_uint8 channelID)
269
431
  {
270
- VALUE block = Qnil;
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
- rb_scan_args(argc, argv, "0&", &block);
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
- void renet_connection_execute_on_packet_receive(enet_uint8* data, enet_uint8 channelID)
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
- VALUE method = rb_iv_get(cENetConnection, "@on_packet_receive");
288
- if (method != Qnil)
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
- VALUE renet_connection_on_disconnection(VALUE self, VALUE method)
462
+
463
+ VALUE renet_connection_on_packet_receive(VALUE self, VALUE method)
295
464
  {
296
- /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
297
- rb_iv_set(cENetConnection, "@on_disconnection", method);
298
- return Qnil;
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
- void renet_connection_execute_on_disconnection()
471
+ /*VALUE renet_connection_on_packet_receive(int argc, VALUE *argv, VALUE self)
302
472
  {
303
- VALUE method = rb_iv_get(cENetConnection, "@on_disconnection");
304
- if (method != Qnil)
305
- {
306
- rb_funcall(method, rb_intern("call"), 0);
307
- }
308
- }
473
+ VALUE block = Qnil;
309
474
 
310
- VALUE renet_connection_online(VALUE self)
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
- Connection* connection;
313
- Data_Get_Struct(self, Connection, connection);
314
- if (connection->online == 1)
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
+