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