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.
@@ -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
+