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.
@@ -27,7 +27,7 @@ typedef struct {
27
27
  ENetEvent* event;
28
28
  ENetAddress* address;
29
29
  int channels;
30
- int online;
30
+ int online;
31
31
  } Connection;
32
32
 
33
33
  void init_renet_connection();
@@ -48,10 +48,10 @@ void renet_connection_execute_on_connection();
48
48
 
49
49
  VALUE renet_connection_on_packet_receive(VALUE self, VALUE method);
50
50
  /*VALUE renet_connection_on_packet_receive(int argc, VALUE *argv, VALUE self);*/
51
- void renet_connection_execute_on_packet_receive(enet_uint8* data, enet_uint8 channelID);
51
+ void renet_connection_execute_on_packet_receive(VALUE self, ENetPacket * const packet, enet_uint8 channelID);
52
52
 
53
53
  VALUE renet_connection_on_disconnection(VALUE self, VALUE method);
54
- void renet_connection_execute_on_disconnection();
54
+ void renet_connection_execute_on_disconnection(VALUE self);
55
55
 
56
56
  VALUE renet_connection_online(VALUE self);
57
57
 
@@ -18,11 +18,10 @@
18
18
 
19
19
  #include "renet_server.h"
20
20
 
21
- VALUE cENetServer;
22
21
 
23
22
  void init_renet_server()
24
23
  {
25
- cENetServer = rb_define_class_under(mENet, "Server", rb_cObject);
24
+ VALUE cENetServer = rb_define_class_under(mENet, "Server", rb_cObject);
26
25
  rb_define_alloc_func(cENetServer, renet_server_allocate);
27
26
 
28
27
  rb_define_method(cENetServer, "initialize", renet_server_initialize, 5);
@@ -40,6 +39,11 @@ void init_renet_server()
40
39
 
41
40
  rb_define_method(cENetServer, "max_clients", renet_server_max_clients, 0);
42
41
  rb_define_method(cENetServer, "clients_count", renet_server_clients_count, 0);
42
+
43
+ rb_define_attr(cENetServer, "total_sent_data", 1, 1);
44
+ rb_define_attr(cENetServer, "total_received_data", 1, 1);
45
+ rb_define_attr(cENetServer, "total_sent_packets", 1, 1);
46
+ rb_define_attr(cENetServer, "total_received_packets", 1, 1);
43
47
  }
44
48
 
45
49
  VALUE renet_server_allocate(VALUE self)
@@ -54,227 +58,327 @@ VALUE renet_server_allocate(VALUE self)
54
58
 
55
59
  void renet_server_deallocate(void* server)
56
60
  {
57
- free(((Server*)server)->event);
58
- free(((Server*)server)->address);
59
- enet_host_destroy(((Server*)server)->host);
60
- free((Server*)server);
61
+ free(((Server*)server)->event);
62
+ free(((Server*)server)->address);
63
+ enet_host_destroy(((Server*)server)->host);
64
+ free((Server*)server);
61
65
  }
62
66
 
63
67
  VALUE renet_server_initialize(VALUE self, VALUE port, VALUE n_peers, VALUE channels, VALUE download, VALUE upload)
64
68
  {
65
- rb_funcall(mENet, rb_intern("initialize"), 0);
66
- Server* server;
67
- Data_Get_Struct(self, Server, server);
68
-
69
- server->address->host = ENET_HOST_ANY;
70
- server->address->port = NUM2UINT(port);
71
- server->channels = NUM2UINT(channels);
72
- server->host = enet_host_create(server->address, NUM2UINT(n_peers), server->channels, NUM2UINT(download), NUM2UINT(upload));
73
- if (server->host == NULL)
69
+ rb_funcall(mENet, rb_intern("initialize"), 0);
70
+ Server* server;
71
+ Data_Get_Struct(self, Server, server);
72
+
73
+ VALUE lock = rb_mutex_new();
74
+ rb_iv_set(self, "@lock", lock);
75
+ rb_mutex_lock(lock);
76
+
77
+ server->address->host = ENET_HOST_ANY;
78
+ server->address->port = NUM2UINT(port);
79
+ server->channels = NUM2UINT(channels);
80
+ server->host = enet_host_create(server->address, NUM2UINT(n_peers), server->channels, NUM2UINT(download), NUM2UINT(upload));
81
+ if (server->host == NULL)
74
82
  {
75
- rb_raise(rb_eStandardError, "Cannot create server");
76
- }
77
- rb_iv_set(self, "@total_sent_data", INT2FIX(0));
78
- rb_iv_set(self, "@total_received_data", INT2FIX(0));
79
- rb_iv_set(self, "@total_sent_packets", INT2FIX(0));
80
- rb_iv_set(self, "@total_received_packets", INT2FIX(0));
81
-
82
- rb_define_attr(cENetServer, "total_sent_data", 1, 1);
83
- rb_define_attr(cENetServer, "total_received_data", 1, 1);
84
- rb_define_attr(cENetServer, "total_sent_packets", 1, 1);
85
- rb_define_attr(cENetServer, "total_received_packets", 1, 1);
86
-
87
- return self;
83
+ rb_raise(rb_eStandardError, "Cannot create server");
84
+ }
85
+ rb_iv_set(self, "@total_sent_data", INT2FIX(0));
86
+ rb_iv_set(self, "@total_received_data", INT2FIX(0));
87
+ rb_iv_set(self, "@total_sent_packets", INT2FIX(0));
88
+ rb_iv_set(self, "@total_received_packets", INT2FIX(0));
89
+
90
+ rb_mutex_unlock(lock);
91
+
92
+ return self;
88
93
  }
89
94
 
90
95
  VALUE renet_server_disconnect_client(VALUE self, VALUE peer_id)
91
96
  {
92
- Server* server;
93
- Data_Get_Struct(self, Server, server);
94
- enet_peer_disconnect_now(&(server->host->peers[NUM2UINT(peer_id)]), 0);
95
- renet_server_execute_on_disconnection(peer_id);
96
- return Qtrue;
97
+ Server* server;
98
+ Data_Get_Struct(self, Server, server);
99
+ VALUE lock = rb_iv_get(self, "@lock");
100
+ rb_mutex_lock(lock);
101
+ enet_peer_disconnect_now(&(server->host->peers[NUM2UINT(peer_id)]), 0);
102
+ renet_server_execute_on_disconnection(self, peer_id);
103
+ rb_mutex_unlock(lock);
104
+ return Qtrue;
97
105
  }
98
106
 
99
107
  VALUE renet_server_send_packet(VALUE self, VALUE peer_id, VALUE data, VALUE flag, VALUE channel)
100
108
  {
101
- Server* server;
102
- Data_Get_Struct(self, Server, server);
103
- Check_Type(data, T_STRING);
104
- char* cdata = StringValuePtr(data);
105
- ENetPacket* packet;
106
- if (flag == Qtrue)
107
- {
108
- packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, ENET_PACKET_FLAG_RELIABLE);
109
- }
110
- else
111
- {
112
- packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, 0);
113
- }
109
+ Server* server;
110
+ Data_Get_Struct(self, Server, server);
111
+ VALUE lock = rb_iv_get(self, "@lock");
112
+ rb_mutex_lock(lock);
113
+ Check_Type(data, T_STRING);
114
+ char* cdata = StringValuePtr(data);
115
+ ENetPacket* packet;
116
+ if (flag == Qtrue)
117
+ {
118
+ packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, ENET_PACKET_FLAG_RELIABLE);
119
+ }
120
+ else
121
+ {
122
+ packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, 0);
123
+ }
114
124
  enet_peer_send(&(server->host->peers[NUM2UINT(peer_id)]), NUM2UINT(channel), packet);
115
- return Qnil;
125
+ rb_mutex_unlock(lock);
126
+ return Qnil;
116
127
  }
117
128
 
118
129
  VALUE renet_server_broadcast_packet(VALUE self, VALUE data, VALUE flag, VALUE channel)
119
130
  {
120
- Server* server;
121
- Data_Get_Struct(self, Server, server);
122
- Check_Type(data, T_STRING);
123
- char* cdata = StringValuePtr(data);
124
- ENetPacket* packet;
125
- if (flag == Qtrue)
126
- {
127
- packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, ENET_PACKET_FLAG_RELIABLE);
128
- }
129
- else
130
- {
131
- packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, 0);
132
- }
131
+ Server* server;
132
+ Data_Get_Struct(self, Server, server);
133
+ VALUE lock = rb_iv_get(self, "@lock");
134
+ rb_mutex_lock(lock);
135
+ Check_Type(data, T_STRING);
136
+ char* cdata = StringValuePtr(data);
137
+ ENetPacket* packet;
138
+ if (flag == Qtrue)
139
+ {
140
+ packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, ENET_PACKET_FLAG_RELIABLE);
141
+ }
142
+ else
143
+ {
144
+ packet = enet_packet_create(cdata, RSTRING_LEN(data) + 1, 0);
145
+ }
133
146
  enet_host_broadcast(server->host, NUM2UINT(channel), packet);
134
- return Qnil;
147
+ rb_mutex_unlock(lock);
148
+ return Qnil;
135
149
  }
136
150
 
137
151
  VALUE renet_server_send_queued_packets(VALUE self)
138
152
  {
139
- Server* server;
140
- Data_Get_Struct(self, Server, server);
153
+ Server* server;
154
+ Data_Get_Struct(self, Server, server);
155
+ VALUE lock = rb_iv_get(self, "@lock");
156
+ rb_mutex_lock(lock);
141
157
  enet_host_flush(server->host);
158
+ rb_mutex_unlock(lock);
142
159
  return Qnil;
143
160
  }
144
161
 
162
+ /* These let us release the global interpreter lock if while we're waiting for
163
+ enet_host_service to finish:
164
+
165
+ CallbackData
166
+ do_service
167
+ service
168
+ */
169
+ typedef struct
170
+ {
171
+ Server * server;
172
+ enet_uint32 timeout;
173
+ } CallbackData;
174
+
175
+ static VALUE do_service(void *data)
176
+ {
177
+ CallbackData* temp_data = data;
178
+ int result = enet_host_service(temp_data->server->host, temp_data->server->event, temp_data->timeout);
179
+ // this will do weird things with the negative numbers but we'll undo it on the other side
180
+ return (unsigned int)result;
181
+ }
182
+
183
+ static int service(VALUE self, Server* server, enet_uint32 timeout)
184
+ {
185
+ CallbackData data = {server, timeout};
186
+ VALUE result;
187
+ if (timeout > 0)
188
+ {
189
+ result = rb_thread_blocking_region(do_service, &data, RUBY_UBF_IO, 0);
190
+ }
191
+ else
192
+ {
193
+ result = do_service(&data);
194
+ }
195
+ // undo our cast to VALUE in a way that will properly restore negative numbers
196
+ unsigned int fix_negatives = (unsigned int)result;
197
+ return (int)fix_negatives;
198
+ }
199
+
145
200
  VALUE renet_server_update(VALUE self, VALUE timeout)
146
201
  {
147
- Server* server;
148
- Data_Get_Struct(self, Server, server);
149
- int peer_id;
150
-
151
- while (enet_host_service(server->host, server->event, NUM2UINT(timeout)) > 0)
202
+ Server* server;
203
+ Data_Get_Struct(self, Server, server);
204
+ VALUE lock = rb_iv_get(self, "@lock");
205
+ rb_mutex_lock(lock);
206
+ int peer_id;
207
+
208
+ /* wait up to timeout milliseconds for a packet */
209
+ if (service(self, server, NUM2UINT(timeout)) > 0)
210
+ {
211
+ do
152
212
  {
153
- switch (server->event->type)
154
- {
155
- case ENET_EVENT_TYPE_NONE:
156
-
157
- break;
158
-
159
- case ENET_EVENT_TYPE_CONNECT:
160
- server->n_clients += 1;
161
- enet_address_get_host_ip(&(server->event->peer->address), server->conn_ip, 20);
162
- peer_id = (int)(server->event->peer - server->host->peers);
163
- renet_server_execute_on_connection(INT2NUM(peer_id), rb_str_new2(server->conn_ip));
164
- break;
165
-
166
- case ENET_EVENT_TYPE_RECEIVE:
167
- peer_id = (int)(server->event->peer - server->host->peers);
168
- renet_server_execute_on_packet_receive(INT2NUM(peer_id), server->event->packet->data, server->event->channelID);
169
- enet_packet_destroy(server->event->packet);
170
- break;
171
-
172
- case ENET_EVENT_TYPE_DISCONNECT:
173
- server->n_clients -= 1;
174
- peer_id = (int)(server->event->peer - server->host->peers);
175
- renet_server_execute_on_disconnection(INT2NUM(peer_id));
176
- }
213
+ switch (server->event->type)
214
+ {
215
+ case ENET_EVENT_TYPE_NONE:
216
+ break;
217
+
218
+ case ENET_EVENT_TYPE_CONNECT:
219
+ server->n_clients += 1;
220
+ enet_address_get_host_ip(&(server->event->peer->address), server->conn_ip, 20);
221
+ peer_id = (int)(server->event->peer - server->host->peers);
222
+ renet_server_execute_on_connection(self, INT2NUM(peer_id), rb_str_new2(server->conn_ip));
223
+ break;
224
+
225
+ case ENET_EVENT_TYPE_RECEIVE:
226
+ peer_id = (int)(server->event->peer - server->host->peers);
227
+ renet_server_execute_on_packet_receive(self, INT2NUM(peer_id), server->event->packet, server->event->channelID);
228
+ break;
229
+
230
+ case ENET_EVENT_TYPE_DISCONNECT:
231
+ server->n_clients -= 1;
232
+ peer_id = (int)(server->event->peer - server->host->peers);
233
+ server->event->peer->data = NULL;
234
+ renet_server_execute_on_disconnection(self, INT2NUM(peer_id));
235
+ break;
236
+ }
177
237
  }
238
+ while (service(self, server, 0) > 0);
239
+ }
240
+
241
+ /* we are unlocking now because it's important to unlock before going
242
+ back into ruby land (which rb_funcall will do). If we don't then an
243
+ exception can leave the locks in an inconsistent state */
244
+ rb_mutex_unlock(lock);
245
+
246
+ {
247
+ VALUE total = rb_iv_get(self, "@total_sent_data");
248
+ VALUE result = rb_funcall( total
249
+ , rb_intern("+")
250
+ , 1
251
+ , UINT2NUM(server->host->totalSentData));
252
+ rb_iv_set(self, "@total_sent_data", result);
253
+ server->host->totalSentData = 0;
254
+ }
255
+
256
+ {
257
+ VALUE total = rb_iv_get(self, "@total_received_data");
258
+ VALUE result = rb_funcall( total
259
+ , rb_intern("+")
260
+ , 1
261
+ , UINT2NUM(server->host->totalReceivedData));
262
+ rb_iv_set(self, "@total_received_data", result);
263
+ server->host->totalReceivedData = 0;
264
+ }
178
265
 
179
- int tmp;
180
- tmp = NUM2INT(rb_iv_get(self, "@total_sent_data"));
181
- tmp = tmp + server->host->totalSentData;
182
- server->host->totalSentData = 0;
183
- rb_iv_set(self, "@total_sent_data", UINT2NUM(tmp));
184
-
185
- tmp = NUM2INT(rb_iv_get(self, "@total_received_data"));
186
- tmp = tmp + server->host->totalReceivedData;
187
- server->host->totalReceivedData = 0;
188
- rb_iv_set(self, "@total_received_data", UINT2NUM(tmp));
189
-
190
- tmp = NUM2INT(rb_iv_get(self, "@total_sent_packets"));
191
- tmp = tmp + server->host->totalSentPackets;
192
- server->host->totalSentPackets = 0;
193
- rb_iv_set(self, "@total_sent_packets", UINT2NUM(tmp));
194
-
195
- tmp = NUM2INT(rb_iv_get(self, "@total_received_packets"));
196
- tmp = tmp + server->host->totalReceivedPackets;
197
- server->host->totalReceivedPackets = 0;
198
- rb_iv_set(self, "@total_received_packets", UINT2NUM(tmp));
199
-
200
- return Qtrue;
266
+ {
267
+ VALUE total = rb_iv_get(self, "@total_sent_packets");
268
+ VALUE result = rb_funcall( total
269
+ , rb_intern("+")
270
+ , 1
271
+ , UINT2NUM(server->host->totalSentPackets));
272
+ rb_iv_set(self, "@total_sent_packets", result);
273
+ server->host->totalSentPackets = 0;
274
+ }
275
+
276
+ {
277
+ VALUE total = rb_iv_get(self, "@total_received_packets");
278
+ VALUE result = rb_funcall( total
279
+ , rb_intern("+")
280
+ , 1
281
+ , UINT2NUM(server->host->totalReceivedPackets));
282
+ rb_iv_set(self, "@total_received_packets", result);
283
+ server->host->totalReceivedPackets = 0;
284
+ }
285
+
286
+ return Qtrue;
201
287
  }
202
288
 
203
289
  VALUE renet_server_use_compression(VALUE self, VALUE flag)
204
290
  {
205
- Server* server;
206
- Data_Get_Struct(self, Server, server);
207
- if (flag == Qtrue)
208
- {
209
- enet_host_compress_with_range_coder(server->host);
210
- }
211
- else
212
- {
213
- enet_host_compress(server->host, NULL);
214
- }
215
- return Qnil;
291
+ Server* server;
292
+ Data_Get_Struct(self, Server, server);
293
+ VALUE lock = rb_iv_get(self, "@lock");
294
+ rb_mutex_lock(lock);
295
+ if (flag == Qtrue)
296
+ {
297
+ enet_host_compress_with_range_coder(server->host);
298
+ }
299
+ else
300
+ {
301
+ enet_host_compress(server->host, NULL);
302
+ }
303
+ rb_mutex_unlock(lock);
304
+ return Qnil;
216
305
  }
217
306
 
218
307
  VALUE renet_server_on_connection(VALUE self, VALUE method)
219
308
  {
220
- /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
221
- rb_iv_set(cENetServer, "@on_connection", method);
222
- return Qnil;
309
+ /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
310
+ rb_iv_set(self, "@on_connection", method);
311
+ return Qnil;
223
312
  }
224
313
 
225
- void renet_server_execute_on_connection(VALUE peer_id, VALUE ip)
314
+ void renet_server_execute_on_connection(VALUE self, VALUE peer_id, VALUE ip)
226
315
  {
227
- VALUE method = rb_iv_get(cENetServer, "@on_connection");
228
- if (method != Qnil)
229
- {
230
- rb_funcall(method, rb_intern("call"), 2, peer_id, ip);
231
- }
316
+ VALUE method = rb_iv_get(self, "@on_connection");
317
+ if (method != Qnil)
318
+ {
319
+ VALUE lock = rb_iv_get(self, "@lock");
320
+ rb_mutex_unlock(lock);
321
+ rb_funcall(method, rb_intern("call"), 2, peer_id, ip);
322
+ rb_mutex_lock(lock);
323
+ }
232
324
  }
233
325
 
234
326
  VALUE renet_server_on_packet_receive(VALUE self, VALUE method)
235
327
  {
236
-
237
- /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
238
- rb_iv_set(cENetServer, "@on_packet_receive", method);
239
- return Qnil;
328
+
329
+ /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
330
+ rb_iv_set(self, "@on_packet_receive", method);
331
+ return Qnil;
240
332
  }
241
333
 
242
- void renet_server_execute_on_packet_receive(VALUE peer_id, enet_uint8* data, enet_uint8 channelID)
334
+ void renet_server_execute_on_packet_receive(VALUE self, VALUE peer_id, ENetPacket * const packet, enet_uint8 channelID)
243
335
  {
244
- VALUE method = rb_iv_get(cENetServer, "@on_packet_receive");
245
- if (method != Qnil)
246
- {
247
- rb_funcall(method, rb_intern("call"), 3, peer_id, rb_str_new2(data), UINT2NUM(channelID));
248
- }
336
+ VALUE method = rb_iv_get(self, "@on_packet_receive");
337
+ VALUE data = rb_str_new((char const *)packet->data, packet->dataLength);
338
+ /* marshal data and then destroy packet
339
+ if we don't do this now the packet might become invalid before we get
340
+ back and we'd get a segfault when we attempt to destroy */
341
+ enet_packet_destroy(packet);
342
+
343
+ if (method != Qnil)
344
+ {
345
+ VALUE lock = rb_iv_get(self, "@lock");
346
+ rb_mutex_unlock(lock);
347
+ rb_funcall(method, rb_intern("call"), 3, peer_id, data, UINT2NUM(channelID));
348
+ rb_mutex_lock(lock);
349
+ }
249
350
  }
250
351
 
251
352
  VALUE renet_server_on_disconnection(VALUE self, VALUE method)
252
353
  {
253
- /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
254
- rb_iv_set(cENetServer, "@on_disconnection", method);
255
- return Qnil;
354
+ /*VALUE method = rb_funcall(rb_cObject, rb_intern("method"), 1, symbol);*/
355
+ rb_iv_set(self, "@on_disconnection", method);
356
+ return Qnil;
256
357
  }
257
358
 
258
- void renet_server_execute_on_disconnection(VALUE peer_id)
359
+ void renet_server_execute_on_disconnection(VALUE self, VALUE peer_id)
259
360
  {
260
- VALUE method = rb_iv_get(cENetServer, "@on_disconnection");
261
- if (method != Qnil)
262
- {
263
- rb_funcall(method, rb_intern("call"), 1, peer_id);
264
- }
361
+ VALUE method = rb_iv_get(self, "@on_disconnection");
362
+ if (method != Qnil)
363
+ {
364
+ VALUE lock = rb_iv_get(self, "@lock");
365
+ rb_mutex_unlock(lock);
366
+ rb_funcall(method, rb_intern("call"), 1, peer_id);
367
+ rb_mutex_lock(lock);
368
+ }
265
369
  }
266
370
 
267
371
  VALUE renet_server_max_clients(VALUE self)
268
372
  {
269
- Server* server;
270
- Data_Get_Struct(self, Server, server);
271
- return UINT2NUM(server->host->peerCount);
373
+ Server* server;
374
+ Data_Get_Struct(self, Server, server);
375
+ return UINT2NUM(server->host->peerCount);
272
376
  }
273
377
 
274
378
  VALUE renet_server_clients_count(VALUE self)
275
379
  {
276
- Server* server;
277
- Data_Get_Struct(self, Server, server);
278
- return UINT2NUM(server->n_clients);
380
+ Server* server;
381
+ Data_Get_Struct(self, Server, server);
382
+ return UINT2NUM(server->n_clients);
279
383
  }
280
384