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.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -0
  3. data/CHANGELOG.md +67 -16
  4. data/README.md +123 -32
  5. data/TODO.md +18 -11
  6. data/ext/audio/audio_enums.c +58 -20
  7. data/ext/audio/listener.c +89 -6
  8. data/ext/audio/music.c +212 -5
  9. data/ext/audio/sound.c +218 -9
  10. data/ext/audio/sound_buffer.c +197 -47
  11. data/ext/audio/sound_buffer_recorder.c +90 -18
  12. data/ext/audio/sound_recorder.c +188 -58
  13. data/ext/audio/sound_source_cone.c +127 -33
  14. data/ext/audio/sound_stream.c +204 -21
  15. data/ext/core/exceptions.c +10 -8
  16. data/ext/core/unicode.c +12 -2
  17. data/ext/ext.c +8 -0
  18. data/ext/graphics/blend_mode.c +218 -60
  19. data/ext/graphics/circle.c +300 -16
  20. data/ext/graphics/color.c +253 -94
  21. data/ext/graphics/drawable.c +16 -4
  22. data/ext/graphics/font.c +144 -25
  23. data/ext/graphics/glyph.c +38 -8
  24. data/ext/graphics/image.c +205 -41
  25. data/ext/graphics/polygon.c +317 -30
  26. data/ext/graphics/rect.c +225 -60
  27. data/ext/graphics/rectangle.c +307 -35
  28. data/ext/graphics/render_state.c +124 -12
  29. data/ext/graphics/render_texture.c +191 -14
  30. data/ext/graphics/render_window.c +55 -0
  31. data/ext/graphics/render_window.h +10 -0
  32. data/ext/graphics/shader.c +289 -17
  33. data/ext/graphics/shape.c +265 -32
  34. data/ext/graphics/sprite.c +245 -30
  35. data/ext/graphics/stencil_mode.c +163 -46
  36. data/ext/graphics/target.c +121 -43
  37. data/ext/graphics/target.h +31 -17
  38. data/ext/graphics/text.c +339 -19
  39. data/ext/graphics/texture.c +291 -6
  40. data/ext/graphics/transform.c +178 -5
  41. data/ext/graphics/transformable.c +127 -12
  42. data/ext/graphics/vertex.c +98 -6
  43. data/ext/graphics/vertex_array.c +142 -21
  44. data/ext/graphics/vertex_buffer.c +154 -12
  45. data/ext/graphics/view.c +140 -6
  46. data/ext/network/ftp.c +278 -12
  47. data/ext/network/http.c +179 -44
  48. data/ext/network/ip_address.c +127 -35
  49. data/ext/network/network_enums.c +248 -141
  50. data/ext/network/packet.c +280 -41
  51. data/ext/network/socket_selector.c +98 -21
  52. data/ext/network/tcp_listener.c +82 -18
  53. data/ext/network/tcp_socket.c +135 -27
  54. data/ext/network/udp_socket.c +129 -28
  55. data/ext/ports.rb +7 -0
  56. data/ext/system/buffer.c +47 -16
  57. data/ext/system/clock.c +77 -12
  58. data/ext/system/input_stream.c +113 -51
  59. data/ext/system/sleep.c +10 -2
  60. data/ext/system/time.c +182 -40
  61. data/ext/system/vec2.c +166 -39
  62. data/ext/system/vec3.c +177 -39
  63. data/ext/window/clipboard.c +47 -17
  64. data/ext/window/context.c +66 -13
  65. data/ext/window/context_settings.c +132 -42
  66. data/ext/window/cursor.c +45 -9
  67. data/ext/window/event.c +164 -53
  68. data/ext/window/joystick.c +69 -3
  69. data/ext/window/keyboard.c +168 -116
  70. data/ext/window/mouse.c +64 -13
  71. data/ext/window/sensor.c +28 -2
  72. data/ext/window/touch.c +32 -12
  73. data/ext/window/video_mode.c +93 -31
  74. data/ext/window/vulkan.c +34 -6
  75. data/ext/window/window.c +228 -229
  76. data/ext/window/window.h +4 -4
  77. data/ext/window/window_base.c +251 -0
  78. data/ext/window/window_base.h +43 -0
  79. data/ext/window/window_base.inc +236 -0
  80. data/lib/sfml/version.rb +1 -1
  81. data/sig/audio/audio_enums.rbs +30 -0
  82. data/sig/audio/listener.rbs +16 -0
  83. data/sig/audio/music.rbs +56 -0
  84. data/sig/audio/sound.rbs +51 -0
  85. data/sig/audio/sound_buffer.rbs +17 -0
  86. data/sig/audio/sound_buffer_recorder.rbs +14 -0
  87. data/sig/audio/sound_recorder.rbs +17 -0
  88. data/sig/audio/sound_source_cone.rbs +14 -0
  89. data/sig/audio/sound_stream.rbs +51 -0
  90. data/sig/graphics/blend_mode.rbs +29 -0
  91. data/sig/graphics/circle.rbs +44 -0
  92. data/sig/graphics/color.rbs +39 -0
  93. data/sig/graphics/drawable.rbs +5 -0
  94. data/sig/graphics/font.rbs +20 -0
  95. data/sig/graphics/glyph.rbs +7 -0
  96. data/sig/graphics/image.rbs +22 -0
  97. data/sig/graphics/polygon.rbs +42 -0
  98. data/sig/graphics/rect.rbs +33 -0
  99. data/sig/graphics/rectangle.rbs +42 -0
  100. data/sig/graphics/render_state.rbs +21 -0
  101. data/sig/graphics/render_target.rbs +18 -0
  102. data/sig/graphics/render_texture.rbs +39 -0
  103. data/sig/graphics/render_window.rbs +7 -0
  104. data/sig/graphics/shader.rbs +39 -0
  105. data/sig/graphics/shape.rbs +38 -0
  106. data/sig/graphics/sprite.rbs +34 -0
  107. data/sig/graphics/stencil_mode.rbs +18 -0
  108. data/sig/graphics/target.rbs +8 -0
  109. data/sig/graphics/text.rbs +48 -0
  110. data/sig/graphics/texture.rbs +34 -0
  111. data/sig/graphics/transform.rbs +37 -0
  112. data/sig/graphics/transformable.rbs +25 -0
  113. data/sig/graphics/vertex.rbs +17 -0
  114. data/sig/graphics/vertex_array.rbs +17 -0
  115. data/sig/graphics/vertex_buffer.rbs +22 -0
  116. data/sig/graphics/view.rbs +23 -0
  117. data/sig/network/ftp.rbs +46 -0
  118. data/sig/network/http.rbs +27 -0
  119. data/sig/network/ip_address.rbs +22 -0
  120. data/sig/network/network_enums.rbs +95 -0
  121. data/sig/network/packet.rbs +40 -0
  122. data/sig/network/socket_selector.rbs +14 -0
  123. data/sig/network/tcp_listener.rbs +13 -0
  124. data/sig/network/tcp_socket.rbs +18 -0
  125. data/sig/network/udp_socket.rbs +17 -0
  126. data/sig/sfml/version.rbs +3 -0
  127. data/sig/system/buffer.rbs +11 -0
  128. data/sig/system/clock.rbs +13 -0
  129. data/sig/system/input_stream.rbs +7 -0
  130. data/sig/system/sleep.rbs +3 -0
  131. data/sig/system/time.rbs +28 -0
  132. data/sig/system/vec2.rbs +26 -0
  133. data/sig/system/vec3.rbs +27 -0
  134. data/sig/window/clipboard.rbs +8 -0
  135. data/sig/window/context.rbs +11 -0
  136. data/sig/window/context_settings.rbs +20 -0
  137. data/sig/window/cursor.rbs +6 -0
  138. data/sig/window/event.rbs +20 -0
  139. data/sig/window/joystick.rbs +15 -0
  140. data/sig/window/keyboard.rbs +10 -0
  141. data/sig/window/mouse.rbs +9 -0
  142. data/sig/window/sensor.rbs +8 -0
  143. data/sig/window/touch.rbs +6 -0
  144. data/sig/window/video_mode.rbs +16 -0
  145. data/sig/window/vulkan.rbs +7 -0
  146. data/sig/window/window.rbs +34 -0
  147. data/sig/window/window_base.rbs +33 -0
  148. metadata +76 -3
data/ext/system/vec2.c CHANGED
@@ -13,19 +13,43 @@ typedef struct {
13
13
 
14
14
  static VALUE rb_cVector2;
15
15
 
16
- static void Vector2_free(void *ptr) {
16
+ static void Vector2_free(void* ptr) {
17
17
  free(ptr);
18
18
  }
19
19
 
20
20
  static const rb_data_type_t Vector2_data_type = {
21
21
  .wrap_struct_name = "SFML::Vector2",
22
22
  .function = {.dmark = NULL, .dfree = Vector2_free, .dsize = NULL},
23
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
24
- };
23
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
25
24
 
26
- static VALUE Vector2_new(int argc, VALUE *argv, VALUE klass) {
27
- VALUE self;
28
- Vector2 *ptr;
25
+ static VALUE Vector2_alloc(VALUE klass) {
26
+ Vector2* ptr = malloc(sizeof(Vector2));
27
+
28
+ if (ptr == NULL) {
29
+ rb_raise(rb_eNoMemError, "failed to allocate vector");
30
+ }
31
+
32
+ ptr->vec.x = 0;
33
+ ptr->vec.y = 0;
34
+
35
+ return TypedData_Wrap_Struct(klass, &Vector2_data_type, ptr);
36
+ }
37
+
38
+ /* call-seq:
39
+ * Vector2.new -> Vector2(0, 0)
40
+ * Vector2.new(x, y) -> Vector2(x, y)
41
+ * Vector2.new([x, y]) -> Vector2(x, y)
42
+ * Vector2.new(other_vector2) -> copy of +other_vector2+
43
+ *
44
+ * Creates a new 2D vector from two coordinates, a 2-element Array, or
45
+ * another Vector2.
46
+ *
47
+ * @return [Vector2]
48
+ * @raise [ArgumentError] if given an Array shorter than 2 elements, or an
49
+ * argument count other than 0, 1 or 2
50
+ */
51
+ static VALUE Vector2_initialize(int argc, VALUE* argv, VALUE self) {
52
+ Vector2* ptr;
29
53
  float x = 0;
30
54
  float y = 0;
31
55
 
@@ -47,41 +71,77 @@ static VALUE Vector2_new(int argc, VALUE *argv, VALUE klass) {
47
71
  raise_invalid_arguments_excepted(2, argc);
48
72
  }
49
73
 
50
- ptr = malloc(sizeof(Vector2));
74
+ ptr = Get_Vector2_Struct(self);
51
75
  ptr->vec.x = x;
52
76
  ptr->vec.y = y;
53
77
 
54
- self = TypedData_Wrap_Struct(klass, &Vector2_data_type, ptr);
55
-
56
78
  return self;
57
79
  }
58
80
 
81
+ /* call-seq: x -> Float
82
+ *
83
+ * Returns the X component of the vector.
84
+ *
85
+ * @return [Float] the X component
86
+ */
59
87
  static VALUE Vector2_get_x(VALUE self) {
60
- return DBL2NUM(((Vector2 *) Get_Vector2_Struct(self))->vec.x);
88
+ return DBL2NUM(((Vector2*)Get_Vector2_Struct(self))->vec.x);
61
89
  }
62
90
 
91
+ /* call-seq: y -> Float
92
+ *
93
+ * Returns the Y component of the vector.
94
+ *
95
+ * @return [Float] the Y component
96
+ */
63
97
  static VALUE Vector2_get_y(VALUE self) {
64
- return DBL2NUM(((Vector2 *) Get_Vector2_Struct(self))->vec.y);
98
+ return DBL2NUM(((Vector2*)Get_Vector2_Struct(self))->vec.y);
65
99
  }
66
100
 
101
+ /* call-seq:
102
+ * x=(value) -> Float
103
+ *
104
+ * Sets the X component. +value+ is any Float-convertible number.
105
+ *
106
+ * @return [Float] +value+
107
+ */
67
108
  static VALUE Vector2_set_x(VALUE self, VALUE rb_x) {
68
- ((Vector2 *) Get_Vector2_Struct(self))->vec.x = NUM2DBL(rb_x);
109
+ ((Vector2*)Get_Vector2_Struct(self))->vec.x = NUM2DBL(rb_x);
69
110
  return rb_x;
70
111
  }
71
112
 
113
+ /* call-seq:
114
+ * y=(value) -> Float
115
+ *
116
+ * Sets the Y component. +value+ is any Float-convertible number.
117
+ *
118
+ * @return [Float] +value+
119
+ */
72
120
  static VALUE Vector2_set_y(VALUE self, VALUE rb_y) {
73
- ((Vector2 *) Get_Vector2_Struct(self))->vec.y = NUM2DBL(rb_y);
121
+ ((Vector2*)Get_Vector2_Struct(self))->vec.y = NUM2DBL(rb_y);
74
122
  return rb_y;
75
123
  }
76
124
 
125
+ /* call-seq: to_a -> [Float, Float]
126
+ *
127
+ * Returns the vector's components as a two-element Array.
128
+ *
129
+ * @return [Array<Float>] +[x, y]+
130
+ */
77
131
  static VALUE Vector2_to_a(VALUE self) {
78
- Vector2 *vec = Get_Vector2_Struct(self);
132
+ Vector2* vec = Get_Vector2_Struct(self);
79
133
 
80
134
  return rb_ary_new_from_args(2, DBL2NUM(vec->vec.x), DBL2NUM(vec->vec.y));
81
135
  }
82
136
 
137
+ /* call-seq: each { |component| ... } -> self
138
+ *
139
+ * Yields +x+ then +y+.
140
+ *
141
+ * @return [self]
142
+ */
83
143
  static VALUE Vector2_each(VALUE self) {
84
- Vector2 *vec = Get_Vector2_Struct(self);
144
+ Vector2* vec = Get_Vector2_Struct(self);
85
145
 
86
146
  rb_yield(DBL2NUM(vec->vec.x));
87
147
  rb_yield(DBL2NUM(vec->vec.y));
@@ -89,20 +149,40 @@ static VALUE Vector2_each(VALUE self) {
89
149
  return self;
90
150
  }
91
151
 
152
+ /* call-seq:
153
+ * [](index) -> Float
154
+ *
155
+ * Returns the component stored at +index+.
156
+ *
157
+ * @return [Float] +x+ for index 0, +y+ for index 1
158
+ */
92
159
  static VALUE Vector2_aref(VALUE self, VALUE rb_index) {
93
160
  return rb_ary_entry(Vector2_to_a(self), NUM2LONG(rb_index));
94
161
  }
95
162
 
163
+ /* call-seq: size -> Integer
164
+ *
165
+ * Returns the number of components, always 2.
166
+ *
167
+ * @return [Integer] always 2
168
+ */
96
169
  static VALUE Vector2_size(VALUE self) {
97
170
  return INT2NUM(2);
98
171
  }
99
172
 
173
+ /* call-seq:
174
+ * self == other -> true or false
175
+ *
176
+ * +other+ may be a Vector2 or a 2-element Array.
177
+ *
178
+ * @return [Boolean]
179
+ */
100
180
  static VALUE Vector2_eql(VALUE self, VALUE rb_other) {
101
- Vector2 *a = Get_Vector2_Struct(self);
181
+ Vector2* a = Get_Vector2_Struct(self);
102
182
  sfVector2f b;
103
183
 
104
184
  if (rb_obj_is_kind_of(rb_other, rb_cVector2)) {
105
- b = ((Vector2 *) Get_Vector2_Struct(rb_other))->vec;
185
+ b = ((Vector2*)Get_Vector2_Struct(rb_other))->vec;
106
186
  } else if (RB_TYPE_P(rb_other, T_ARRAY) && RARRAY_LEN(rb_other) >= 2) {
107
187
  b = vec2f_from_rb(rb_other);
108
188
  } else {
@@ -112,29 +192,56 @@ static VALUE Vector2_eql(VALUE self, VALUE rb_other) {
112
192
  return BOOL2RB(a->vec.x == b.x && a->vec.y == b.y);
113
193
  }
114
194
 
195
+ /* call-seq:
196
+ * self + other -> Vector2
197
+ *
198
+ * +other+ may be a Vector2 or a 2-element Array.
199
+ *
200
+ * @return [Vector2] componentwise sum
201
+ */
115
202
  static VALUE Vector2_add(VALUE self, VALUE rb_other) {
116
- Vector2 *a = Get_Vector2_Struct(self);
203
+ Vector2* a = Get_Vector2_Struct(self);
117
204
  sfVector2f b = vec2f_from_rb(rb_other);
118
205
 
119
- return vec2f_to_rb((sfVector2f) {a->vec.x + b.x, a->vec.y + b.y});
206
+ return vec2f_to_rb((sfVector2f){a->vec.x + b.x, a->vec.y + b.y});
120
207
  }
121
208
 
209
+ /* call-seq:
210
+ * self - other -> Vector2
211
+ *
212
+ * +other+ may be a Vector2 or a 2-element Array.
213
+ *
214
+ * @return [Vector2] componentwise difference
215
+ */
122
216
  static VALUE Vector2_sub(VALUE self, VALUE rb_other) {
123
- Vector2 *a = Get_Vector2_Struct(self);
217
+ Vector2* a = Get_Vector2_Struct(self);
124
218
  sfVector2f b = vec2f_from_rb(rb_other);
125
219
 
126
- return vec2f_to_rb((sfVector2f) {a->vec.x - b.x, a->vec.y - b.y});
220
+ return vec2f_to_rb((sfVector2f){a->vec.x - b.x, a->vec.y - b.y});
127
221
  }
128
222
 
223
+ /* call-seq:
224
+ * self * scalar -> Vector2
225
+ *
226
+ * Multiplies both components by +scalar+.
227
+ *
228
+ * @return [Vector2]
229
+ */
129
230
  static VALUE Vector2_mul(VALUE self, VALUE rb_scalar) {
130
- Vector2 *a = Get_Vector2_Struct(self);
231
+ Vector2* a = Get_Vector2_Struct(self);
131
232
  float scalar = NUM2DBL(rb_scalar);
132
233
 
133
- return vec2f_to_rb((sfVector2f) {a->vec.x * scalar, a->vec.y * scalar});
234
+ return vec2f_to_rb((sfVector2f){a->vec.x * scalar, a->vec.y * scalar});
134
235
  }
135
236
 
237
+ /* call-seq: to_s -> String
238
+ *
239
+ * Returns a human-readable +"(x, y)"+ representation.
240
+ *
241
+ * @return [String] +"(x, y)"+
242
+ */
136
243
  static VALUE Vector2_to_s(VALUE self) {
137
- Vector2 *a = Get_Vector2_Struct(self);
244
+ Vector2* a = Get_Vector2_Struct(self);
138
245
  char buffer[64];
139
246
 
140
247
  snprintf(buffer, sizeof(buffer), "(%g, %g)", a->vec.x, a->vec.y);
@@ -142,12 +249,30 @@ static VALUE Vector2_to_s(VALUE self) {
142
249
  return rb_str_new2(buffer);
143
250
  }
144
251
 
145
- void Init_Vector2(VALUE rb_module) {
146
- rb_cVector2 = rb_define_class_under(rb_module, "Vector2", rb_cObject);
252
+ /* Document-class: SFML::Vector2
253
+ * A 2D vector of floats, used throughout the library for positions, sizes,
254
+ * scale factors and directions.
255
+ *
256
+ * Includes +Enumerable+ and behaves like a 2-element sequence: it responds to
257
+ * #each, #to_a and #[], and can be compared or combined with a plain
258
+ * +[x, y]+ Array anywhere a Vector2 is accepted.
259
+ *
260
+ * @!attribute x
261
+ * Returns the X component.
262
+ *
263
+ * @return [Float] the X component
264
+ * @!attribute y
265
+ * Returns the Y component.
266
+ *
267
+ * @return [Float] the Y component
268
+ */
269
+ void Init_Vector2(VALUE rb_mSFML) {
270
+ rb_cVector2 = rb_define_class_under(rb_mSFML, "Vector2", rb_cObject);
147
271
 
148
272
  rb_include_module(rb_cVector2, rb_mEnumerable);
149
273
 
150
- rb_define_singleton_method(rb_cVector2, "new", Vector2_new, -1);
274
+ rb_define_alloc_func(rb_cVector2, Vector2_alloc);
275
+ rb_define_method(rb_cVector2, "initialize", Vector2_initialize, -1);
151
276
 
152
277
  rb_define_method(rb_cVector2, "x", Vector2_get_x, 0);
153
278
  rb_define_method(rb_cVector2, "y", Vector2_get_y, 0);
@@ -171,15 +296,15 @@ VALUE Get_Klass_Vector2(void) {
171
296
  return rb_cVector2;
172
297
  }
173
298
 
174
- void *Get_Vector2_Struct(VALUE self) {
175
- Vector2 *ptr;
299
+ void* Get_Vector2_Struct(VALUE self) {
300
+ Vector2* ptr;
176
301
  TypedData_Get_Struct(self, Vector2, &Vector2_data_type, ptr);
177
302
  return ptr;
178
303
  }
179
304
 
180
305
  sfVector2f vec2f_from_rb(VALUE rb_vec) {
181
306
  if (rb_obj_is_kind_of(rb_vec, rb_cVector2)) {
182
- return ((Vector2 *) Get_Vector2_Struct(rb_vec))->vec;
307
+ return ((Vector2*)Get_Vector2_Struct(rb_vec))->vec;
183
308
  }
184
309
 
185
310
  if (RB_TYPE_P(rb_vec, T_ARRAY)) {
@@ -187,31 +312,33 @@ sfVector2f vec2f_from_rb(VALUE rb_vec) {
187
312
  raise_invalid_array_length(2);
188
313
  }
189
314
 
190
- return (sfVector2f) {
191
- (float) NUM2DBL(rb_ary_entry(rb_vec, 0)),
192
- (float) NUM2DBL(rb_ary_entry(rb_vec, 1))
193
- };
315
+ return (sfVector2f){(float)NUM2DBL(rb_ary_entry(rb_vec, 0)),
316
+ (float)NUM2DBL(rb_ary_entry(rb_vec, 1))};
194
317
  }
195
318
 
196
319
  raise_invalid_argument_class(rb_cVector2);
197
320
 
198
- return (sfVector2f) {0, 0};
321
+ return (sfVector2f){0, 0};
199
322
  }
200
323
 
201
324
  sfVector2i vec2i_from_rb(VALUE rb_vec) {
202
325
  sfVector2f vec = vec2f_from_rb(rb_vec);
203
326
 
204
- return (sfVector2i) {(int) vec.x, (int) vec.y};
327
+ return (sfVector2i){(int)vec.x, (int)vec.y};
205
328
  }
206
329
 
207
330
  sfVector2u vec2u_from_rb(VALUE rb_vec) {
208
331
  sfVector2f vec = vec2f_from_rb(rb_vec);
209
332
 
210
- return (sfVector2u) {(unsigned) vec.x, (unsigned) vec.y};
333
+ return (sfVector2u){(unsigned)vec.x, (unsigned)vec.y};
211
334
  }
212
335
 
213
336
  VALUE vec2f_to_rb(sfVector2f c_vec) {
214
- Vector2 *ptr = malloc(sizeof(Vector2));
337
+ Vector2* ptr = malloc(sizeof(Vector2));
338
+
339
+ if (ptr == NULL) {
340
+ rb_raise(rb_eNoMemError, "failed to allocate vector");
341
+ }
215
342
 
216
343
  ptr->vec = c_vec;
217
344
 
@@ -219,7 +346,7 @@ VALUE vec2f_to_rb(sfVector2f c_vec) {
219
346
  }
220
347
 
221
348
  VALUE vec2_new(float x, float y) {
222
- return vec2f_to_rb((sfVector2f) {x, y});
349
+ return vec2f_to_rb((sfVector2f){x, y});
223
350
  }
224
351
 
225
352
  void vec2_check(VALUE rb_arr) {
data/ext/system/vec3.c CHANGED
@@ -12,19 +12,44 @@ typedef struct {
12
12
 
13
13
  static VALUE rb_cVector3;
14
14
 
15
- static void Vector3_free(void *ptr) {
15
+ static void Vector3_free(void* ptr) {
16
16
  free(ptr);
17
17
  }
18
18
 
19
19
  static const rb_data_type_t Vector3_data_type = {
20
20
  .wrap_struct_name = "SFML::Vector3",
21
21
  .function = {.dmark = NULL, .dfree = Vector3_free, .dsize = NULL},
22
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
23
- };
22
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
24
23
 
25
- static VALUE Vector3_new(int argc, VALUE *argv, VALUE klass) {
26
- VALUE self;
27
- Vector3 *ptr;
24
+ static VALUE Vector3_alloc(VALUE klass) {
25
+ Vector3* ptr = malloc(sizeof(Vector3));
26
+
27
+ if (ptr == NULL) {
28
+ rb_raise(rb_eNoMemError, "failed to allocate vector");
29
+ }
30
+
31
+ ptr->vec.x = 0;
32
+ ptr->vec.y = 0;
33
+ ptr->vec.z = 0;
34
+
35
+ return TypedData_Wrap_Struct(klass, &Vector3_data_type, ptr);
36
+ }
37
+
38
+ /* call-seq:
39
+ * Vector3.new -> Vector3(0, 0, 0)
40
+ * Vector3.new(x, y, z) -> Vector3(x, y, z)
41
+ * Vector3.new([x, y, z]) -> Vector3(x, y, z)
42
+ * Vector3.new(other_vector3) -> copy of +other_vector3+
43
+ *
44
+ * Creates a new 3D vector from three coordinates, a 3-element Array, or
45
+ * another Vector3.
46
+ *
47
+ * @return [Vector3]
48
+ * @raise [ArgumentError] if given an Array shorter than 3 elements, or an
49
+ * argument count other than 0, 1 or 3
50
+ */
51
+ static VALUE Vector3_initialize(int argc, VALUE* argv, VALUE self) {
52
+ Vector3* ptr;
28
53
  float x = 0;
29
54
  float y = 0;
30
55
  float z = 0;
@@ -50,51 +75,100 @@ static VALUE Vector3_new(int argc, VALUE *argv, VALUE klass) {
50
75
  raise_invalid_arguments_excepted(3, argc);
51
76
  }
52
77
 
53
- ptr = malloc(sizeof(Vector3));
78
+ ptr = Get_Vector3_Struct(self);
54
79
  ptr->vec.x = x;
55
80
  ptr->vec.y = y;
56
81
  ptr->vec.z = z;
57
82
 
58
- self = TypedData_Wrap_Struct(klass, &Vector3_data_type, ptr);
59
-
60
83
  return self;
61
84
  }
62
85
 
86
+ /* call-seq: x -> Float
87
+ *
88
+ * Returns the X component of the vector.
89
+ *
90
+ * @return [Float] the X component
91
+ */
63
92
  static VALUE Vector3_get_x(VALUE self) {
64
- return DBL2NUM(((Vector3 *) Get_Vector3_Struct(self))->vec.x);
93
+ return DBL2NUM(((Vector3*)Get_Vector3_Struct(self))->vec.x);
65
94
  }
66
95
 
96
+ /* call-seq: y -> Float
97
+ *
98
+ * Returns the Y component of the vector.
99
+ *
100
+ * @return [Float] the Y component
101
+ */
67
102
  static VALUE Vector3_get_y(VALUE self) {
68
- return DBL2NUM(((Vector3 *) Get_Vector3_Struct(self))->vec.y);
103
+ return DBL2NUM(((Vector3*)Get_Vector3_Struct(self))->vec.y);
69
104
  }
70
105
 
106
+ /* call-seq: z -> Float
107
+ *
108
+ * Returns the Z component of the vector.
109
+ *
110
+ * @return [Float] the Z component
111
+ */
71
112
  static VALUE Vector3_get_z(VALUE self) {
72
- return DBL2NUM(((Vector3 *) Get_Vector3_Struct(self))->vec.z);
113
+ return DBL2NUM(((Vector3*)Get_Vector3_Struct(self))->vec.z);
73
114
  }
74
115
 
116
+ /* call-seq:
117
+ * x=(value) -> Float
118
+ *
119
+ * Sets the X component. +value+ is any Float-convertible number.
120
+ *
121
+ * @return [Float] +value+
122
+ */
75
123
  static VALUE Vector3_set_x(VALUE self, VALUE rb_x) {
76
- ((Vector3 *) Get_Vector3_Struct(self))->vec.x = NUM2DBL(rb_x);
124
+ ((Vector3*)Get_Vector3_Struct(self))->vec.x = NUM2DBL(rb_x);
77
125
  return rb_x;
78
126
  }
79
127
 
128
+ /* call-seq:
129
+ * y=(value) -> Float
130
+ *
131
+ * Sets the Y component. +value+ is any Float-convertible number.
132
+ *
133
+ * @return [Float] +value+
134
+ */
80
135
  static VALUE Vector3_set_y(VALUE self, VALUE rb_y) {
81
- ((Vector3 *) Get_Vector3_Struct(self))->vec.y = NUM2DBL(rb_y);
136
+ ((Vector3*)Get_Vector3_Struct(self))->vec.y = NUM2DBL(rb_y);
82
137
  return rb_y;
83
138
  }
84
139
 
140
+ /* call-seq:
141
+ * z=(value) -> Float
142
+ *
143
+ * Sets the Z component. +value+ is any Float-convertible number.
144
+ *
145
+ * @return [Float] +value+
146
+ */
85
147
  static VALUE Vector3_set_z(VALUE self, VALUE rb_z) {
86
- ((Vector3 *) Get_Vector3_Struct(self))->vec.z = NUM2DBL(rb_z);
148
+ ((Vector3*)Get_Vector3_Struct(self))->vec.z = NUM2DBL(rb_z);
87
149
  return rb_z;
88
150
  }
89
151
 
152
+ /* call-seq: to_a -> Array
153
+ *
154
+ * Returns the vector's components as a three-element Array.
155
+ *
156
+ * @return [Array<Float>] +[x, y, z]+
157
+ */
90
158
  static VALUE Vector3_to_a(VALUE self) {
91
- Vector3 *vec = Get_Vector3_Struct(self);
159
+ Vector3* vec = Get_Vector3_Struct(self);
92
160
 
93
161
  return rb_ary_new_from_args(3, DBL2NUM(vec->vec.x), DBL2NUM(vec->vec.y), DBL2NUM(vec->vec.z));
94
162
  }
95
163
 
164
+ /* call-seq: each { |component| ... } -> self
165
+ *
166
+ * Yields +x+, +y+, then +z+.
167
+ *
168
+ * @return [self]
169
+ */
96
170
  static VALUE Vector3_each(VALUE self) {
97
- Vector3 *vec = Get_Vector3_Struct(self);
171
+ Vector3* vec = Get_Vector3_Struct(self);
98
172
 
99
173
  rb_yield(DBL2NUM(vec->vec.x));
100
174
  rb_yield(DBL2NUM(vec->vec.y));
@@ -103,16 +177,29 @@ static VALUE Vector3_each(VALUE self) {
103
177
  return self;
104
178
  }
105
179
 
180
+ /* call-seq: size -> Integer
181
+ *
182
+ * Returns the number of components, always 3.
183
+ *
184
+ * @return [Integer] always 3
185
+ */
106
186
  static VALUE Vector3_size(VALUE self) {
107
187
  return INT2NUM(3);
108
188
  }
109
189
 
190
+ /* call-seq:
191
+ * self == other -> true or false
192
+ *
193
+ * +other+ may be a Vector3 or a 3-element Array.
194
+ *
195
+ * @return [Boolean]
196
+ */
110
197
  static VALUE Vector3_eql(VALUE self, VALUE rb_other) {
111
- Vector3 *a = Get_Vector3_Struct(self);
198
+ Vector3* a = Get_Vector3_Struct(self);
112
199
  sfVector3f b;
113
200
 
114
201
  if (rb_obj_is_kind_of(rb_other, rb_cVector3)) {
115
- b = ((Vector3 *) Get_Vector3_Struct(rb_other))->vec;
202
+ b = ((Vector3*)Get_Vector3_Struct(rb_other))->vec;
116
203
  } else if (RB_TYPE_P(rb_other, T_ARRAY) && RARRAY_LEN(rb_other) >= 3) {
117
204
  b = vec3f_from_rb(rb_other);
118
205
  } else {
@@ -122,29 +209,56 @@ static VALUE Vector3_eql(VALUE self, VALUE rb_other) {
122
209
  return BOOL2RB(a->vec.x == b.x && a->vec.y == b.y && a->vec.z == b.z);
123
210
  }
124
211
 
212
+ /* call-seq:
213
+ * self + other -> Vector3
214
+ *
215
+ * +other+ may be a Vector3 or a 3-element Array.
216
+ *
217
+ * @return [Vector3] componentwise sum
218
+ */
125
219
  static VALUE Vector3_add(VALUE self, VALUE rb_other) {
126
- Vector3 *a = Get_Vector3_Struct(self);
220
+ Vector3* a = Get_Vector3_Struct(self);
127
221
  sfVector3f b = vec3f_from_rb(rb_other);
128
222
 
129
- return vec3f_to_rb((sfVector3f) {a->vec.x + b.x, a->vec.y + b.y, a->vec.z + b.z});
223
+ return vec3f_to_rb((sfVector3f){a->vec.x + b.x, a->vec.y + b.y, a->vec.z + b.z});
130
224
  }
131
225
 
226
+ /* call-seq:
227
+ * self - other -> Vector3
228
+ *
229
+ * +other+ may be a Vector3 or a 3-element Array.
230
+ *
231
+ * @return [Vector3] componentwise difference
232
+ */
132
233
  static VALUE Vector3_sub(VALUE self, VALUE rb_other) {
133
- Vector3 *a = Get_Vector3_Struct(self);
234
+ Vector3* a = Get_Vector3_Struct(self);
134
235
  sfVector3f b = vec3f_from_rb(rb_other);
135
236
 
136
- return vec3f_to_rb((sfVector3f) {a->vec.x - b.x, a->vec.y - b.y, a->vec.z - b.z});
237
+ return vec3f_to_rb((sfVector3f){a->vec.x - b.x, a->vec.y - b.y, a->vec.z - b.z});
137
238
  }
138
239
 
240
+ /* call-seq:
241
+ * self * scalar -> Vector3
242
+ *
243
+ * Multiplies all three components by +scalar+.
244
+ *
245
+ * @return [Vector3]
246
+ */
139
247
  static VALUE Vector3_mul(VALUE self, VALUE rb_scalar) {
140
- Vector3 *a = Get_Vector3_Struct(self);
248
+ Vector3* a = Get_Vector3_Struct(self);
141
249
  float scalar = NUM2DBL(rb_scalar);
142
250
 
143
- return vec3f_to_rb((sfVector3f) {a->vec.x * scalar, a->vec.y * scalar, a->vec.z * scalar});
251
+ return vec3f_to_rb((sfVector3f){a->vec.x * scalar, a->vec.y * scalar, a->vec.z * scalar});
144
252
  }
145
253
 
254
+ /* call-seq: to_s -> String
255
+ *
256
+ * Returns a human-readable +"(x, y, z)"+ representation.
257
+ *
258
+ * @return [String] +"(x, y, z)"+
259
+ */
146
260
  static VALUE Vector3_to_s(VALUE self) {
147
- Vector3 *a = Get_Vector3_Struct(self);
261
+ Vector3* a = Get_Vector3_Struct(self);
148
262
  char buffer[96];
149
263
 
150
264
  snprintf(buffer, sizeof(buffer), "(%g, %g, %g)", a->vec.x, a->vec.y, a->vec.z);
@@ -152,12 +266,34 @@ static VALUE Vector3_to_s(VALUE self) {
152
266
  return rb_str_new2(buffer);
153
267
  }
154
268
 
155
- void Init_Vector3(VALUE rb_module) {
156
- rb_cVector3 = rb_define_class_under(rb_module, "Vector3", rb_cObject);
269
+ /* Document-class: SFML::Vector3
270
+ * A 3D vector of floats, used for positions, sizes and directions in 3D
271
+ * space (e.g. Listener and SoundSource position/direction/velocity).
272
+ *
273
+ * Includes +Enumerable+ and behaves like a 3-element sequence: it responds to
274
+ * #each and #to_a, and can be compared or combined with a plain
275
+ * +[x, y, z]+ Array anywhere a Vector3 is accepted.
276
+ *
277
+ * @!attribute x
278
+ * Returns the X component.
279
+ *
280
+ * @return [Float] the X component
281
+ * @!attribute y
282
+ * Returns the Y component.
283
+ *
284
+ * @return [Float] the Y component
285
+ * @!attribute z
286
+ * Returns the Z component.
287
+ *
288
+ * @return [Float] the Z component
289
+ */
290
+ void Init_Vector3(VALUE rb_mSFML) {
291
+ rb_cVector3 = rb_define_class_under(rb_mSFML, "Vector3", rb_cObject);
157
292
 
158
293
  rb_include_module(rb_cVector3, rb_mEnumerable);
159
294
 
160
- rb_define_singleton_method(rb_cVector3, "new", Vector3_new, -1);
295
+ rb_define_alloc_func(rb_cVector3, Vector3_alloc);
296
+ rb_define_method(rb_cVector3, "initialize", Vector3_initialize, -1);
161
297
 
162
298
  rb_define_method(rb_cVector3, "x", Vector3_get_x, 0);
163
299
  rb_define_method(rb_cVector3, "y", Vector3_get_y, 0);
@@ -182,15 +318,15 @@ VALUE Get_Klass_Vector3(void) {
182
318
  return rb_cVector3;
183
319
  }
184
320
 
185
- void *Get_Vector3_Struct(VALUE self) {
186
- Vector3 *ptr;
321
+ void* Get_Vector3_Struct(VALUE self) {
322
+ Vector3* ptr;
187
323
  TypedData_Get_Struct(self, Vector3, &Vector3_data_type, ptr);
188
324
  return ptr;
189
325
  }
190
326
 
191
327
  sfVector3f vec3f_from_rb(VALUE rb_vec) {
192
328
  if (rb_obj_is_kind_of(rb_vec, rb_cVector3)) {
193
- return ((Vector3 *) Get_Vector3_Struct(rb_vec))->vec;
329
+ return ((Vector3*)Get_Vector3_Struct(rb_vec))->vec;
194
330
  }
195
331
 
196
332
  if (RB_TYPE_P(rb_vec, T_ARRAY)) {
@@ -198,20 +334,22 @@ sfVector3f vec3f_from_rb(VALUE rb_vec) {
198
334
  raise_invalid_array_length(3);
199
335
  }
200
336
 
201
- return (sfVector3f) {
202
- (float) NUM2DBL(rb_ary_entry(rb_vec, 0)),
203
- (float) NUM2DBL(rb_ary_entry(rb_vec, 1)),
204
- (float) NUM2DBL(rb_ary_entry(rb_vec, 2))
205
- };
337
+ return (sfVector3f){(float)NUM2DBL(rb_ary_entry(rb_vec, 0)),
338
+ (float)NUM2DBL(rb_ary_entry(rb_vec, 1)),
339
+ (float)NUM2DBL(rb_ary_entry(rb_vec, 2))};
206
340
  }
207
341
 
208
342
  raise_invalid_argument_class(rb_cVector3);
209
343
 
210
- return (sfVector3f) {0, 0, 0};
344
+ return (sfVector3f){0, 0, 0};
211
345
  }
212
346
 
213
347
  VALUE vec3f_to_rb(sfVector3f c_vec) {
214
- Vector3 *ptr = malloc(sizeof(Vector3));
348
+ Vector3* ptr = malloc(sizeof(Vector3));
349
+
350
+ if (ptr == NULL) {
351
+ rb_raise(rb_eNoMemError, "failed to allocate vector");
352
+ }
215
353
 
216
354
  ptr->vec = c_vec;
217
355