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.
- checksums.yaml +4 -4
- data/.yardopts +9 -0
- data/CHANGELOG.md +43 -17
- data/README.md +97 -29
- data/ext/audio/audio_enums.c +58 -20
- data/ext/audio/listener.c +89 -6
- data/ext/audio/music.c +206 -5
- data/ext/audio/sound.c +175 -5
- data/ext/audio/sound_buffer.c +189 -47
- data/ext/audio/sound_buffer_recorder.c +83 -16
- data/ext/audio/sound_recorder.c +172 -52
- data/ext/audio/sound_source_cone.c +108 -29
- data/ext/audio/sound_stream.c +178 -5
- data/ext/core/exceptions.c +10 -8
- data/ext/core/unicode.c +12 -2
- data/ext/ext.c +4 -0
- data/ext/graphics/blend_mode.c +203 -53
- data/ext/graphics/circle.c +271 -4
- data/ext/graphics/color.c +240 -90
- data/ext/graphics/drawable.c +15 -4
- data/ext/graphics/font.c +138 -25
- data/ext/graphics/glyph.c +31 -8
- data/ext/graphics/image.c +180 -37
- data/ext/graphics/polygon.c +293 -26
- data/ext/graphics/rect.c +211 -54
- data/ext/graphics/rectangle.c +279 -26
- data/ext/graphics/render_state.c +116 -2
- data/ext/graphics/render_texture.c +163 -2
- data/ext/graphics/shader.c +283 -17
- data/ext/graphics/shape.c +252 -26
- data/ext/graphics/sprite.c +216 -25
- data/ext/graphics/stencil_mode.c +148 -39
- data/ext/graphics/target.c +67 -22
- data/ext/graphics/target.h +15 -15
- data/ext/graphics/text.c +306 -6
- data/ext/graphics/texture.c +257 -3
- data/ext/graphics/transform.c +178 -5
- data/ext/graphics/transformable.c +126 -2
- data/ext/graphics/vertex.c +79 -2
- data/ext/graphics/vertex_array.c +128 -16
- data/ext/graphics/vertex_buffer.c +124 -2
- data/ext/graphics/view.c +130 -2
- data/ext/network/ftp.c +249 -10
- data/ext/network/http.c +156 -38
- data/ext/network/ip_address.c +107 -26
- data/ext/network/network_enums.c +248 -141
- data/ext/network/packet.c +273 -39
- data/ext/network/socket_selector.c +91 -19
- data/ext/network/tcp_listener.c +75 -16
- data/ext/network/tcp_socket.c +128 -25
- data/ext/network/udp_socket.c +122 -26
- data/ext/ports.rb +7 -0
- data/ext/system/buffer.c +41 -12
- data/ext/system/clock.c +68 -9
- data/ext/system/input_stream.c +94 -42
- data/ext/system/sleep.c +10 -2
- data/ext/system/time.c +172 -34
- data/ext/system/vec2.c +156 -35
- data/ext/system/vec3.c +166 -35
- data/ext/window/clipboard.c +47 -17
- data/ext/window/context.c +59 -9
- data/ext/window/context_settings.c +116 -38
- data/ext/window/cursor.c +39 -9
- data/ext/window/event.c +163 -42
- data/ext/window/joystick.c +69 -3
- data/ext/window/keyboard.c +168 -116
- data/ext/window/mouse.c +36 -2
- data/ext/window/sensor.c +28 -2
- data/ext/window/touch.c +20 -2
- data/ext/window/video_mode.c +90 -19
- data/ext/window/vulkan.c +34 -6
- data/ext/window/window.c +340 -16
- 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_texture.rbs +37 -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 +10 -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 +24 -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/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 +57 -0
- metadata +66 -2
data/ext/ports.rb
CHANGED
|
@@ -34,10 +34,17 @@ module Ports
|
|
|
34
34
|
'x86-linux-gnu' => { triple: 'i686-linux-gnu', multiarch: 'i386-linux-gnu',
|
|
35
35
|
os: :linux, cpu: 'i686' },
|
|
36
36
|
'aarch64-linux-gnu' => { triple: 'aarch64-linux-gnu', os: :linux, cpu: 'aarch64' },
|
|
37
|
+
'arm-linux-gnu' => { triple: 'arm-linux-gnueabihf', os: :linux, cpu: 'arm' },
|
|
37
38
|
'x86_64-linux-musl' => { triple: 'x86_64-unknown-linux-musl', os: :linux, cpu: 'x86_64' },
|
|
38
39
|
'x86-linux-musl' => { triple: 'i686-unknown-linux-musl', os: :linux, cpu: 'i686' },
|
|
40
|
+
# These two deliberately omit the -unknown- Debian-musl entries above use:
|
|
41
|
+
# the triple must match musl-cross-make's TARGET exactly, since that string
|
|
42
|
+
# is both the compiler prefix and the sysroot path (see musl_sysroot).
|
|
43
|
+
'aarch64-linux-musl' => { triple: 'aarch64-linux-musl', os: :linux, cpu: 'aarch64' },
|
|
44
|
+
'arm-linux-musl' => { triple: 'arm-linux-musleabihf', os: :linux, cpu: 'arm' },
|
|
39
45
|
'x64-mingw-ucrt' => { triple: 'x86_64-w64-mingw32', os: :windows, cpu: 'x86_64' },
|
|
40
46
|
'x86-mingw32' => { triple: 'i686-w64-mingw32', os: :windows, cpu: 'i686' },
|
|
47
|
+
'aarch64-mingw-ucrt' => { triple: 'aarch64-w64-mingw32', os: :windows, cpu: 'arm64' },
|
|
41
48
|
'x86_64-darwin' => { triple: 'x86_64-apple-darwin', os: :darwin, cpu: 'x86_64' },
|
|
42
49
|
'arm64-darwin' => { triple: 'aarch64-apple-darwin', os: :darwin, cpu: 'arm64' }
|
|
43
50
|
}.freeze
|
data/ext/system/buffer.c
CHANGED
|
@@ -7,23 +7,30 @@
|
|
|
7
7
|
|
|
8
8
|
static VALUE rb_cBuffer;
|
|
9
9
|
|
|
10
|
-
static void Buffer_free(void
|
|
10
|
+
static void Buffer_free(void* ptr) {
|
|
11
11
|
sfBuffer_destroy(ptr);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
static const rb_data_type_t Buffer_data_type = {
|
|
15
15
|
.wrap_struct_name = "SFML::Buffer",
|
|
16
16
|
.function = {.dmark = NULL, .dfree = Buffer_free, .dsize = NULL},
|
|
17
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
18
|
-
};
|
|
17
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
19
18
|
|
|
20
|
-
static VALUE Buffer_wrap(VALUE klass, sfBuffer
|
|
19
|
+
static VALUE Buffer_wrap(VALUE klass, sfBuffer* buffer) {
|
|
21
20
|
return TypedData_Wrap_Struct(klass, &Buffer_data_type, buffer);
|
|
22
21
|
}
|
|
23
22
|
|
|
23
|
+
/* call-seq:
|
|
24
|
+
* Buffer.new -> Buffer
|
|
25
|
+
*
|
|
26
|
+
* Creates a new, empty byte buffer.
|
|
27
|
+
*
|
|
28
|
+
* @return [Buffer] a new, empty buffer
|
|
29
|
+
* @raise [NoMemoryError] if the underlying buffer could not be allocated
|
|
30
|
+
*/
|
|
24
31
|
static VALUE Buffer_new(VALUE klass) {
|
|
25
32
|
VALUE self;
|
|
26
|
-
sfBuffer
|
|
33
|
+
sfBuffer* buffer = sfBuffer_create();
|
|
27
34
|
|
|
28
35
|
if (buffer == NULL) {
|
|
29
36
|
rb_raise(rb_eNoMemError, "could not create buffer");
|
|
@@ -34,28 +41,50 @@ static VALUE Buffer_new(VALUE klass) {
|
|
|
34
41
|
return self;
|
|
35
42
|
}
|
|
36
43
|
|
|
44
|
+
/* call-seq: size -> Integer
|
|
45
|
+
*
|
|
46
|
+
* Returns the size of the buffer in bytes.
|
|
47
|
+
*
|
|
48
|
+
* @return [Integer] size in bytes
|
|
49
|
+
*/
|
|
37
50
|
static VALUE Buffer_get_size(VALUE self) {
|
|
38
51
|
return SIZET2NUM(sfBuffer_getSize(Get_Buffer_Struct(self)));
|
|
39
52
|
}
|
|
40
53
|
|
|
54
|
+
/* call-seq: data -> String
|
|
55
|
+
*
|
|
56
|
+
* Returns the raw bytes held by the buffer.
|
|
57
|
+
*
|
|
58
|
+
* @return [String] the raw bytes, as a binary String
|
|
59
|
+
*/
|
|
41
60
|
static VALUE Buffer_get_data(VALUE self) {
|
|
42
|
-
sfBuffer
|
|
61
|
+
sfBuffer* buffer = Get_Buffer_Struct(self);
|
|
43
62
|
size_t size = sfBuffer_getSize(buffer);
|
|
44
|
-
const uint8_t
|
|
63
|
+
const uint8_t* data = sfBuffer_getData(buffer);
|
|
45
64
|
|
|
46
65
|
if (data == NULL || size == 0) {
|
|
47
66
|
return rb_str_new("", 0);
|
|
48
67
|
}
|
|
49
68
|
|
|
50
|
-
return rb_str_new((const char
|
|
69
|
+
return rb_str_new((const char*)data, (long)size);
|
|
51
70
|
}
|
|
52
71
|
|
|
72
|
+
/* call-seq: empty? -> true or false
|
|
73
|
+
*
|
|
74
|
+
* Returns +true+ if the buffer holds no bytes.
|
|
75
|
+
*
|
|
76
|
+
* @return [Boolean]
|
|
77
|
+
*/
|
|
53
78
|
static VALUE Buffer_is_empty(VALUE self) {
|
|
54
79
|
return BOOL2RB(sfBuffer_getSize(Get_Buffer_Struct(self)) == 0);
|
|
55
80
|
}
|
|
56
81
|
|
|
57
|
-
|
|
58
|
-
|
|
82
|
+
/* Document-class: SFML::Buffer
|
|
83
|
+
* A raw byte buffer, as used for encoded/decoded audio and image data
|
|
84
|
+
* elsewhere in the library.
|
|
85
|
+
*/
|
|
86
|
+
void Init_Buffer(VALUE rb_mSFML) {
|
|
87
|
+
rb_cBuffer = rb_define_class_under(rb_mSFML, "Buffer", rb_cObject);
|
|
59
88
|
|
|
60
89
|
rb_define_singleton_method(rb_cBuffer, "new", Buffer_new, 0);
|
|
61
90
|
|
|
@@ -70,8 +99,8 @@ VALUE Get_Klass_Buffer(void) {
|
|
|
70
99
|
return rb_cBuffer;
|
|
71
100
|
}
|
|
72
101
|
|
|
73
|
-
void
|
|
74
|
-
sfBuffer
|
|
102
|
+
void* Get_Buffer_Struct(VALUE self) {
|
|
103
|
+
sfBuffer* ptr;
|
|
75
104
|
TypedData_Get_Struct(self, sfBuffer, &Buffer_data_type, ptr);
|
|
76
105
|
return ptr;
|
|
77
106
|
}
|
data/ext/system/clock.c
CHANGED
|
@@ -9,23 +9,26 @@
|
|
|
9
9
|
|
|
10
10
|
static VALUE rb_cClock;
|
|
11
11
|
|
|
12
|
-
static sfClock
|
|
12
|
+
static sfClock* Clock_create() {
|
|
13
13
|
return sfClock_create();
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
static void Clock_free(void
|
|
16
|
+
static void Clock_free(void* ptr) {
|
|
17
17
|
sfClock_destroy(ptr);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
static const rb_data_type_t Clock_data_type = {
|
|
21
21
|
.wrap_struct_name = "SFML::Clock",
|
|
22
22
|
.function = {.dmark = NULL, .dfree = Clock_free, .dsize = NULL},
|
|
23
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
24
|
-
};
|
|
23
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
25
24
|
|
|
26
|
-
static VALUE Clock_new_from(VALUE klass, sfClock
|
|
25
|
+
static VALUE Clock_new_from(VALUE klass, sfClock* clock) {
|
|
27
26
|
VALUE self;
|
|
28
27
|
|
|
28
|
+
if (clock == NULL) {
|
|
29
|
+
rb_raise(rb_eNoMemError, "failed to allocate clock");
|
|
30
|
+
}
|
|
31
|
+
|
|
29
32
|
self = TypedData_Wrap_Struct(klass, &Clock_data_type, clock);
|
|
30
33
|
|
|
31
34
|
rb_obj_call_init(self, 0, NULL);
|
|
@@ -33,6 +36,13 @@ static VALUE Clock_new_from(VALUE klass, sfClock *clock) {
|
|
|
33
36
|
return self;
|
|
34
37
|
}
|
|
35
38
|
|
|
39
|
+
/* call-seq:
|
|
40
|
+
* Clock.new -> Clock
|
|
41
|
+
*
|
|
42
|
+
* Creates a new clock and starts it immediately.
|
|
43
|
+
*
|
|
44
|
+
* @return [Clock]
|
|
45
|
+
*/
|
|
36
46
|
static VALUE Clock_new(VALUE klass) {
|
|
37
47
|
return Clock_new_from(klass, Clock_create());
|
|
38
48
|
}
|
|
@@ -41,38 +51,87 @@ static VALUE Clock_init(VALUE self) {
|
|
|
41
51
|
return self;
|
|
42
52
|
}
|
|
43
53
|
|
|
54
|
+
/* call-seq: elapsed_time -> Time
|
|
55
|
+
*
|
|
56
|
+
* Returns the time elapsed on the clock.
|
|
57
|
+
*
|
|
58
|
+
* @return [Time] time elapsed since the clock was created, started, or last
|
|
59
|
+
* restarted/reset, whichever is most recent
|
|
60
|
+
*/
|
|
44
61
|
static VALUE Clock_get_elapsed_time(VALUE self) {
|
|
45
62
|
return time_to_rb(sfClock_getElapsedTime(Get_Clock_Struct(self)));
|
|
46
63
|
}
|
|
47
64
|
|
|
65
|
+
/* call-seq: restart! -> Time
|
|
66
|
+
*
|
|
67
|
+
* Restarts the clock (equivalent to #reset! followed by #start!) and
|
|
68
|
+
* returns the time elapsed before restarting.
|
|
69
|
+
*
|
|
70
|
+
* @return [Time]
|
|
71
|
+
*/
|
|
48
72
|
static VALUE Clock_restart(VALUE self) {
|
|
49
73
|
return time_to_rb(sfClock_restart(Get_Clock_Struct(self)));
|
|
50
74
|
}
|
|
51
75
|
|
|
76
|
+
/* call-seq: reset! -> Time
|
|
77
|
+
*
|
|
78
|
+
* Stops the clock and resets its elapsed time to zero, returning the time
|
|
79
|
+
* elapsed before resetting.
|
|
80
|
+
*
|
|
81
|
+
* @return [Time]
|
|
82
|
+
*/
|
|
52
83
|
static VALUE Clock_reset(VALUE self) {
|
|
53
84
|
return time_to_rb(sfClock_reset(Get_Clock_Struct(self)));
|
|
54
85
|
}
|
|
55
86
|
|
|
87
|
+
/* call-seq: running? -> true or false
|
|
88
|
+
*
|
|
89
|
+
* Returns +true+ while the clock is running, +false+ once it is stopped.
|
|
90
|
+
*
|
|
91
|
+
* @return [Boolean]
|
|
92
|
+
*/
|
|
56
93
|
static VALUE Clock_is_running(VALUE self) {
|
|
57
94
|
return BOOL2RB(sfClock_isRunning(Get_Clock_Struct(self)));
|
|
58
95
|
}
|
|
59
96
|
|
|
97
|
+
/* call-seq: start! -> self
|
|
98
|
+
*
|
|
99
|
+
* Resumes a stopped clock without resetting its elapsed time.
|
|
100
|
+
*
|
|
101
|
+
* @return [self]
|
|
102
|
+
*/
|
|
60
103
|
static VALUE Clock_start(VALUE self) {
|
|
61
104
|
sfClock_start(Get_Clock_Struct(self));
|
|
62
105
|
return self;
|
|
63
106
|
}
|
|
64
107
|
|
|
108
|
+
/* call-seq: stop! -> self
|
|
109
|
+
*
|
|
110
|
+
* Pauses the clock; #elapsed_time keeps returning the time at which it
|
|
111
|
+
* was stopped until #start! or #restart! is called.
|
|
112
|
+
*
|
|
113
|
+
* @return [self]
|
|
114
|
+
*/
|
|
65
115
|
static VALUE Clock_stop(VALUE self) {
|
|
66
116
|
sfClock_stop(Get_Clock_Struct(self));
|
|
67
117
|
return self;
|
|
68
118
|
}
|
|
69
119
|
|
|
120
|
+
/* call-seq: copy -> Clock
|
|
121
|
+
*
|
|
122
|
+
* Returns an independent copy of the clock.
|
|
123
|
+
*
|
|
124
|
+
* @return [Clock] an independent copy with the same elapsed/running state
|
|
125
|
+
*/
|
|
70
126
|
static VALUE Clock_copy(VALUE self) {
|
|
71
127
|
return Clock_new_from(Get_Klass_Clock(), sfClock_copy(Get_Clock_Struct(self)));
|
|
72
128
|
}
|
|
73
129
|
|
|
74
|
-
|
|
75
|
-
|
|
130
|
+
/* Document-class: SFML::Clock
|
|
131
|
+
* A stopwatch for measuring elapsed time.
|
|
132
|
+
*/
|
|
133
|
+
void Init_Clock(VALUE rb_mSFML) {
|
|
134
|
+
rb_cClock = rb_define_class_under(rb_mSFML, "Clock", rb_cObject);
|
|
76
135
|
|
|
77
136
|
rb_define_singleton_method(rb_cClock, "new", Clock_new, 0);
|
|
78
137
|
|
|
@@ -89,8 +148,8 @@ void Init_Clock(VALUE rb_module) {
|
|
|
89
148
|
rb_define_method(rb_cClock, "running?", Clock_is_running, 0);
|
|
90
149
|
}
|
|
91
150
|
|
|
92
|
-
void
|
|
93
|
-
sfClock
|
|
151
|
+
void* Get_Clock_Struct(VALUE self) {
|
|
152
|
+
sfClock* clock;
|
|
94
153
|
TypedData_Get_Struct(self, sfClock, &Clock_data_type, clock);
|
|
95
154
|
return clock;
|
|
96
155
|
}
|
data/ext/system/input_stream.c
CHANGED
|
@@ -16,21 +16,20 @@ typedef struct {
|
|
|
16
16
|
|
|
17
17
|
static VALUE rb_cInputStream;
|
|
18
18
|
|
|
19
|
-
static void InputStream_mark(void
|
|
20
|
-
InputStream
|
|
19
|
+
static void InputStream_mark(void* ptr) {
|
|
20
|
+
InputStream* stream = ptr;
|
|
21
21
|
|
|
22
22
|
rb_gc_mark(stream->rb_io);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
static void InputStream_free(void
|
|
25
|
+
static void InputStream_free(void* ptr) {
|
|
26
26
|
free(ptr);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
static const rb_data_type_t InputStream_data_type = {
|
|
30
30
|
.wrap_struct_name = "SFML::InputStream",
|
|
31
31
|
.function = {.dmark = InputStream_mark, .dfree = InputStream_free, .dsize = NULL},
|
|
32
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
33
|
-
};
|
|
32
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
34
33
|
|
|
35
34
|
/* Callbacks run from C++ (SFML), so a Ruby exception must never unwind through
|
|
36
35
|
those frames. Each body runs under rb_protect and reports failure as a
|
|
@@ -38,12 +37,12 @@ static const rb_data_type_t InputStream_data_type = {
|
|
|
38
37
|
typedef struct {
|
|
39
38
|
VALUE io;
|
|
40
39
|
size_t size;
|
|
41
|
-
void
|
|
40
|
+
void* data;
|
|
42
41
|
int64_t result;
|
|
43
42
|
} ReadContext;
|
|
44
43
|
|
|
45
44
|
static VALUE InputStream_read_body(VALUE v) {
|
|
46
|
-
ReadContext
|
|
45
|
+
ReadContext* ctx = (ReadContext*)v;
|
|
47
46
|
VALUE str = rb_funcall(ctx->io, rb_intern("read"), 1, SIZET2NUM(ctx->size));
|
|
48
47
|
|
|
49
48
|
if (NIL_P(str)) {
|
|
@@ -55,25 +54,31 @@ static VALUE InputStream_read_body(VALUE v) {
|
|
|
55
54
|
|
|
56
55
|
long length = RSTRING_LEN(str);
|
|
57
56
|
|
|
58
|
-
if ((size_t)
|
|
59
|
-
length = (long)
|
|
57
|
+
if ((size_t)length > ctx->size) {
|
|
58
|
+
length = (long)ctx->size;
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
if (length > 0) {
|
|
63
|
-
|
|
62
|
+
const unsigned char* src = (const unsigned char*)RSTRING_PTR(str);
|
|
63
|
+
unsigned char* dest = ctx->data;
|
|
64
|
+
long i;
|
|
65
|
+
|
|
66
|
+
for (i = 0; i < length; i++) {
|
|
67
|
+
dest[i] = src[i];
|
|
68
|
+
}
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
ctx->result = (int64_t)
|
|
71
|
+
ctx->result = (int64_t)length;
|
|
67
72
|
|
|
68
73
|
return Qnil;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
static int64_t InputStream_read(void
|
|
72
|
-
InputStream
|
|
76
|
+
static int64_t InputStream_read(void* data, size_t size, void* userData) {
|
|
77
|
+
InputStream* stream = userData;
|
|
73
78
|
ReadContext ctx = {.io = stream->rb_io, .size = size, .data = data, .result = -1};
|
|
74
79
|
int state = 0;
|
|
75
80
|
|
|
76
|
-
rb_protect(InputStream_read_body, (VALUE)
|
|
81
|
+
rb_protect(InputStream_read_body, (VALUE)&ctx, &state);
|
|
77
82
|
|
|
78
83
|
if (state) {
|
|
79
84
|
rb_set_errinfo(Qnil);
|
|
@@ -90,20 +95,20 @@ typedef struct {
|
|
|
90
95
|
} SeekContext;
|
|
91
96
|
|
|
92
97
|
static VALUE InputStream_seek_body(VALUE v) {
|
|
93
|
-
SeekContext
|
|
98
|
+
SeekContext* ctx = (SeekContext*)v;
|
|
94
99
|
|
|
95
100
|
rb_funcall(ctx->io, rb_intern("seek"), 2, SIZET2NUM(ctx->position), INT2NUM(SEEK_SET));
|
|
96
|
-
ctx->result = (int64_t)
|
|
101
|
+
ctx->result = (int64_t)ctx->position;
|
|
97
102
|
|
|
98
103
|
return Qnil;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
static int64_t InputStream_seek(size_t position, void
|
|
102
|
-
InputStream
|
|
106
|
+
static int64_t InputStream_seek(size_t position, void* userData) {
|
|
107
|
+
InputStream* stream = userData;
|
|
103
108
|
SeekContext ctx = {.io = stream->rb_io, .position = position, .result = -1};
|
|
104
109
|
int state = 0;
|
|
105
110
|
|
|
106
|
-
rb_protect(InputStream_seek_body, (VALUE)
|
|
111
|
+
rb_protect(InputStream_seek_body, (VALUE)&ctx, &state);
|
|
107
112
|
|
|
108
113
|
if (state) {
|
|
109
114
|
rb_set_errinfo(Qnil);
|
|
@@ -113,55 +118,91 @@ static int64_t InputStream_seek(size_t position, void *userData) {
|
|
|
113
118
|
return ctx.result;
|
|
114
119
|
}
|
|
115
120
|
|
|
121
|
+
typedef struct {
|
|
122
|
+
VALUE io;
|
|
123
|
+
int64_t result;
|
|
124
|
+
} Int64Context;
|
|
125
|
+
|
|
126
|
+
/* NUM2LL is done here, inside the rb_protect-called body, rather than after
|
|
127
|
+
rb_protect returns: if the IO's #tell/#pos/#size/#length returns something
|
|
128
|
+
that doesn't convert cleanly to a C integer (a String, nil, a Bignum too
|
|
129
|
+
large for int64_t, a #to_int that itself raises), NUM2LL raises directly --
|
|
130
|
+
and unprotected, that exception would unwind straight through CSFML's (and
|
|
131
|
+
possibly SFML's C++) stack frames, exactly what rb_protect exists to
|
|
132
|
+
prevent here. */
|
|
116
133
|
static VALUE InputStream_tell_body(VALUE v) {
|
|
117
|
-
|
|
134
|
+
Int64Context* ctx = (Int64Context*)v;
|
|
135
|
+
VALUE result;
|
|
118
136
|
|
|
119
|
-
if (rb_respond_to(io, rb_intern("tell"))) {
|
|
120
|
-
|
|
137
|
+
if (rb_respond_to(ctx->io, rb_intern("tell"))) {
|
|
138
|
+
result = rb_funcall(ctx->io, rb_intern("tell"), 0);
|
|
139
|
+
} else {
|
|
140
|
+
result = rb_funcall(ctx->io, rb_intern("pos"), 0);
|
|
121
141
|
}
|
|
122
142
|
|
|
123
|
-
|
|
143
|
+
ctx->result = NUM2LL(result);
|
|
144
|
+
|
|
145
|
+
return Qnil;
|
|
124
146
|
}
|
|
125
147
|
|
|
126
|
-
static int64_t InputStream_tell(void
|
|
127
|
-
InputStream
|
|
148
|
+
static int64_t InputStream_tell(void* userData) {
|
|
149
|
+
InputStream* stream = userData;
|
|
150
|
+
Int64Context ctx = {.io = stream->rb_io, .result = -1};
|
|
128
151
|
int state = 0;
|
|
129
|
-
|
|
152
|
+
|
|
153
|
+
rb_protect(InputStream_tell_body, (VALUE)&ctx, &state);
|
|
130
154
|
|
|
131
155
|
if (state) {
|
|
132
156
|
rb_set_errinfo(Qnil);
|
|
133
157
|
return -1;
|
|
134
158
|
}
|
|
135
159
|
|
|
136
|
-
return
|
|
160
|
+
return ctx.result;
|
|
137
161
|
}
|
|
138
162
|
|
|
139
163
|
static VALUE InputStream_get_size_body(VALUE v) {
|
|
140
|
-
|
|
164
|
+
Int64Context* ctx = (Int64Context*)v;
|
|
165
|
+
VALUE result;
|
|
141
166
|
|
|
142
|
-
if (rb_respond_to(io, rb_intern("size"))) {
|
|
143
|
-
|
|
167
|
+
if (rb_respond_to(ctx->io, rb_intern("size"))) {
|
|
168
|
+
result = rb_funcall(ctx->io, rb_intern("size"), 0);
|
|
169
|
+
} else {
|
|
170
|
+
result = rb_funcall(ctx->io, rb_intern("length"), 0);
|
|
144
171
|
}
|
|
145
172
|
|
|
146
|
-
|
|
173
|
+
ctx->result = NUM2LL(result);
|
|
174
|
+
|
|
175
|
+
return Qnil;
|
|
147
176
|
}
|
|
148
177
|
|
|
149
|
-
static int64_t InputStream_get_size(void
|
|
150
|
-
InputStream
|
|
178
|
+
static int64_t InputStream_get_size(void* userData) {
|
|
179
|
+
InputStream* stream = userData;
|
|
180
|
+
Int64Context ctx = {.io = stream->rb_io, .result = -1};
|
|
151
181
|
int state = 0;
|
|
152
|
-
|
|
182
|
+
|
|
183
|
+
rb_protect(InputStream_get_size_body, (VALUE)&ctx, &state);
|
|
153
184
|
|
|
154
185
|
if (state) {
|
|
155
186
|
rb_set_errinfo(Qnil);
|
|
156
187
|
return -1;
|
|
157
188
|
}
|
|
158
189
|
|
|
159
|
-
return
|
|
190
|
+
return ctx.result;
|
|
160
191
|
}
|
|
161
192
|
|
|
193
|
+
/* call-seq:
|
|
194
|
+
* InputStream.new(io) -> InputStream
|
|
195
|
+
*
|
|
196
|
+
* Wraps a Ruby object that responds to +#read+ (and ideally +#seek+/+#tell+
|
|
197
|
+
* or +#pos+, and +#size+ or +#length+) so it can be passed anywhere the
|
|
198
|
+
* library accepts a stream-based data source.
|
|
199
|
+
*
|
|
200
|
+
* @return [InputStream]
|
|
201
|
+
* @raise [ArgumentError] if +io+ does not respond to +#read+
|
|
202
|
+
*/
|
|
162
203
|
static VALUE InputStream_new(VALUE klass, VALUE rb_io) {
|
|
163
204
|
VALUE self;
|
|
164
|
-
InputStream
|
|
205
|
+
InputStream* stream;
|
|
165
206
|
|
|
166
207
|
if (!rb_respond_to(rb_io, rb_intern("read"))) {
|
|
167
208
|
rb_raise(rb_eArgError, "stream object must respond to #read");
|
|
@@ -181,12 +222,23 @@ static VALUE InputStream_new(VALUE klass, VALUE rb_io) {
|
|
|
181
222
|
return self;
|
|
182
223
|
}
|
|
183
224
|
|
|
225
|
+
/* call-seq: io -> Object
|
|
226
|
+
*
|
|
227
|
+
* Returns the IO-like object the stream was created from.
|
|
228
|
+
*
|
|
229
|
+
* @return [Object] the wrapped IO-like object
|
|
230
|
+
*/
|
|
184
231
|
static VALUE InputStream_get_io(VALUE self) {
|
|
185
|
-
return ((InputStream
|
|
232
|
+
return ((InputStream*)Get_InputStream_Struct(self))->rb_io;
|
|
186
233
|
}
|
|
187
234
|
|
|
188
|
-
|
|
189
|
-
|
|
235
|
+
/* Document-class: SFML::InputStream
|
|
236
|
+
* Adapts any Ruby object that responds to +#read+ into the stream interface
|
|
237
|
+
* SFML's loaders expect, so resources can be loaded from something other
|
|
238
|
+
* than a filesystem path (e.g. an in-memory StringIO, or a custom source).
|
|
239
|
+
*/
|
|
240
|
+
void Init_InputStream(VALUE rb_mSFML) {
|
|
241
|
+
rb_cInputStream = rb_define_class_under(rb_mSFML, "InputStream", rb_cObject);
|
|
190
242
|
|
|
191
243
|
rb_define_singleton_method(rb_cInputStream, "new", InputStream_new, 1);
|
|
192
244
|
|
|
@@ -197,8 +249,8 @@ VALUE Get_Klass_InputStream(void) {
|
|
|
197
249
|
return rb_cInputStream;
|
|
198
250
|
}
|
|
199
251
|
|
|
200
|
-
sfInputStream
|
|
201
|
-
InputStream
|
|
252
|
+
sfInputStream* Get_InputStream_Struct(VALUE self) {
|
|
253
|
+
InputStream* ptr;
|
|
202
254
|
TypedData_Get_Struct(self, InputStream, &InputStream_data_type, ptr);
|
|
203
255
|
return &ptr->stream;
|
|
204
256
|
}
|
|
@@ -207,7 +259,7 @@ int InputStream_is_stream(VALUE rb_stream) {
|
|
|
207
259
|
return rb_obj_is_kind_of(rb_stream, rb_cInputStream) ? 1 : 0;
|
|
208
260
|
}
|
|
209
261
|
|
|
210
|
-
sfInputStream
|
|
262
|
+
sfInputStream* input_stream_from_rb(VALUE rb_stream, VALUE* holder) {
|
|
211
263
|
if (InputStream_is_stream(rb_stream)) {
|
|
212
264
|
return Get_InputStream_Struct(rb_stream);
|
|
213
265
|
}
|
data/ext/system/sleep.c
CHANGED
|
@@ -5,12 +5,20 @@
|
|
|
5
5
|
#include "system/time.h"
|
|
6
6
|
#include "core/sfml.h"
|
|
7
7
|
|
|
8
|
+
/* call-seq:
|
|
9
|
+
* SFML.sleep(duration) -> duration
|
|
10
|
+
*
|
|
11
|
+
* Blocks the calling thread for +duration+, which may be a Time, a number
|
|
12
|
+
* of seconds, or anything #to_f-convertible.
|
|
13
|
+
*
|
|
14
|
+
* @return [Time, Numeric] +duration+
|
|
15
|
+
*/
|
|
8
16
|
static VALUE Sleep_sleep(VALUE module, VALUE rb_duration) {
|
|
9
17
|
sfSleep(time_from_rb(rb_duration));
|
|
10
18
|
|
|
11
19
|
return rb_duration;
|
|
12
20
|
}
|
|
13
21
|
|
|
14
|
-
void Init_Sleep(VALUE
|
|
15
|
-
rb_define_module_function(
|
|
22
|
+
void Init_Sleep(VALUE rb_mSFML) {
|
|
23
|
+
rb_define_module_function(rb_mSFML, "sleep", Sleep_sleep, 1);
|
|
16
24
|
}
|