sfml3-rb 0.0.1 → 0.2.2
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/CHANGELOG.md +342 -0
- data/README.md +51 -14
- data/TODO.md +199 -0
- data/ext/audio/audio_enums.c +131 -0
- data/ext/audio/audio_enums.h +18 -0
- data/ext/audio/effect_processor.c +233 -0
- data/ext/audio/effect_processor.h +25 -0
- data/ext/audio/listener.c +83 -0
- data/ext/audio/listener.h +8 -0
- data/ext/audio/music.c +174 -0
- data/ext/audio/music.h +14 -0
- data/ext/audio/sound.c +139 -0
- data/ext/audio/sound.h +14 -0
- data/ext/audio/sound_buffer.c +274 -0
- data/ext/audio/sound_buffer.h +18 -0
- data/ext/audio/sound_buffer_recorder.c +109 -0
- data/ext/audio/sound_buffer_recorder.h +14 -0
- data/ext/audio/sound_recorder.c +268 -0
- data/ext/audio/sound_recorder.h +14 -0
- data/ext/audio/sound_source.h +13 -0
- data/ext/audio/sound_source.inc +271 -0
- data/ext/audio/sound_source_cone.c +138 -0
- data/ext/audio/sound_source_cone.h +20 -0
- data/ext/audio/sound_stream.c +294 -0
- data/ext/audio/sound_stream.h +14 -0
- data/ext/{exceptions.c → core/exceptions.c} +10 -8
- data/ext/{ext → core}/exceptions.h +3 -3
- data/ext/core/foreign_thread.c +149 -0
- data/ext/core/foreign_thread.h +31 -0
- data/ext/core/macros.h +8 -0
- data/ext/{ext → core}/sfml.h +5 -3
- data/ext/core/unicode.c +46 -0
- data/ext/core/unicode.h +25 -0
- data/ext/ext.c +125 -14
- data/ext/extconf.rb +51 -6
- data/ext/graphics/blend_mode.c +261 -0
- data/ext/graphics/blend_mode.h +18 -0
- data/ext/graphics/circle.c +319 -0
- data/ext/{ext/klass/drawable → graphics}/circle.h +3 -3
- data/ext/graphics/color.c +318 -0
- data/ext/graphics/color.h +37 -0
- data/ext/{drawable.c → graphics/drawable.c} +11 -11
- data/ext/graphics/drawable.h +10 -0
- data/ext/graphics/enums.c +123 -0
- data/ext/graphics/enums.h +20 -0
- data/ext/graphics/font.c +148 -0
- data/ext/graphics/font.h +14 -0
- data/ext/graphics/glyph.c +60 -0
- data/ext/graphics/glyph.h +14 -0
- data/ext/graphics/image.c +205 -0
- data/ext/graphics/image.h +16 -0
- data/ext/graphics/polygon.c +300 -0
- data/ext/graphics/polygon.h +10 -0
- data/ext/graphics/rect.c +287 -0
- data/ext/graphics/rect.h +30 -0
- data/ext/graphics/rectangle.c +302 -0
- data/ext/graphics/rectangle.h +10 -0
- data/ext/graphics/render_state.c +204 -0
- data/ext/graphics/render_state.h +18 -0
- data/ext/graphics/render_target.inc +181 -0
- data/ext/graphics/render_texture.c +182 -0
- data/ext/graphics/render_texture.h +14 -0
- data/ext/graphics/shader.c +540 -0
- data/ext/graphics/shader.h +14 -0
- data/ext/graphics/shape.c +311 -0
- data/ext/graphics/shape.h +10 -0
- data/ext/graphics/sprite.c +249 -0
- data/ext/graphics/sprite.h +10 -0
- data/ext/graphics/stencil_mode.c +211 -0
- data/ext/graphics/stencil_mode.h +18 -0
- data/ext/graphics/target.c +133 -0
- data/ext/graphics/target.h +40 -0
- data/ext/graphics/text.c +344 -0
- data/ext/graphics/text.h +10 -0
- data/ext/graphics/texture.c +379 -0
- data/ext/graphics/texture.h +16 -0
- data/ext/graphics/transform.c +372 -0
- data/ext/graphics/transform.h +35 -0
- data/ext/{transformable.c → graphics/transformable.c} +168 -144
- data/ext/{ext/klass → graphics}/transformable.h +3 -3
- data/ext/graphics/vertex.c +179 -0
- data/ext/graphics/vertex.h +23 -0
- data/ext/graphics/vertex_array.c +127 -0
- data/ext/graphics/vertex_array.h +10 -0
- data/ext/graphics/vertex_buffer.c +211 -0
- data/ext/graphics/vertex_buffer.h +14 -0
- data/ext/{view.c → graphics/view.c} +168 -169
- data/ext/{ext/klass → graphics}/view.h +3 -3
- data/ext/network/ftp.c +405 -0
- data/ext/network/ftp.h +20 -0
- data/ext/network/http.c +243 -0
- data/ext/network/http.h +18 -0
- data/ext/network/ip_address.c +164 -0
- data/ext/network/ip_address.h +20 -0
- data/ext/network/network_enums.c +298 -0
- data/ext/network/network_enums.h +26 -0
- data/ext/network/packet.c +189 -0
- data/ext/network/packet.h +14 -0
- data/ext/network/socket_selector.c +142 -0
- data/ext/network/socket_selector.h +14 -0
- data/ext/network/tcp_listener.c +115 -0
- data/ext/network/tcp_listener.h +14 -0
- data/ext/network/tcp_socket.c +199 -0
- data/ext/network/tcp_socket.h +17 -0
- data/ext/network/udp_socket.c +190 -0
- data/ext/network/udp_socket.h +14 -0
- data/ext/ports.rb +97 -21
- data/ext/system/buffer.c +77 -0
- data/ext/system/buffer.h +14 -0
- data/ext/system/clock.c +100 -0
- data/ext/{ext/klass → system}/clock.h +3 -3
- data/ext/system/input_stream.c +229 -0
- data/ext/system/input_stream.h +23 -0
- data/ext/system/sleep.c +16 -0
- data/ext/system/sleep.h +8 -0
- data/ext/system/time.c +218 -0
- data/ext/system/time.h +18 -0
- data/ext/system/vec2.c +251 -0
- data/ext/system/vec2.h +55 -0
- data/ext/system/vec3.c +219 -0
- data/ext/system/vec3.h +18 -0
- data/ext/window/clipboard.c +89 -0
- data/ext/window/clipboard.h +8 -0
- data/ext/window/context.c +70 -0
- data/ext/window/context.h +8 -0
- data/ext/window/context_settings.c +220 -0
- data/ext/window/context_settings.h +18 -0
- data/ext/window/cursor.c +56 -0
- data/ext/window/cursor.h +14 -0
- data/ext/window/event.c +216 -0
- data/ext/window/event.h +14 -0
- data/ext/{event_name.c → window/event_name.c} +2 -2
- data/ext/window/event_name.h +8 -0
- data/ext/window/input_enums.c +261 -0
- data/ext/window/input_enums.h +36 -0
- data/ext/window/joystick.c +60 -0
- data/ext/window/joystick.h +8 -0
- data/ext/{keyboard.c → window/keyboard.c} +74 -2
- data/ext/window/keyboard.h +12 -0
- data/ext/window/mouse.c +70 -0
- data/ext/window/mouse.h +8 -0
- data/ext/window/sensor.c +30 -0
- data/ext/window/sensor.h +8 -0
- data/ext/window/touch.c +49 -0
- data/ext/window/touch.h +8 -0
- data/ext/window/video_mode.c +133 -0
- data/ext/window/video_mode.h +14 -0
- data/ext/window/vulkan.c +44 -0
- data/ext/window/vulkan.h +8 -0
- data/ext/window/window.c +414 -0
- data/ext/{ext/klass → window}/window.h +3 -3
- data/lib/sfml/version.rb +4 -2
- data/lib/sfml.rb +2 -0
- metadata +163 -56
- data/ext/circle.c +0 -198
- data/ext/clock.c +0 -65
- data/ext/color.c +0 -43
- data/ext/event.c +0 -148
- data/ext/ext/klass/color.h +0 -26
- data/ext/ext/klass/drawable/image.h +0 -4
- data/ext/ext/klass/drawable/polygon.h +0 -4
- data/ext/ext/klass/drawable/rectangle.h +0 -4
- data/ext/ext/klass/drawable/sprite.h +0 -4
- data/ext/ext/klass/drawable/texture.h +0 -4
- data/ext/ext/klass/event/event_name.h +0 -8
- data/ext/ext/klass/event.h +0 -12
- data/ext/ext/klass/keyboard.h +0 -8
- data/ext/ext/klass/render_state.h +0 -16
- data/ext/ext/klass/target.h +0 -18
- data/ext/ext/klass/transform.h +0 -17
- data/ext/ext/klass/video_mode.h +0 -12
- data/ext/ext/module/drawable/drawable.h +0 -10
- data/ext/ext/module/transform.h +0 -18
- data/ext/ext/module.h +0 -10
- data/ext/ext/rect.h +0 -16
- data/ext/ext/style_name.h +0 -11
- data/ext/ext/vec2.h +0 -38
- data/ext/image.c +0 -5
- data/ext/polygon.c +0 -5
- data/ext/rect.c +0 -26
- data/ext/rectangle.c +0 -5
- data/ext/render_state.c +0 -109
- data/ext/sprite.c +0 -5
- data/ext/style_name.c +0 -15
- data/ext/target.c +0 -106
- data/ext/texture.c +0 -5
- data/ext/transform.c +0 -107
- data/ext/vec2.c +0 -42
- data/ext/video_mode.c +0 -78
- data/ext/window.c +0 -274
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
#include "system/input_stream.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
#include <stdio.h>
|
|
5
|
+
#include <string.h>
|
|
6
|
+
|
|
7
|
+
#include "core/exceptions.h"
|
|
8
|
+
|
|
9
|
+
/* Wrap a Ruby IO-like object (read/seek/tell, optionally size). The struct is
|
|
10
|
+
owned by the Ruby object; userData points at it, and dmark keeps the IO
|
|
11
|
+
alive for as long as any load call might touch it. */
|
|
12
|
+
typedef struct {
|
|
13
|
+
sfInputStream stream;
|
|
14
|
+
VALUE rb_io;
|
|
15
|
+
} InputStream;
|
|
16
|
+
|
|
17
|
+
static VALUE rb_cInputStream;
|
|
18
|
+
|
|
19
|
+
static void InputStream_mark(void *ptr) {
|
|
20
|
+
InputStream *stream = ptr;
|
|
21
|
+
|
|
22
|
+
rb_gc_mark(stream->rb_io);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static void InputStream_free(void *ptr) {
|
|
26
|
+
free(ptr);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static const rb_data_type_t InputStream_data_type = {
|
|
30
|
+
.wrap_struct_name = "SFML::InputStream",
|
|
31
|
+
.function = {.dmark = InputStream_mark, .dfree = InputStream_free, .dsize = NULL},
|
|
32
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/* Callbacks run from C++ (SFML), so a Ruby exception must never unwind through
|
|
36
|
+
those frames. Each body runs under rb_protect and reports failure as a
|
|
37
|
+
negative result instead. */
|
|
38
|
+
typedef struct {
|
|
39
|
+
VALUE io;
|
|
40
|
+
size_t size;
|
|
41
|
+
void *data;
|
|
42
|
+
int64_t result;
|
|
43
|
+
} ReadContext;
|
|
44
|
+
|
|
45
|
+
static VALUE InputStream_read_body(VALUE v) {
|
|
46
|
+
ReadContext *ctx = (ReadContext *) v;
|
|
47
|
+
VALUE str = rb_funcall(ctx->io, rb_intern("read"), 1, SIZET2NUM(ctx->size));
|
|
48
|
+
|
|
49
|
+
if (NIL_P(str)) {
|
|
50
|
+
ctx->result = 0;
|
|
51
|
+
return Qnil;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
StringValue(str);
|
|
55
|
+
|
|
56
|
+
long length = RSTRING_LEN(str);
|
|
57
|
+
|
|
58
|
+
if ((size_t) length > ctx->size) {
|
|
59
|
+
length = (long) ctx->size;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (length > 0) {
|
|
63
|
+
memcpy(ctx->data, RSTRING_PTR(str), (size_t) length);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
ctx->result = (int64_t) length;
|
|
67
|
+
|
|
68
|
+
return Qnil;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static int64_t InputStream_read(void *data, size_t size, void *userData) {
|
|
72
|
+
InputStream *stream = userData;
|
|
73
|
+
ReadContext ctx = {.io = stream->rb_io, .size = size, .data = data, .result = -1};
|
|
74
|
+
int state = 0;
|
|
75
|
+
|
|
76
|
+
rb_protect(InputStream_read_body, (VALUE) &ctx, &state);
|
|
77
|
+
|
|
78
|
+
if (state) {
|
|
79
|
+
rb_set_errinfo(Qnil);
|
|
80
|
+
return -1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return ctx.result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
typedef struct {
|
|
87
|
+
VALUE io;
|
|
88
|
+
size_t position;
|
|
89
|
+
int64_t result;
|
|
90
|
+
} SeekContext;
|
|
91
|
+
|
|
92
|
+
static VALUE InputStream_seek_body(VALUE v) {
|
|
93
|
+
SeekContext *ctx = (SeekContext *) v;
|
|
94
|
+
|
|
95
|
+
rb_funcall(ctx->io, rb_intern("seek"), 2, SIZET2NUM(ctx->position), INT2NUM(SEEK_SET));
|
|
96
|
+
ctx->result = (int64_t) ctx->position;
|
|
97
|
+
|
|
98
|
+
return Qnil;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static int64_t InputStream_seek(size_t position, void *userData) {
|
|
102
|
+
InputStream *stream = userData;
|
|
103
|
+
SeekContext ctx = {.io = stream->rb_io, .position = position, .result = -1};
|
|
104
|
+
int state = 0;
|
|
105
|
+
|
|
106
|
+
rb_protect(InputStream_seek_body, (VALUE) &ctx, &state);
|
|
107
|
+
|
|
108
|
+
if (state) {
|
|
109
|
+
rb_set_errinfo(Qnil);
|
|
110
|
+
return -1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return ctx.result;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static VALUE InputStream_tell_body(VALUE v) {
|
|
117
|
+
VALUE io = (VALUE) v;
|
|
118
|
+
|
|
119
|
+
if (rb_respond_to(io, rb_intern("tell"))) {
|
|
120
|
+
return rb_funcall(io, rb_intern("tell"), 0);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return rb_funcall(io, rb_intern("pos"), 0);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static int64_t InputStream_tell(void *userData) {
|
|
127
|
+
InputStream *stream = userData;
|
|
128
|
+
int state = 0;
|
|
129
|
+
VALUE result = rb_protect(InputStream_tell_body, stream->rb_io, &state);
|
|
130
|
+
|
|
131
|
+
if (state) {
|
|
132
|
+
rb_set_errinfo(Qnil);
|
|
133
|
+
return -1;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return NUM2LL(result);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static VALUE InputStream_get_size_body(VALUE v) {
|
|
140
|
+
VALUE io = (VALUE) v;
|
|
141
|
+
|
|
142
|
+
if (rb_respond_to(io, rb_intern("size"))) {
|
|
143
|
+
return rb_funcall(io, rb_intern("size"), 0);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return rb_funcall(io, rb_intern("length"), 0);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static int64_t InputStream_get_size(void *userData) {
|
|
150
|
+
InputStream *stream = userData;
|
|
151
|
+
int state = 0;
|
|
152
|
+
VALUE result = rb_protect(InputStream_get_size_body, stream->rb_io, &state);
|
|
153
|
+
|
|
154
|
+
if (state) {
|
|
155
|
+
rb_set_errinfo(Qnil);
|
|
156
|
+
return -1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return NUM2LL(result);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static VALUE InputStream_new(VALUE klass, VALUE rb_io) {
|
|
163
|
+
VALUE self;
|
|
164
|
+
InputStream *stream;
|
|
165
|
+
|
|
166
|
+
if (!rb_respond_to(rb_io, rb_intern("read"))) {
|
|
167
|
+
rb_raise(rb_eArgError, "stream object must respond to #read");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
stream = malloc(sizeof(InputStream));
|
|
171
|
+
|
|
172
|
+
stream->rb_io = rb_io;
|
|
173
|
+
stream->stream.read = InputStream_read;
|
|
174
|
+
stream->stream.seek = InputStream_seek;
|
|
175
|
+
stream->stream.tell = InputStream_tell;
|
|
176
|
+
stream->stream.getSize = InputStream_get_size;
|
|
177
|
+
stream->stream.userData = stream;
|
|
178
|
+
|
|
179
|
+
self = TypedData_Wrap_Struct(klass, &InputStream_data_type, stream);
|
|
180
|
+
|
|
181
|
+
return self;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static VALUE InputStream_get_io(VALUE self) {
|
|
185
|
+
return ((InputStream *) Get_InputStream_Struct(self))->rb_io;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
void Init_InputStream(VALUE rb_module) {
|
|
189
|
+
rb_cInputStream = rb_define_class_under(rb_module, "InputStream", rb_cObject);
|
|
190
|
+
|
|
191
|
+
rb_define_singleton_method(rb_cInputStream, "new", InputStream_new, 1);
|
|
192
|
+
|
|
193
|
+
rb_define_method(rb_cInputStream, "io", InputStream_get_io, 0);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
VALUE Get_Klass_InputStream(void) {
|
|
197
|
+
return rb_cInputStream;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
sfInputStream *Get_InputStream_Struct(VALUE self) {
|
|
201
|
+
InputStream *ptr;
|
|
202
|
+
TypedData_Get_Struct(self, InputStream, &InputStream_data_type, ptr);
|
|
203
|
+
return &ptr->stream;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
int InputStream_is_stream(VALUE rb_stream) {
|
|
207
|
+
return rb_obj_is_kind_of(rb_stream, rb_cInputStream) ? 1 : 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
sfInputStream *input_stream_from_rb(VALUE rb_stream, VALUE *holder) {
|
|
211
|
+
if (InputStream_is_stream(rb_stream)) {
|
|
212
|
+
return Get_InputStream_Struct(rb_stream);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (rb_respond_to(rb_stream, rb_intern("read"))) {
|
|
216
|
+
VALUE wrapper = rb_funcall(rb_cInputStream, rb_intern("new"), 1, rb_stream);
|
|
217
|
+
|
|
218
|
+
/* Callers keep this on their own stack so a GC triggered by the load
|
|
219
|
+
call cannot collect the wrapper mid-flight. */
|
|
220
|
+
if (holder != NULL) {
|
|
221
|
+
*holder = wrapper;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return Get_InputStream_Struct(wrapper);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
rb_raise(rb_eArgError, "expected an SFML::InputStream or an object responding to #read");
|
|
228
|
+
return NULL;
|
|
229
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#ifndef SFML_RB_SYSTEM_INPUT_STREAM_H
|
|
2
|
+
#define SFML_RB_SYSTEM_INPUT_STREAM_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_InputStream(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_InputStream(void);
|
|
11
|
+
|
|
12
|
+
sfInputStream *Get_InputStream_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
/* True when the object is an SFML::InputStream. */
|
|
15
|
+
int InputStream_is_stream(VALUE rb_stream);
|
|
16
|
+
|
|
17
|
+
/* Returns the underlying sfInputStream, wrapping any #read-able object in an
|
|
18
|
+
SFML::InputStream first. When wrapping happens the wrapper is stored in
|
|
19
|
+
*holder (a caller-local VALUE), so a GC during the subsequent load cannot
|
|
20
|
+
collect it. */
|
|
21
|
+
sfInputStream *input_stream_from_rb(VALUE rb_stream, VALUE *holder);
|
|
22
|
+
|
|
23
|
+
#endif //SFML_RB_SYSTEM_INPUT_STREAM_H
|
data/ext/system/sleep.c
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#include "system/sleep.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
|
|
5
|
+
#include "system/time.h"
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
static VALUE Sleep_sleep(VALUE module, VALUE rb_duration) {
|
|
9
|
+
sfSleep(time_from_rb(rb_duration));
|
|
10
|
+
|
|
11
|
+
return rb_duration;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
void Init_Sleep(VALUE rb_module) {
|
|
15
|
+
rb_define_module_function(rb_module, "sleep", Sleep_sleep, 1);
|
|
16
|
+
}
|
data/ext/system/sleep.h
ADDED
data/ext/system/time.c
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#include "system/time.h"
|
|
2
|
+
|
|
3
|
+
#include <stdio.h>
|
|
4
|
+
#include <stdlib.h>
|
|
5
|
+
|
|
6
|
+
#include "core/exceptions.h"
|
|
7
|
+
#include "core/macros.h"
|
|
8
|
+
|
|
9
|
+
typedef struct {
|
|
10
|
+
sfTime time;
|
|
11
|
+
} Time;
|
|
12
|
+
|
|
13
|
+
static VALUE rb_cSFTime;
|
|
14
|
+
|
|
15
|
+
static void Time_free(void *ptr) {
|
|
16
|
+
free(ptr);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static const rb_data_type_t Time_data_type = {
|
|
20
|
+
.wrap_struct_name = "SFML::Time",
|
|
21
|
+
.function = {.dmark = NULL, .dfree = Time_free, .dsize = NULL},
|
|
22
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
static VALUE Time_wrap(sfTime time) {
|
|
26
|
+
Time *ptr = malloc(sizeof(Time));
|
|
27
|
+
|
|
28
|
+
ptr->time = time;
|
|
29
|
+
|
|
30
|
+
return TypedData_Wrap_Struct(rb_cSFTime, &Time_data_type, ptr);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static VALUE Time_new(int argc, VALUE *argv, VALUE klass) {
|
|
34
|
+
VALUE self;
|
|
35
|
+
Time *ptr;
|
|
36
|
+
sfTime time = sfTime_Zero;
|
|
37
|
+
|
|
38
|
+
if (argc == 1 && rb_obj_is_kind_of(argv[0], rb_cSFTime)) {
|
|
39
|
+
time = ((Time *) Get_Time_Struct(argv[0]))->time;
|
|
40
|
+
} else if (argc == 1 && RB_INTEGER_TYPE_P(argv[0])) {
|
|
41
|
+
time = sfMicroseconds((int64_t) NUM2LL(argv[0]));
|
|
42
|
+
} else if (argc == 1) {
|
|
43
|
+
time = sfSeconds((float) NUM2DBL(argv[0]));
|
|
44
|
+
} else if (argc != 0) {
|
|
45
|
+
raise_invalid_arguments_excepted(1, argc);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
ptr = malloc(sizeof(Time));
|
|
49
|
+
ptr->time = time;
|
|
50
|
+
|
|
51
|
+
self = TypedData_Wrap_Struct(klass, &Time_data_type, ptr);
|
|
52
|
+
|
|
53
|
+
return self;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static VALUE Time_seconds(VALUE klass, VALUE rb_seconds) {
|
|
57
|
+
return Time_wrap(sfSeconds((float) NUM2DBL(rb_seconds)));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static VALUE Time_milliseconds(VALUE klass, VALUE rb_milliseconds) {
|
|
61
|
+
return Time_wrap(sfMilliseconds((int32_t) NUM2INT(rb_milliseconds)));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static VALUE Time_microseconds(VALUE klass, VALUE rb_microseconds) {
|
|
65
|
+
return Time_wrap(sfMicroseconds((int64_t) NUM2LL(rb_microseconds)));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static VALUE Time_zero(VALUE klass) {
|
|
69
|
+
return Time_wrap(sfTime_Zero);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static VALUE Time_as_seconds(VALUE self) {
|
|
73
|
+
return DBL2NUM(sfTime_asSeconds(((Time *) Get_Time_Struct(self))->time));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static VALUE Time_as_milliseconds(VALUE self) {
|
|
77
|
+
return INT2NUM(sfTime_asMilliseconds(((Time *) Get_Time_Struct(self))->time));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static VALUE Time_as_microseconds(VALUE self) {
|
|
81
|
+
return LL2NUM(sfTime_asMicroseconds(((Time *) Get_Time_Struct(self))->time));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static VALUE Time_to_f(VALUE self) {
|
|
85
|
+
return Time_as_seconds(self);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static VALUE Time_to_i(VALUE self) {
|
|
89
|
+
return Time_as_microseconds(self);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static VALUE Time_add(VALUE self, VALUE rb_other) {
|
|
93
|
+
sfTime a = ((Time *) Get_Time_Struct(self))->time;
|
|
94
|
+
sfTime b = time_from_rb(rb_other);
|
|
95
|
+
|
|
96
|
+
return Time_wrap(sfMicroseconds(sfTime_asMicroseconds(a) + sfTime_asMicroseconds(b)));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static VALUE Time_sub(VALUE self, VALUE rb_other) {
|
|
100
|
+
sfTime a = ((Time *) Get_Time_Struct(self))->time;
|
|
101
|
+
sfTime b = time_from_rb(rb_other);
|
|
102
|
+
|
|
103
|
+
return Time_wrap(sfMicroseconds(sfTime_asMicroseconds(a) - sfTime_asMicroseconds(b)));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static VALUE Time_mul(VALUE self, VALUE rb_scalar) {
|
|
107
|
+
sfTime a = ((Time *) Get_Time_Struct(self))->time;
|
|
108
|
+
|
|
109
|
+
return Time_wrap(sfMicroseconds((int64_t) (sfTime_asMicroseconds(a) * NUM2DBL(rb_scalar))));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static VALUE Time_div(VALUE self, VALUE rb_other) {
|
|
113
|
+
sfTime a = ((Time *) Get_Time_Struct(self))->time;
|
|
114
|
+
|
|
115
|
+
if (rb_obj_is_kind_of(rb_other, rb_cSFTime)) {
|
|
116
|
+
int64_t b = sfTime_asMicroseconds(((Time *) Get_Time_Struct(rb_other))->time);
|
|
117
|
+
|
|
118
|
+
if (b == 0) {
|
|
119
|
+
rb_raise(rb_eZeroDivError, "divided by 0");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return DBL2NUM((double) sfTime_asMicroseconds(a) / (double) b);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return Time_wrap(sfMicroseconds((int64_t) (sfTime_asMicroseconds(a) / NUM2DBL(rb_other))));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static VALUE Time_cmp(VALUE self, VALUE rb_other) {
|
|
129
|
+
sfTime a = ((Time *) Get_Time_Struct(self))->time;
|
|
130
|
+
sfTime b = time_from_rb(rb_other);
|
|
131
|
+
int64_t micro_a = sfTime_asMicroseconds(a);
|
|
132
|
+
int64_t micro_b = sfTime_asMicroseconds(b);
|
|
133
|
+
|
|
134
|
+
if (micro_a < micro_b) {
|
|
135
|
+
return INT2NUM(-1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (micro_a > micro_b) {
|
|
139
|
+
return INT2NUM(1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return INT2NUM(0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static VALUE Time_eql(VALUE self, VALUE rb_other) {
|
|
146
|
+
if (!rb_obj_is_kind_of(rb_other, rb_cSFTime)) {
|
|
147
|
+
return Qfalse;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return BOOL2RB(sfTime_asMicroseconds(((Time *) Get_Time_Struct(self))->time) ==
|
|
151
|
+
sfTime_asMicroseconds(((Time *) Get_Time_Struct(rb_other))->time));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static VALUE Time_to_s(VALUE self) {
|
|
155
|
+
char buffer[64];
|
|
156
|
+
|
|
157
|
+
snprintf(buffer, sizeof(buffer), "%g s", sfTime_asSeconds(((Time *) Get_Time_Struct(self))->time));
|
|
158
|
+
|
|
159
|
+
return rb_str_new2(buffer);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void Init_Time(VALUE rb_module) {
|
|
163
|
+
rb_cSFTime = rb_define_class_under(rb_module, "Time", rb_cObject);
|
|
164
|
+
|
|
165
|
+
rb_include_module(rb_cSFTime, rb_mComparable);
|
|
166
|
+
|
|
167
|
+
rb_define_singleton_method(rb_cSFTime, "new", Time_new, -1);
|
|
168
|
+
rb_define_singleton_method(rb_cSFTime, "seconds", Time_seconds, 1);
|
|
169
|
+
rb_define_singleton_method(rb_cSFTime, "milliseconds", Time_milliseconds, 1);
|
|
170
|
+
rb_define_singleton_method(rb_cSFTime, "microseconds", Time_microseconds, 1);
|
|
171
|
+
rb_define_singleton_method(rb_cSFTime, "zero", Time_zero, 0);
|
|
172
|
+
|
|
173
|
+
rb_define_method(rb_cSFTime, "as_seconds", Time_as_seconds, 0);
|
|
174
|
+
rb_define_method(rb_cSFTime, "as_milliseconds", Time_as_milliseconds, 0);
|
|
175
|
+
rb_define_method(rb_cSFTime, "as_microseconds", Time_as_microseconds, 0);
|
|
176
|
+
rb_define_method(rb_cSFTime, "to_f", Time_to_f, 0);
|
|
177
|
+
rb_define_method(rb_cSFTime, "to_i", Time_to_i, 0);
|
|
178
|
+
|
|
179
|
+
rb_define_method(rb_cSFTime, "+", Time_add, 1);
|
|
180
|
+
rb_define_method(rb_cSFTime, "-", Time_sub, 1);
|
|
181
|
+
rb_define_method(rb_cSFTime, "*", Time_mul, 1);
|
|
182
|
+
rb_define_method(rb_cSFTime, "/", Time_div, 1);
|
|
183
|
+
rb_define_method(rb_cSFTime, "<=>", Time_cmp, 1);
|
|
184
|
+
rb_define_method(rb_cSFTime, "==", Time_eql, 1);
|
|
185
|
+
rb_define_method(rb_cSFTime, "to_s", Time_to_s, 0);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
VALUE Get_Klass_Time(void) {
|
|
189
|
+
return rb_cSFTime;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void *Get_Time_Struct(VALUE self) {
|
|
193
|
+
Time *ptr;
|
|
194
|
+
TypedData_Get_Struct(self, Time, &Time_data_type, ptr);
|
|
195
|
+
return ptr;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
sfTime time_from_rb(VALUE rb_time) {
|
|
199
|
+
if (rb_obj_is_kind_of(rb_time, rb_cSFTime)) {
|
|
200
|
+
return ((Time *) Get_Time_Struct(rb_time))->time;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (RB_INTEGER_TYPE_P(rb_time)) {
|
|
204
|
+
return sfMicroseconds((int64_t) NUM2LL(rb_time));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (RB_FLOAT_TYPE_P(rb_time) || RB_TYPE_P(rb_time, T_RATIONAL)) {
|
|
208
|
+
return sfSeconds((float) NUM2DBL(rb_time));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
raise_invalid_argument_class(rb_cSFTime);
|
|
212
|
+
|
|
213
|
+
return sfTime_Zero;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
VALUE time_to_rb(sfTime c_time) {
|
|
217
|
+
return Time_wrap(c_time);
|
|
218
|
+
}
|
data/ext/system/time.h
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#ifndef SFML_RB_SYSTEM_TIME_H
|
|
2
|
+
#define SFML_RB_SYSTEM_TIME_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_Time(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_Time(void);
|
|
11
|
+
|
|
12
|
+
void *Get_Time_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
sfTime time_from_rb(VALUE rb_time);
|
|
15
|
+
|
|
16
|
+
VALUE time_to_rb(sfTime c_time);
|
|
17
|
+
|
|
18
|
+
#endif //SFML_RB_SYSTEM_TIME_H
|