sfml3-rb 0.2.2 → 0.3.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.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -0
  3. data/CHANGELOG.md +43 -17
  4. data/README.md +97 -29
  5. data/ext/audio/audio_enums.c +58 -20
  6. data/ext/audio/listener.c +89 -6
  7. data/ext/audio/music.c +206 -5
  8. data/ext/audio/sound.c +175 -5
  9. data/ext/audio/sound_buffer.c +189 -47
  10. data/ext/audio/sound_buffer_recorder.c +83 -16
  11. data/ext/audio/sound_recorder.c +172 -52
  12. data/ext/audio/sound_source_cone.c +108 -29
  13. data/ext/audio/sound_stream.c +178 -5
  14. data/ext/core/exceptions.c +10 -8
  15. data/ext/core/unicode.c +12 -2
  16. data/ext/ext.c +4 -0
  17. data/ext/graphics/blend_mode.c +203 -53
  18. data/ext/graphics/circle.c +271 -4
  19. data/ext/graphics/color.c +240 -90
  20. data/ext/graphics/drawable.c +15 -4
  21. data/ext/graphics/font.c +138 -25
  22. data/ext/graphics/glyph.c +31 -8
  23. data/ext/graphics/image.c +180 -37
  24. data/ext/graphics/polygon.c +293 -26
  25. data/ext/graphics/rect.c +211 -54
  26. data/ext/graphics/rectangle.c +279 -26
  27. data/ext/graphics/render_state.c +116 -2
  28. data/ext/graphics/render_texture.c +163 -2
  29. data/ext/graphics/shader.c +283 -17
  30. data/ext/graphics/shape.c +252 -26
  31. data/ext/graphics/sprite.c +216 -25
  32. data/ext/graphics/stencil_mode.c +148 -39
  33. data/ext/graphics/target.c +67 -22
  34. data/ext/graphics/target.h +15 -15
  35. data/ext/graphics/text.c +306 -6
  36. data/ext/graphics/texture.c +257 -3
  37. data/ext/graphics/transform.c +178 -5
  38. data/ext/graphics/transformable.c +126 -2
  39. data/ext/graphics/vertex.c +79 -2
  40. data/ext/graphics/vertex_array.c +128 -16
  41. data/ext/graphics/vertex_buffer.c +124 -2
  42. data/ext/graphics/view.c +130 -2
  43. data/ext/network/ftp.c +249 -10
  44. data/ext/network/http.c +156 -38
  45. data/ext/network/ip_address.c +107 -26
  46. data/ext/network/network_enums.c +248 -141
  47. data/ext/network/packet.c +273 -39
  48. data/ext/network/socket_selector.c +91 -19
  49. data/ext/network/tcp_listener.c +75 -16
  50. data/ext/network/tcp_socket.c +128 -25
  51. data/ext/network/udp_socket.c +122 -26
  52. data/ext/ports.rb +7 -0
  53. data/ext/system/buffer.c +41 -12
  54. data/ext/system/clock.c +68 -9
  55. data/ext/system/input_stream.c +94 -42
  56. data/ext/system/sleep.c +10 -2
  57. data/ext/system/time.c +172 -34
  58. data/ext/system/vec2.c +156 -35
  59. data/ext/system/vec3.c +166 -35
  60. data/ext/window/clipboard.c +47 -17
  61. data/ext/window/context.c +59 -9
  62. data/ext/window/context_settings.c +116 -38
  63. data/ext/window/cursor.c +39 -9
  64. data/ext/window/event.c +163 -42
  65. data/ext/window/joystick.c +69 -3
  66. data/ext/window/keyboard.c +168 -116
  67. data/ext/window/mouse.c +36 -2
  68. data/ext/window/sensor.c +28 -2
  69. data/ext/window/touch.c +20 -2
  70. data/ext/window/video_mode.c +90 -19
  71. data/ext/window/vulkan.c +34 -6
  72. data/ext/window/window.c +340 -16
  73. data/lib/sfml/version.rb +1 -1
  74. data/sig/audio/audio_enums.rbs +30 -0
  75. data/sig/audio/listener.rbs +16 -0
  76. data/sig/audio/music.rbs +56 -0
  77. data/sig/audio/sound.rbs +51 -0
  78. data/sig/audio/sound_buffer.rbs +17 -0
  79. data/sig/audio/sound_buffer_recorder.rbs +14 -0
  80. data/sig/audio/sound_recorder.rbs +17 -0
  81. data/sig/audio/sound_source_cone.rbs +14 -0
  82. data/sig/audio/sound_stream.rbs +51 -0
  83. data/sig/graphics/blend_mode.rbs +29 -0
  84. data/sig/graphics/circle.rbs +44 -0
  85. data/sig/graphics/color.rbs +39 -0
  86. data/sig/graphics/drawable.rbs +5 -0
  87. data/sig/graphics/font.rbs +20 -0
  88. data/sig/graphics/glyph.rbs +7 -0
  89. data/sig/graphics/image.rbs +22 -0
  90. data/sig/graphics/polygon.rbs +42 -0
  91. data/sig/graphics/rect.rbs +33 -0
  92. data/sig/graphics/rectangle.rbs +42 -0
  93. data/sig/graphics/render_state.rbs +21 -0
  94. data/sig/graphics/render_texture.rbs +37 -0
  95. data/sig/graphics/shader.rbs +39 -0
  96. data/sig/graphics/shape.rbs +38 -0
  97. data/sig/graphics/sprite.rbs +34 -0
  98. data/sig/graphics/stencil_mode.rbs +18 -0
  99. data/sig/graphics/target.rbs +10 -0
  100. data/sig/graphics/text.rbs +48 -0
  101. data/sig/graphics/texture.rbs +34 -0
  102. data/sig/graphics/transform.rbs +37 -0
  103. data/sig/graphics/transformable.rbs +25 -0
  104. data/sig/graphics/vertex.rbs +17 -0
  105. data/sig/graphics/vertex_array.rbs +17 -0
  106. data/sig/graphics/vertex_buffer.rbs +22 -0
  107. data/sig/graphics/view.rbs +24 -0
  108. data/sig/network/ftp.rbs +46 -0
  109. data/sig/network/http.rbs +27 -0
  110. data/sig/network/ip_address.rbs +22 -0
  111. data/sig/network/network_enums.rbs +95 -0
  112. data/sig/network/packet.rbs +40 -0
  113. data/sig/network/socket_selector.rbs +14 -0
  114. data/sig/network/tcp_listener.rbs +13 -0
  115. data/sig/network/tcp_socket.rbs +18 -0
  116. data/sig/network/udp_socket.rbs +17 -0
  117. data/sig/system/buffer.rbs +11 -0
  118. data/sig/system/clock.rbs +13 -0
  119. data/sig/system/input_stream.rbs +7 -0
  120. data/sig/system/sleep.rbs +3 -0
  121. data/sig/system/time.rbs +28 -0
  122. data/sig/system/vec2.rbs +26 -0
  123. data/sig/system/vec3.rbs +27 -0
  124. data/sig/window/clipboard.rbs +8 -0
  125. data/sig/window/context.rbs +11 -0
  126. data/sig/window/context_settings.rbs +20 -0
  127. data/sig/window/cursor.rbs +6 -0
  128. data/sig/window/event.rbs +20 -0
  129. data/sig/window/joystick.rbs +15 -0
  130. data/sig/window/keyboard.rbs +10 -0
  131. data/sig/window/mouse.rbs +9 -0
  132. data/sig/window/sensor.rbs +8 -0
  133. data/sig/window/touch.rbs +6 -0
  134. data/sig/window/video_mode.rbs +16 -0
  135. data/sig/window/vulkan.rbs +7 -0
  136. data/sig/window/window.rbs +57 -0
  137. metadata +66 -2
@@ -9,13 +9,13 @@
9
9
  #include "network/tcp_socket.h"
10
10
 
11
11
  typedef struct {
12
- sfTcpListener *handle;
12
+ sfTcpListener* handle;
13
13
  } TcpListener;
14
14
 
15
15
  static VALUE rb_cTcpListener;
16
16
 
17
- static void TcpListener_free(void *ptr) {
18
- TcpListener *listener = ptr;
17
+ static void TcpListener_free(void* ptr) {
18
+ TcpListener* listener = ptr;
19
19
 
20
20
  if (listener->handle != NULL) {
21
21
  sfTcpListener_destroy(listener->handle);
@@ -27,11 +27,10 @@ static void TcpListener_free(void *ptr) {
27
27
  static const rb_data_type_t TcpListener_data_type = {
28
28
  .wrap_struct_name = "SFML::TcpListener",
29
29
  .function = {.dmark = NULL, .dfree = TcpListener_free, .dsize = NULL},
30
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
31
- };
30
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
32
31
 
33
- static VALUE TcpListener_wrap(VALUE klass, sfTcpListener *handle) {
34
- TcpListener *ptr;
32
+ static VALUE TcpListener_wrap(VALUE klass, sfTcpListener* handle) {
33
+ TcpListener* ptr;
35
34
 
36
35
  if (handle == NULL) {
37
36
  rb_raise(rb_eRuntimeError, "failed to create TCP listener");
@@ -43,44 +42,100 @@ static VALUE TcpListener_wrap(VALUE klass, sfTcpListener *handle) {
43
42
  return TypedData_Wrap_Struct(klass, &TcpListener_data_type, ptr);
44
43
  }
45
44
 
45
+ /* call-seq:
46
+ * TcpListener.new -> TcpListener
47
+ *
48
+ * Creates a new TCP listener that is not yet listening.
49
+ *
50
+ * @return [TcpListener]
51
+ */
46
52
  static VALUE TcpListener_new(VALUE klass) {
47
53
  return TcpListener_wrap(klass, sfTcpListener_create());
48
54
  }
49
55
 
56
+ /* call-seq:
57
+ * TcpListener.any_port -> Integer
58
+ *
59
+ * Returns the port value that makes #listen bind to an OS-chosen port.
60
+ *
61
+ * @return [Integer] a port value that #listen interprets as "let the OS
62
+ * pick an available port"
63
+ */
50
64
  static VALUE TcpListener_any_port(VALUE klass) {
51
65
  return UINT2NUM(sfTcpListener_anyPort());
52
66
  }
53
67
 
68
+ /* call-seq: blocking? -> true or false
69
+ *
70
+ * Returns +true+ if the listener is in blocking mode.
71
+ *
72
+ * @return [Boolean]
73
+ */
54
74
  static VALUE TcpListener_blocking(VALUE self) {
55
75
  return BOOL2RB(sfTcpListener_isBlocking(Get_TcpListener_Struct(self)));
56
76
  }
57
77
 
78
+ /* call-seq:
79
+ * blocking=(value) -> value
80
+ *
81
+ * Enables or disables blocking mode according to +value+.
82
+ *
83
+ * @return [Boolean] +value+
84
+ */
58
85
  static VALUE TcpListener_set_blocking(VALUE self, VALUE rb_value) {
59
86
  sfTcpListener_setBlocking(Get_TcpListener_Struct(self), RTEST(rb_value));
60
87
  return rb_value;
61
88
  }
62
89
 
90
+ /* call-seq: local_port -> Integer
91
+ *
92
+ * Returns the port the listener is bound to, or 0 if it isn't listening.
93
+ *
94
+ * @return [Integer] the port the listener is bound to, or 0 if it isn't
95
+ * listening
96
+ */
63
97
  static VALUE TcpListener_local_port(VALUE self) {
64
98
  return UINT2NUM(sfTcpListener_getLocalPort(Get_TcpListener_Struct(self)));
65
99
  }
66
100
 
67
- static VALUE TcpListener_listen(int argc, VALUE *argv, VALUE self) {
101
+ /* call-seq:
102
+ * listen(port, address = IpAddress::ANY) -> Symbol
103
+ *
104
+ * Starts listening for incoming connections on +port+, optionally
105
+ * restricted to a specific local network interface via +address+.
106
+ *
107
+ * @return [Symbol] a SocketStatus name, +:done+ on success
108
+ */
109
+ static VALUE TcpListener_listen(int argc, VALUE* argv, VALUE self) {
68
110
  VALUE rb_port, rb_address;
69
111
 
70
112
  rb_scan_args(argc, argv, "11", &rb_port, &rb_address);
71
113
 
72
- return ID2SYM(rb_intern(socket_status_name(sfTcpListener_listen(
73
- Get_TcpListener_Struct(self), (unsigned short) NUM2INT(rb_port),
74
- ip_address_from_rb(rb_address, sfIpAddress_Any)))));
114
+ return ID2SYM(rb_intern(socket_status_name(
115
+ sfTcpListener_listen(Get_TcpListener_Struct(self), (unsigned short)NUM2INT(rb_port),
116
+ ip_address_from_rb(rb_address, sfIpAddress_Any)))));
75
117
  }
76
118
 
119
+ /* call-seq: close -> self
120
+ *
121
+ * Stops listening and closes the underlying socket.
122
+ *
123
+ * @return [self]
124
+ */
77
125
  static VALUE TcpListener_close(VALUE self) {
78
126
  sfTcpListener_close(Get_TcpListener_Struct(self));
79
127
  return self;
80
128
  }
81
129
 
130
+ /* call-seq: accept -> [TcpSocket, Symbol]
131
+ *
132
+ * Blocks (unless #blocking? is +false+) waiting for a client to connect.
133
+ *
134
+ * @return [Array(TcpSocket, Symbol)] the connected socket (or +nil+ if the
135
+ * status isn't +:done+), and a SocketStatus name
136
+ */
82
137
  static VALUE TcpListener_accept(VALUE self) {
83
- sfTcpSocket *socket = NULL;
138
+ sfTcpSocket* socket = NULL;
84
139
  sfSocketStatus status = sfTcpListener_accept(Get_TcpListener_Struct(self), &socket);
85
140
  VALUE rb_result = rb_ary_new_capa(2);
86
141
 
@@ -90,8 +145,12 @@ static VALUE TcpListener_accept(VALUE self) {
90
145
  return rb_result;
91
146
  }
92
147
 
93
- void Init_TcpListener(VALUE rb_module) {
94
- rb_cTcpListener = rb_define_class_under(rb_module, "TcpListener", rb_cObject);
148
+ /* Document-class: SFML::TcpListener
149
+ * Listens for and accepts incoming TCP connections, producing connected
150
+ * TcpSocket instances.
151
+ */
152
+ void Init_TcpListener(VALUE rb_mSFML) {
153
+ rb_cTcpListener = rb_define_class_under(rb_mSFML, "TcpListener", rb_cObject);
95
154
 
96
155
  rb_define_singleton_method(rb_cTcpListener, "new", TcpListener_new, 0);
97
156
  rb_define_singleton_method(rb_cTcpListener, "any_port", TcpListener_any_port, 0);
@@ -108,8 +167,8 @@ VALUE Get_Klass_TcpListener(void) {
108
167
  return rb_cTcpListener;
109
168
  }
110
169
 
111
- void *Get_TcpListener_Struct(VALUE self) {
112
- TcpListener *ptr;
170
+ void* Get_TcpListener_Struct(VALUE self) {
171
+ TcpListener* ptr;
113
172
  TypedData_Get_Struct(self, TcpListener, &TcpListener_data_type, ptr);
114
173
  return ptr->handle;
115
174
  }
@@ -10,13 +10,13 @@
10
10
  #include "system/time.h"
11
11
 
12
12
  typedef struct {
13
- sfTcpSocket *handle;
13
+ sfTcpSocket* handle;
14
14
  } TcpSocket;
15
15
 
16
16
  static VALUE rb_cTcpSocket;
17
17
 
18
- static void TcpSocket_free(void *ptr) {
19
- TcpSocket *socket = ptr;
18
+ static void TcpSocket_free(void* ptr) {
19
+ TcpSocket* socket = ptr;
20
20
 
21
21
  if (socket->handle != NULL) {
22
22
  sfTcpSocket_destroy(socket->handle);
@@ -28,11 +28,10 @@ static void TcpSocket_free(void *ptr) {
28
28
  static const rb_data_type_t TcpSocket_data_type = {
29
29
  .wrap_struct_name = "SFML::TcpSocket",
30
30
  .function = {.dmark = NULL, .dfree = TcpSocket_free, .dsize = NULL},
31
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
32
- };
31
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
33
32
 
34
- static VALUE TcpSocket_wrap(VALUE klass, sfTcpSocket *handle) {
35
- TcpSocket *ptr;
33
+ static VALUE TcpSocket_wrap(VALUE klass, sfTcpSocket* handle) {
34
+ TcpSocket* ptr;
36
35
 
37
36
  if (handle == NULL) {
38
37
  rb_raise(rb_eRuntimeError, "failed to create TCP socket");
@@ -44,36 +43,84 @@ static VALUE TcpSocket_wrap(VALUE klass, sfTcpSocket *handle) {
44
43
  return TypedData_Wrap_Struct(klass, &TcpSocket_data_type, ptr);
45
44
  }
46
45
 
47
- VALUE tcp_socket_from_handle(sfTcpSocket *socket) {
46
+ VALUE tcp_socket_from_handle(sfTcpSocket* socket) {
48
47
  return TcpSocket_wrap(rb_cTcpSocket, socket);
49
48
  }
50
49
 
50
+ /* call-seq:
51
+ * TcpSocket.new -> TcpSocket
52
+ *
53
+ * Creates a new, unconnected TCP socket.
54
+ *
55
+ * @return [TcpSocket] a new, unconnected socket
56
+ */
51
57
  static VALUE TcpSocket_new(VALUE klass) {
52
58
  return TcpSocket_wrap(klass, sfTcpSocket_create());
53
59
  }
54
60
 
61
+ /* call-seq: blocking? -> true or false
62
+ *
63
+ * Returns +true+ if the socket is in blocking mode.
64
+ *
65
+ * @return [Boolean]
66
+ */
55
67
  static VALUE TcpSocket_blocking(VALUE self) {
56
68
  return BOOL2RB(sfTcpSocket_isBlocking(Get_TcpSocket_Struct(self)));
57
69
  }
58
70
 
71
+ /* call-seq:
72
+ * blocking=(value) -> value
73
+ *
74
+ * Enables or disables blocking mode according to +value+.
75
+ *
76
+ * @return [Boolean] +value+
77
+ */
59
78
  static VALUE TcpSocket_set_blocking(VALUE self, VALUE rb_value) {
60
79
  sfTcpSocket_setBlocking(Get_TcpSocket_Struct(self), RTEST(rb_value));
61
80
  return rb_value;
62
81
  }
63
82
 
83
+ /* call-seq: local_port -> Integer
84
+ *
85
+ * Returns the local port the socket is bound to.
86
+ *
87
+ * @return [Integer] the local port the socket is bound to, or 0 if it
88
+ * isn't connected
89
+ */
64
90
  static VALUE TcpSocket_local_port(VALUE self) {
65
91
  return UINT2NUM(sfTcpSocket_getLocalPort(Get_TcpSocket_Struct(self)));
66
92
  }
67
93
 
94
+ /* call-seq: remote_address -> IpAddress
95
+ *
96
+ * Returns the address of the remote peer.
97
+ *
98
+ * @return [IpAddress] the address of the remote peer, or +IpAddress::NONE+
99
+ * if not connected
100
+ */
68
101
  static VALUE TcpSocket_remote_address(VALUE self) {
69
102
  return ip_address_to_rb(sfTcpSocket_getRemoteAddress(Get_TcpSocket_Struct(self)));
70
103
  }
71
104
 
105
+ /* call-seq: remote_port -> Integer
106
+ *
107
+ * Returns the port of the remote peer.
108
+ *
109
+ * @return [Integer] the port of the remote peer, or 0 if not connected
110
+ */
72
111
  static VALUE TcpSocket_remote_port(VALUE self) {
73
112
  return UINT2NUM(sfTcpSocket_getRemotePort(Get_TcpSocket_Struct(self)));
74
113
  }
75
114
 
76
- static VALUE TcpSocket_connect(int argc, VALUE *argv, VALUE self) {
115
+ /* call-seq:
116
+ * connect(address, port, timeout = Time.zero) -> Symbol
117
+ *
118
+ * Connects to a remote peer, blocking (unless #blocking? is +false+) until
119
+ * connected or +timeout+ elapses.
120
+ *
121
+ * @return [Symbol] a SocketStatus name, +:done+ on success
122
+ */
123
+ static VALUE TcpSocket_connect(int argc, VALUE* argv, VALUE self) {
77
124
  VALUE rb_address, rb_port, rb_timeout;
78
125
  sfTime timeout = sfTime_Zero;
79
126
 
@@ -85,22 +132,45 @@ static VALUE TcpSocket_connect(int argc, VALUE *argv, VALUE self) {
85
132
 
86
133
  return ID2SYM(rb_intern(socket_status_name(sfTcpSocket_connect(
87
134
  Get_TcpSocket_Struct(self), ip_address_from_rb(rb_address, sfIpAddress_None),
88
- (unsigned short) NUM2INT(rb_port), timeout))));
135
+ (unsigned short)NUM2INT(rb_port), timeout))));
89
136
  }
90
137
 
138
+ /* call-seq: disconnect -> self
139
+ *
140
+ * Closes the connection.
141
+ *
142
+ * @return [self]
143
+ */
91
144
  static VALUE TcpSocket_disconnect(VALUE self) {
92
145
  sfTcpSocket_disconnect(Get_TcpSocket_Struct(self));
93
146
  return self;
94
147
  }
95
148
 
149
+ /* call-seq:
150
+ * send(data) -> Symbol
151
+ *
152
+ * Sends the full contents of +data+, blocking (unless #blocking? is
153
+ * +false+) until it is all sent. Prefer #send_partial for non-blocking
154
+ * sockets, since this can return +:not_ready+ having sent only part of
155
+ * the data with no way to know how much.
156
+ *
157
+ * @return [Symbol] a SocketStatus name, +:done+ on success
158
+ */
96
159
  static VALUE TcpSocket_send(VALUE self, VALUE rb_data) {
97
160
  StringValue(rb_data);
98
161
 
99
- return ID2SYM(rb_intern(socket_status_name(
100
- sfTcpSocket_send(Get_TcpSocket_Struct(self), RSTRING_PTR(rb_data),
101
- (size_t) RSTRING_LEN(rb_data)))));
162
+ return ID2SYM(rb_intern(socket_status_name(sfTcpSocket_send(
163
+ Get_TcpSocket_Struct(self), RSTRING_PTR(rb_data), (size_t)RSTRING_LEN(rb_data)))));
102
164
  }
103
165
 
166
+ /* call-seq:
167
+ * send_partial(data) -> [Integer, Symbol]
168
+ *
169
+ * Like #send, but may send only part of +data+ and reports how much.
170
+ *
171
+ * @return [Array(Integer, Symbol)] the number of bytes actually sent, and
172
+ * a SocketStatus name
173
+ */
104
174
  static VALUE TcpSocket_send_partial(VALUE self, VALUE rb_data) {
105
175
  size_t sent = 0;
106
176
  sfSocketStatus status;
@@ -109,7 +179,7 @@ static VALUE TcpSocket_send_partial(VALUE self, VALUE rb_data) {
109
179
  StringValue(rb_data);
110
180
 
111
181
  status = sfTcpSocket_sendPartial(Get_TcpSocket_Struct(self), RSTRING_PTR(rb_data),
112
- (size_t) RSTRING_LEN(rb_data), &sent);
182
+ (size_t)RSTRING_LEN(rb_data), &sent);
113
183
 
114
184
  rb_result = rb_ary_new_capa(2);
115
185
  rb_ary_push(rb_result, SIZET2NUM(sent));
@@ -118,12 +188,19 @@ static VALUE TcpSocket_send_partial(VALUE self, VALUE rb_data) {
118
188
  return rb_result;
119
189
  }
120
190
 
121
- /* Receive needs a maximum size up front because CSFML fills a caller buffer.
122
- Returns [data, status], where data is empty unless the status is :done. */
123
- static VALUE TcpSocket_receive(int argc, VALUE *argv, VALUE self) {
191
+ /* call-seq:
192
+ * receive(max_length = 1024) -> [String, Symbol]
193
+ *
194
+ * Receive needs a maximum size up front because CSFML fills a caller buffer.
195
+ * Returns [data, status], where data is empty unless the status is :done.
196
+ *
197
+ * @return [Array(String, Symbol)] the bytes received, and a SocketStatus name
198
+ * @raise [ArgumentError] if +max_length+ isn't positive
199
+ */
200
+ static VALUE TcpSocket_receive(int argc, VALUE* argv, VALUE self) {
124
201
  VALUE rb_max_length;
125
202
  long max_length = 1024;
126
- char *buffer;
203
+ char* buffer;
127
204
  size_t received = 0;
128
205
  sfSocketStatus status;
129
206
  VALUE rb_result;
@@ -138,12 +215,16 @@ static VALUE TcpSocket_receive(int argc, VALUE *argv, VALUE self) {
138
215
  rb_raise(rb_eArgError, "maximum length must be positive");
139
216
  }
140
217
 
141
- buffer = malloc((size_t) max_length);
218
+ buffer = malloc((size_t)max_length);
219
+
220
+ if (buffer == NULL) {
221
+ rb_raise(rb_eNoMemError, "failed to allocate receive buffer");
222
+ }
142
223
 
143
- status = sfTcpSocket_receive(Get_TcpSocket_Struct(self), buffer, (size_t) max_length, &received);
224
+ status = sfTcpSocket_receive(Get_TcpSocket_Struct(self), buffer, (size_t)max_length, &received);
144
225
 
145
226
  rb_result = rb_ary_new_capa(2);
146
- rb_ary_push(rb_result, rb_str_new(buffer, (long) received));
227
+ rb_ary_push(rb_result, rb_str_new(buffer, (long)received));
147
228
  rb_ary_push(rb_result, ID2SYM(rb_intern(socket_status_name(status))));
148
229
 
149
230
  free(buffer);
@@ -151,6 +232,14 @@ static VALUE TcpSocket_receive(int argc, VALUE *argv, VALUE self) {
151
232
  return rb_result;
152
233
  }
153
234
 
235
+ /* call-seq:
236
+ * send_packet(packet) -> Symbol
237
+ *
238
+ * Sends +packet+ over the connection.
239
+ *
240
+ * @return [Symbol] a SocketStatus name, +:done+ on success
241
+ * @raise [TypeError] if +packet+ is not an SFML::Packet
242
+ */
154
243
  static VALUE TcpSocket_send_packet(VALUE self, VALUE rb_packet) {
155
244
  if (!rb_obj_is_kind_of(rb_packet, Get_Klass_Packet())) {
156
245
  rb_raise(rb_eTypeError, "expected an SFML::Packet");
@@ -160,6 +249,15 @@ static VALUE TcpSocket_send_packet(VALUE self, VALUE rb_packet) {
160
249
  sfTcpSocket_sendPacket(Get_TcpSocket_Struct(self), Get_Packet_Struct(rb_packet)))));
161
250
  }
162
251
 
252
+ /* call-seq:
253
+ * receive_packet(packet) -> Symbol
254
+ *
255
+ * Fills +packet+ (replacing its previous contents) with the next packet
256
+ * received.
257
+ *
258
+ * @return [Symbol] a SocketStatus name, +:done+ on success
259
+ * @raise [TypeError] if +packet+ is not an SFML::Packet
260
+ */
163
261
  static VALUE TcpSocket_receive_packet(VALUE self, VALUE rb_packet) {
164
262
  if (!rb_obj_is_kind_of(rb_packet, Get_Klass_Packet())) {
165
263
  rb_raise(rb_eTypeError, "expected an SFML::Packet");
@@ -169,8 +267,13 @@ static VALUE TcpSocket_receive_packet(VALUE self, VALUE rb_packet) {
169
267
  sfTcpSocket_receivePacket(Get_TcpSocket_Struct(self), Get_Packet_Struct(rb_packet)))));
170
268
  }
171
269
 
172
- void Init_TcpSocket(VALUE rb_module) {
173
- rb_cTcpSocket = rb_define_class_under(rb_module, "TcpSocket", rb_cObject);
270
+ /* Document-class: SFML::TcpSocket
271
+ * A connection-oriented, reliable, byte-stream socket for TCP communication.
272
+ * Connect with #connect (or receive one already connected from
273
+ * TcpListener#accept), then send/receive raw bytes or Packet instances.
274
+ */
275
+ void Init_TcpSocket(VALUE rb_mSFML) {
276
+ rb_cTcpSocket = rb_define_class_under(rb_mSFML, "TcpSocket", rb_cObject);
174
277
 
175
278
  rb_define_singleton_method(rb_cTcpSocket, "new", TcpSocket_new, 0);
176
279
 
@@ -192,8 +295,8 @@ VALUE Get_Klass_TcpSocket(void) {
192
295
  return rb_cTcpSocket;
193
296
  }
194
297
 
195
- void *Get_TcpSocket_Struct(VALUE self) {
196
- TcpSocket *ptr;
298
+ void* Get_TcpSocket_Struct(VALUE self) {
299
+ TcpSocket* ptr;
197
300
  TypedData_Get_Struct(self, TcpSocket, &TcpSocket_data_type, ptr);
198
301
  return ptr->handle;
199
302
  }
@@ -9,13 +9,13 @@
9
9
  #include "network/packet.h"
10
10
 
11
11
  typedef struct {
12
- sfUdpSocket *handle;
12
+ sfUdpSocket* handle;
13
13
  } UdpSocket;
14
14
 
15
15
  static VALUE rb_cUdpSocket;
16
16
 
17
- static void UdpSocket_free(void *ptr) {
18
- UdpSocket *socket = ptr;
17
+ static void UdpSocket_free(void* ptr) {
18
+ UdpSocket* socket = ptr;
19
19
 
20
20
  if (socket->handle != NULL) {
21
21
  sfUdpSocket_destroy(socket->handle);
@@ -27,11 +27,10 @@ static void UdpSocket_free(void *ptr) {
27
27
  static const rb_data_type_t UdpSocket_data_type = {
28
28
  .wrap_struct_name = "SFML::UdpSocket",
29
29
  .function = {.dmark = NULL, .dfree = UdpSocket_free, .dsize = NULL},
30
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
31
- };
30
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
32
31
 
33
- static VALUE UdpSocket_wrap(VALUE klass, sfUdpSocket *handle) {
34
- UdpSocket *ptr;
32
+ static VALUE UdpSocket_wrap(VALUE klass, sfUdpSocket* handle) {
33
+ UdpSocket* ptr;
35
34
 
36
35
  if (handle == NULL) {
37
36
  rb_raise(rb_eRuntimeError, "failed to create UDP socket");
@@ -43,60 +42,131 @@ static VALUE UdpSocket_wrap(VALUE klass, sfUdpSocket *handle) {
43
42
  return TypedData_Wrap_Struct(klass, &UdpSocket_data_type, ptr);
44
43
  }
45
44
 
45
+ /* call-seq:
46
+ * UdpSocket.new -> UdpSocket
47
+ *
48
+ * Creates a new, unbound UDP socket.
49
+ *
50
+ * @return [UdpSocket] a new, unbound socket
51
+ */
46
52
  static VALUE UdpSocket_new(VALUE klass) {
47
53
  return UdpSocket_wrap(klass, sfUdpSocket_create());
48
54
  }
49
55
 
56
+ /* call-seq:
57
+ * UdpSocket.any_port -> Integer
58
+ *
59
+ * Returns the port value that makes #bind bind to an OS-chosen port.
60
+ *
61
+ * @return [Integer] a port value that #bind interprets as "let the OS pick
62
+ * an available port"
63
+ */
50
64
  static VALUE UdpSocket_any_port(VALUE klass) {
51
65
  return UINT2NUM(sfUdpSocket_anyPort());
52
66
  }
53
67
 
68
+ /* call-seq:
69
+ * UdpSocket.max_datagram_size -> Integer
70
+ *
71
+ * Returns the maximum size, in bytes, of a single UDP datagram.
72
+ *
73
+ * @return [Integer] the maximum number of bytes that can be sent in a
74
+ * single UDP datagram (65507)
75
+ */
54
76
  static VALUE UdpSocket_max_datagram_size(VALUE klass) {
55
77
  return UINT2NUM(sfUdpSocket_maxDatagramSize());
56
78
  }
57
79
 
80
+ /* call-seq: blocking? -> true or false
81
+ *
82
+ * Returns +true+ if the socket is in blocking mode.
83
+ *
84
+ * @return [Boolean]
85
+ */
58
86
  static VALUE UdpSocket_blocking(VALUE self) {
59
87
  return BOOL2RB(sfUdpSocket_isBlocking(Get_UdpSocket_Struct(self)));
60
88
  }
61
89
 
90
+ /* call-seq:
91
+ * blocking=(value) -> value
92
+ *
93
+ * Enables or disables blocking mode according to +value+.
94
+ *
95
+ * @return [Boolean] +value+
96
+ */
62
97
  static VALUE UdpSocket_set_blocking(VALUE self, VALUE rb_value) {
63
98
  sfUdpSocket_setBlocking(Get_UdpSocket_Struct(self), RTEST(rb_value));
64
99
  return rb_value;
65
100
  }
66
101
 
102
+ /* call-seq: local_port -> Integer
103
+ *
104
+ * Returns the local port the socket is bound to.
105
+ *
106
+ * @return [Integer] the port the socket is bound to, or 0 if not bound
107
+ */
67
108
  static VALUE UdpSocket_local_port(VALUE self) {
68
109
  return UINT2NUM(sfUdpSocket_getLocalPort(Get_UdpSocket_Struct(self)));
69
110
  }
70
111
 
71
- static VALUE UdpSocket_bind(int argc, VALUE *argv, VALUE self) {
112
+ /* call-seq:
113
+ * bind(port, address = IpAddress::ANY) -> Symbol
114
+ *
115
+ * Binds the socket to a local port, optionally restricted to a specific
116
+ * local network interface via +address+, so it can receive datagrams.
117
+ *
118
+ * @return [Symbol] a SocketStatus name, +:done+ on success
119
+ */
120
+ static VALUE UdpSocket_bind(int argc, VALUE* argv, VALUE self) {
72
121
  VALUE rb_port, rb_address;
73
122
 
74
123
  rb_scan_args(argc, argv, "11", &rb_port, &rb_address);
75
124
 
76
- return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_bind(
77
- Get_UdpSocket_Struct(self), (unsigned short) NUM2INT(rb_port),
78
- ip_address_from_rb(rb_address, sfIpAddress_Any)))));
125
+ return ID2SYM(rb_intern(socket_status_name(
126
+ sfUdpSocket_bind(Get_UdpSocket_Struct(self), (unsigned short)NUM2INT(rb_port),
127
+ ip_address_from_rb(rb_address, sfIpAddress_Any)))));
79
128
  }
80
129
 
130
+ /* call-seq: unbind -> self
131
+ *
132
+ * Unbinds the socket from its local port.
133
+ *
134
+ * @return [self]
135
+ */
81
136
  static VALUE UdpSocket_unbind(VALUE self) {
82
137
  sfUdpSocket_unbind(Get_UdpSocket_Struct(self));
83
138
  return self;
84
139
  }
85
140
 
141
+ /* call-seq:
142
+ * send(data, address, port) -> Symbol
143
+ *
144
+ * Sends a single datagram to a remote peer. +data+ must be no larger than
145
+ * .max_datagram_size bytes.
146
+ *
147
+ * @return [Symbol] a SocketStatus name, +:done+ on success
148
+ */
86
149
  static VALUE UdpSocket_send(VALUE self, VALUE rb_data, VALUE rb_address, VALUE rb_port) {
87
150
  StringValue(rb_data);
88
151
 
89
152
  return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_send(
90
- Get_UdpSocket_Struct(self), RSTRING_PTR(rb_data), (size_t) RSTRING_LEN(rb_data),
91
- ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short) NUM2INT(rb_port)))));
153
+ Get_UdpSocket_Struct(self), RSTRING_PTR(rb_data), (size_t)RSTRING_LEN(rb_data),
154
+ ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short)NUM2INT(rb_port)))));
92
155
  }
93
156
 
94
- /* Returns [data, IpAddress, port, status]; the address and port are those of
95
- the sender. */
96
- static VALUE UdpSocket_receive(int argc, VALUE *argv, VALUE self) {
157
+ /* call-seq:
158
+ * receive(max_length = 1024) -> [String, IpAddress, Integer, Symbol]
159
+ *
160
+ * Returns [data, IpAddress, port, status]; the address and port are those of
161
+ * the sender.
162
+ *
163
+ * @return [Array(String, IpAddress, Integer, Symbol)]
164
+ * @raise [ArgumentError] if +max_length+ isn't positive
165
+ */
166
+ static VALUE UdpSocket_receive(int argc, VALUE* argv, VALUE self) {
97
167
  VALUE rb_max_length;
98
168
  long max_length = 1024;
99
- char *buffer;
169
+ char* buffer;
100
170
  size_t received = 0;
101
171
  sfIpAddress remote_address = sfIpAddress_None;
102
172
  unsigned short remote_port = 0;
@@ -113,13 +183,17 @@ static VALUE UdpSocket_receive(int argc, VALUE *argv, VALUE self) {
113
183
  rb_raise(rb_eArgError, "maximum length must be positive");
114
184
  }
115
185
 
116
- buffer = malloc((size_t) max_length);
186
+ buffer = malloc((size_t)max_length);
117
187
 
118
- status = sfUdpSocket_receive(Get_UdpSocket_Struct(self), buffer, (size_t) max_length, &received,
188
+ if (buffer == NULL) {
189
+ rb_raise(rb_eNoMemError, "failed to allocate receive buffer");
190
+ }
191
+
192
+ status = sfUdpSocket_receive(Get_UdpSocket_Struct(self), buffer, (size_t)max_length, &received,
119
193
  &remote_address, &remote_port);
120
194
 
121
195
  rb_result = rb_ary_new_capa(4);
122
- rb_ary_push(rb_result, rb_str_new(buffer, (long) received));
196
+ rb_ary_push(rb_result, rb_str_new(buffer, (long)received));
123
197
  rb_ary_push(rb_result, ip_address_to_rb(remote_address));
124
198
  rb_ary_push(rb_result, UINT2NUM(remote_port));
125
199
  rb_ary_push(rb_result, ID2SYM(rb_intern(socket_status_name(status))));
@@ -129,6 +203,14 @@ static VALUE UdpSocket_receive(int argc, VALUE *argv, VALUE self) {
129
203
  return rb_result;
130
204
  }
131
205
 
206
+ /* call-seq:
207
+ * send_packet(packet, address, port) -> Symbol
208
+ *
209
+ * Sends +packet+ as a datagram to the given +address+ and +port+.
210
+ *
211
+ * @return [Symbol] a SocketStatus name, +:done+ on success
212
+ * @raise [TypeError] if +packet+ is not an SFML::Packet
213
+ */
132
214
  static VALUE UdpSocket_send_packet(VALUE self, VALUE rb_packet, VALUE rb_address, VALUE rb_port) {
133
215
  if (!rb_obj_is_kind_of(rb_packet, Get_Klass_Packet())) {
134
216
  rb_raise(rb_eTypeError, "expected an SFML::Packet");
@@ -136,10 +218,19 @@ static VALUE UdpSocket_send_packet(VALUE self, VALUE rb_packet, VALUE rb_address
136
218
 
137
219
  return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_sendPacket(
138
220
  Get_UdpSocket_Struct(self), Get_Packet_Struct(rb_packet),
139
- ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short) NUM2INT(rb_port)))));
221
+ ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short)NUM2INT(rb_port)))));
140
222
  }
141
223
 
142
- /* Returns [IpAddress, port, status]. */
224
+ /* call-seq:
225
+ * receive_packet(packet) -> [IpAddress, Integer, Symbol]
226
+ *
227
+ * Fills +packet+ (replacing its previous contents) with the next datagram
228
+ * received. Returns [IpAddress, port, status], the address and port of the
229
+ * sender.
230
+ *
231
+ * @return [Array(IpAddress, Integer, Symbol)]
232
+ * @raise [TypeError] if +packet+ is not an SFML::Packet
233
+ */
143
234
  static VALUE UdpSocket_receive_packet(VALUE self, VALUE rb_packet) {
144
235
  sfIpAddress remote_address = sfIpAddress_None;
145
236
  unsigned short remote_port = 0;
@@ -161,8 +252,13 @@ static VALUE UdpSocket_receive_packet(VALUE self, VALUE rb_packet) {
161
252
  return rb_result;
162
253
  }
163
254
 
164
- void Init_UdpSocket(VALUE rb_module) {
165
- rb_cUdpSocket = rb_define_class_under(rb_module, "UdpSocket", rb_cObject);
255
+ /* Document-class: SFML::UdpSocket
256
+ * A connectionless, unreliable, datagram-oriented socket for UDP
257
+ * communication. Datagrams may be lost, duplicated or arrive out of order,
258
+ * and are capped at .max_datagram_size bytes.
259
+ */
260
+ void Init_UdpSocket(VALUE rb_mSFML) {
261
+ rb_cUdpSocket = rb_define_class_under(rb_mSFML, "UdpSocket", rb_cObject);
166
262
 
167
263
  rb_define_singleton_method(rb_cUdpSocket, "new", UdpSocket_new, 0);
168
264
  rb_define_singleton_method(rb_cUdpSocket, "any_port", UdpSocket_any_port, 0);
@@ -183,8 +279,8 @@ VALUE Get_Klass_UdpSocket(void) {
183
279
  return rb_cUdpSocket;
184
280
  }
185
281
 
186
- void *Get_UdpSocket_Struct(VALUE self) {
187
- UdpSocket *ptr;
282
+ void* Get_UdpSocket_Struct(VALUE self) {
283
+ UdpSocket* ptr;
188
284
  TypedData_Get_Struct(self, UdpSocket, &UdpSocket_data_type, ptr);
189
285
  return ptr->handle;
190
286
  }