sfml3-rb 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -0
  3. data/CHANGELOG.md +43 -17
  4. data/README.md +97 -29
  5. data/ext/audio/audio_enums.c +58 -20
  6. data/ext/audio/listener.c +89 -6
  7. data/ext/audio/music.c +206 -5
  8. data/ext/audio/sound.c +175 -5
  9. data/ext/audio/sound_buffer.c +189 -47
  10. data/ext/audio/sound_buffer_recorder.c +83 -16
  11. data/ext/audio/sound_recorder.c +172 -52
  12. data/ext/audio/sound_source_cone.c +108 -29
  13. data/ext/audio/sound_stream.c +178 -5
  14. data/ext/core/exceptions.c +10 -8
  15. data/ext/core/unicode.c +12 -2
  16. data/ext/ext.c +4 -0
  17. data/ext/graphics/blend_mode.c +203 -53
  18. data/ext/graphics/circle.c +271 -4
  19. data/ext/graphics/color.c +240 -90
  20. data/ext/graphics/drawable.c +15 -4
  21. data/ext/graphics/font.c +138 -25
  22. data/ext/graphics/glyph.c +31 -8
  23. data/ext/graphics/image.c +180 -37
  24. data/ext/graphics/polygon.c +293 -26
  25. data/ext/graphics/rect.c +211 -54
  26. data/ext/graphics/rectangle.c +279 -26
  27. data/ext/graphics/render_state.c +116 -2
  28. data/ext/graphics/render_texture.c +163 -2
  29. data/ext/graphics/shader.c +283 -17
  30. data/ext/graphics/shape.c +252 -26
  31. data/ext/graphics/sprite.c +216 -25
  32. data/ext/graphics/stencil_mode.c +148 -39
  33. data/ext/graphics/target.c +67 -22
  34. data/ext/graphics/target.h +15 -15
  35. data/ext/graphics/text.c +306 -6
  36. data/ext/graphics/texture.c +257 -3
  37. data/ext/graphics/transform.c +178 -5
  38. data/ext/graphics/transformable.c +126 -2
  39. data/ext/graphics/vertex.c +79 -2
  40. data/ext/graphics/vertex_array.c +128 -16
  41. data/ext/graphics/vertex_buffer.c +124 -2
  42. data/ext/graphics/view.c +130 -2
  43. data/ext/network/ftp.c +249 -10
  44. data/ext/network/http.c +156 -38
  45. data/ext/network/ip_address.c +107 -26
  46. data/ext/network/network_enums.c +248 -141
  47. data/ext/network/packet.c +273 -39
  48. data/ext/network/socket_selector.c +91 -19
  49. data/ext/network/tcp_listener.c +75 -16
  50. data/ext/network/tcp_socket.c +128 -25
  51. data/ext/network/udp_socket.c +122 -26
  52. data/ext/ports.rb +7 -0
  53. data/ext/system/buffer.c +41 -12
  54. data/ext/system/clock.c +68 -9
  55. data/ext/system/input_stream.c +94 -42
  56. data/ext/system/sleep.c +10 -2
  57. data/ext/system/time.c +172 -34
  58. data/ext/system/vec2.c +156 -35
  59. data/ext/system/vec3.c +166 -35
  60. data/ext/window/clipboard.c +47 -17
  61. data/ext/window/context.c +59 -9
  62. data/ext/window/context_settings.c +116 -38
  63. data/ext/window/cursor.c +39 -9
  64. data/ext/window/event.c +163 -42
  65. data/ext/window/joystick.c +69 -3
  66. data/ext/window/keyboard.c +168 -116
  67. data/ext/window/mouse.c +36 -2
  68. data/ext/window/sensor.c +28 -2
  69. data/ext/window/touch.c +20 -2
  70. data/ext/window/video_mode.c +90 -19
  71. data/ext/window/vulkan.c +34 -6
  72. data/ext/window/window.c +340 -16
  73. data/lib/sfml/version.rb +1 -1
  74. data/sig/audio/audio_enums.rbs +30 -0
  75. data/sig/audio/listener.rbs +16 -0
  76. data/sig/audio/music.rbs +56 -0
  77. data/sig/audio/sound.rbs +51 -0
  78. data/sig/audio/sound_buffer.rbs +17 -0
  79. data/sig/audio/sound_buffer_recorder.rbs +14 -0
  80. data/sig/audio/sound_recorder.rbs +17 -0
  81. data/sig/audio/sound_source_cone.rbs +14 -0
  82. data/sig/audio/sound_stream.rbs +51 -0
  83. data/sig/graphics/blend_mode.rbs +29 -0
  84. data/sig/graphics/circle.rbs +44 -0
  85. data/sig/graphics/color.rbs +39 -0
  86. data/sig/graphics/drawable.rbs +5 -0
  87. data/sig/graphics/font.rbs +20 -0
  88. data/sig/graphics/glyph.rbs +7 -0
  89. data/sig/graphics/image.rbs +22 -0
  90. data/sig/graphics/polygon.rbs +42 -0
  91. data/sig/graphics/rect.rbs +33 -0
  92. data/sig/graphics/rectangle.rbs +42 -0
  93. data/sig/graphics/render_state.rbs +21 -0
  94. data/sig/graphics/render_texture.rbs +37 -0
  95. data/sig/graphics/shader.rbs +39 -0
  96. data/sig/graphics/shape.rbs +38 -0
  97. data/sig/graphics/sprite.rbs +34 -0
  98. data/sig/graphics/stencil_mode.rbs +18 -0
  99. data/sig/graphics/target.rbs +10 -0
  100. data/sig/graphics/text.rbs +48 -0
  101. data/sig/graphics/texture.rbs +34 -0
  102. data/sig/graphics/transform.rbs +37 -0
  103. data/sig/graphics/transformable.rbs +25 -0
  104. data/sig/graphics/vertex.rbs +17 -0
  105. data/sig/graphics/vertex_array.rbs +17 -0
  106. data/sig/graphics/vertex_buffer.rbs +22 -0
  107. data/sig/graphics/view.rbs +24 -0
  108. data/sig/network/ftp.rbs +46 -0
  109. data/sig/network/http.rbs +27 -0
  110. data/sig/network/ip_address.rbs +22 -0
  111. data/sig/network/network_enums.rbs +95 -0
  112. data/sig/network/packet.rbs +40 -0
  113. data/sig/network/socket_selector.rbs +14 -0
  114. data/sig/network/tcp_listener.rbs +13 -0
  115. data/sig/network/tcp_socket.rbs +18 -0
  116. data/sig/network/udp_socket.rbs +17 -0
  117. data/sig/system/buffer.rbs +11 -0
  118. data/sig/system/clock.rbs +13 -0
  119. data/sig/system/input_stream.rbs +7 -0
  120. data/sig/system/sleep.rbs +3 -0
  121. data/sig/system/time.rbs +28 -0
  122. data/sig/system/vec2.rbs +26 -0
  123. data/sig/system/vec3.rbs +27 -0
  124. data/sig/window/clipboard.rbs +8 -0
  125. data/sig/window/context.rbs +11 -0
  126. data/sig/window/context_settings.rbs +20 -0
  127. data/sig/window/cursor.rbs +6 -0
  128. data/sig/window/event.rbs +20 -0
  129. data/sig/window/joystick.rbs +15 -0
  130. data/sig/window/keyboard.rbs +10 -0
  131. data/sig/window/mouse.rbs +9 -0
  132. data/sig/window/sensor.rbs +8 -0
  133. data/sig/window/touch.rbs +6 -0
  134. data/sig/window/video_mode.rbs +16 -0
  135. data/sig/window/vulkan.rbs +7 -0
  136. data/sig/window/window.rbs +57 -0
  137. metadata +66 -2
data/ext/system/time.c CHANGED
@@ -12,40 +12,61 @@ typedef struct {
12
12
 
13
13
  static VALUE rb_cSFTime;
14
14
 
15
- static void Time_free(void *ptr) {
15
+ static void Time_free(void* ptr) {
16
16
  free(ptr);
17
17
  }
18
18
 
19
19
  static const rb_data_type_t Time_data_type = {
20
20
  .wrap_struct_name = "SFML::Time",
21
21
  .function = {.dmark = NULL, .dfree = Time_free, .dsize = NULL},
22
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
23
- };
22
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
24
23
 
25
24
  static VALUE Time_wrap(sfTime time) {
26
- Time *ptr = malloc(sizeof(Time));
25
+ Time* ptr = malloc(sizeof(Time));
26
+
27
+ if (ptr == NULL) {
28
+ rb_raise(rb_eNoMemError, "failed to allocate time");
29
+ }
27
30
 
28
31
  ptr->time = time;
29
32
 
30
33
  return TypedData_Wrap_Struct(rb_cSFTime, &Time_data_type, ptr);
31
34
  }
32
35
 
33
- static VALUE Time_new(int argc, VALUE *argv, VALUE klass) {
36
+ /* call-seq:
37
+ * Time.new -> Time(0)
38
+ * Time.new(seconds) -> Time
39
+ * Time.new(microseconds_integer) -> Time
40
+ * Time.new(other_time) -> copy of +other_time+
41
+ *
42
+ * A Float argument is interpreted as seconds; an Integer argument is
43
+ * interpreted as microseconds. Prefer .seconds/.milliseconds/.microseconds
44
+ * to be explicit.
45
+ *
46
+ * @return [Time]
47
+ * @raise [ArgumentError] if given more than one argument
48
+ */
49
+ static VALUE Time_new(int argc, VALUE* argv, VALUE klass) {
34
50
  VALUE self;
35
- Time *ptr;
51
+ Time* ptr;
36
52
  sfTime time = sfTime_Zero;
37
53
 
38
54
  if (argc == 1 && rb_obj_is_kind_of(argv[0], rb_cSFTime)) {
39
- time = ((Time *) Get_Time_Struct(argv[0]))->time;
55
+ time = ((Time*)Get_Time_Struct(argv[0]))->time;
40
56
  } else if (argc == 1 && RB_INTEGER_TYPE_P(argv[0])) {
41
- time = sfMicroseconds((int64_t) NUM2LL(argv[0]));
57
+ time = sfMicroseconds((int64_t)NUM2LL(argv[0]));
42
58
  } else if (argc == 1) {
43
- time = sfSeconds((float) NUM2DBL(argv[0]));
59
+ time = sfSeconds((float)NUM2DBL(argv[0]));
44
60
  } else if (argc != 0) {
45
61
  raise_invalid_arguments_excepted(1, argc);
46
62
  }
47
63
 
48
64
  ptr = malloc(sizeof(Time));
65
+
66
+ if (ptr == NULL) {
67
+ rb_raise(rb_eNoMemError, "failed to allocate time");
68
+ }
69
+
49
70
  ptr->time = time;
50
71
 
51
72
  self = TypedData_Wrap_Struct(klass, &Time_data_type, ptr);
@@ -53,80 +74,176 @@ static VALUE Time_new(int argc, VALUE *argv, VALUE klass) {
53
74
  return self;
54
75
  }
55
76
 
77
+ /* call-seq:
78
+ * Time.seconds(value) -> Time
79
+ *
80
+ * Creates a Time of +value+ seconds, where +value+ is any Float-convertible
81
+ * number.
82
+ *
83
+ * @return [Time]
84
+ */
56
85
  static VALUE Time_seconds(VALUE klass, VALUE rb_seconds) {
57
- return Time_wrap(sfSeconds((float) NUM2DBL(rb_seconds)));
86
+ return Time_wrap(sfSeconds((float)NUM2DBL(rb_seconds)));
58
87
  }
59
88
 
89
+ /* call-seq:
90
+ * Time.milliseconds(value) -> Time
91
+ *
92
+ * Creates a Time of +value+ milliseconds.
93
+ *
94
+ * @return [Time]
95
+ */
60
96
  static VALUE Time_milliseconds(VALUE klass, VALUE rb_milliseconds) {
61
- return Time_wrap(sfMilliseconds((int32_t) NUM2INT(rb_milliseconds)));
97
+ return Time_wrap(sfMilliseconds((int32_t)NUM2INT(rb_milliseconds)));
62
98
  }
63
99
 
100
+ /* call-seq:
101
+ * Time.microseconds(value) -> Time
102
+ *
103
+ * Creates a Time of +value+ microseconds.
104
+ *
105
+ * @return [Time]
106
+ */
64
107
  static VALUE Time_microseconds(VALUE klass, VALUE rb_microseconds) {
65
- return Time_wrap(sfMicroseconds((int64_t) NUM2LL(rb_microseconds)));
108
+ return Time_wrap(sfMicroseconds((int64_t)NUM2LL(rb_microseconds)));
66
109
  }
67
110
 
111
+ /* call-seq:
112
+ * Time.zero -> Time
113
+ *
114
+ * Returns the zero-duration Time.
115
+ *
116
+ * @return [Time] a zero-duration Time
117
+ */
68
118
  static VALUE Time_zero(VALUE klass) {
69
119
  return Time_wrap(sfTime_Zero);
70
120
  }
71
121
 
122
+ /* call-seq: as_seconds -> Float
123
+ *
124
+ * Returns the duration expressed in seconds.
125
+ *
126
+ * @return [Float]
127
+ */
72
128
  static VALUE Time_as_seconds(VALUE self) {
73
- return DBL2NUM(sfTime_asSeconds(((Time *) Get_Time_Struct(self))->time));
129
+ return DBL2NUM(sfTime_asSeconds(((Time*)Get_Time_Struct(self))->time));
74
130
  }
75
131
 
132
+ /* call-seq: as_milliseconds -> Integer
133
+ *
134
+ * Returns the duration expressed in whole milliseconds.
135
+ *
136
+ * @return [Integer]
137
+ */
76
138
  static VALUE Time_as_milliseconds(VALUE self) {
77
- return INT2NUM(sfTime_asMilliseconds(((Time *) Get_Time_Struct(self))->time));
139
+ return INT2NUM(sfTime_asMilliseconds(((Time*)Get_Time_Struct(self))->time));
78
140
  }
79
141
 
142
+ /* call-seq: as_microseconds -> Integer
143
+ *
144
+ * Returns the duration expressed in whole microseconds.
145
+ *
146
+ * @return [Integer]
147
+ */
80
148
  static VALUE Time_as_microseconds(VALUE self) {
81
- return LL2NUM(sfTime_asMicroseconds(((Time *) Get_Time_Struct(self))->time));
149
+ return LL2NUM(sfTime_asMicroseconds(((Time*)Get_Time_Struct(self))->time));
82
150
  }
83
151
 
152
+ /* call-seq: to_f -> Float
153
+ *
154
+ * Alias for #as_seconds.
155
+ *
156
+ * @return [Float]
157
+ */
84
158
  static VALUE Time_to_f(VALUE self) {
85
159
  return Time_as_seconds(self);
86
160
  }
87
161
 
162
+ /* call-seq: to_i -> Integer
163
+ *
164
+ * Alias for #as_microseconds.
165
+ *
166
+ * @return [Integer]
167
+ */
88
168
  static VALUE Time_to_i(VALUE self) {
89
169
  return Time_as_microseconds(self);
90
170
  }
91
171
 
172
+ /* call-seq:
173
+ * self + other -> Time
174
+ *
175
+ * Adds +other+ to the duration, returning a new Time.
176
+ *
177
+ * @return [Time]
178
+ */
92
179
  static VALUE Time_add(VALUE self, VALUE rb_other) {
93
- sfTime a = ((Time *) Get_Time_Struct(self))->time;
180
+ sfTime a = ((Time*)Get_Time_Struct(self))->time;
94
181
  sfTime b = time_from_rb(rb_other);
95
182
 
96
183
  return Time_wrap(sfMicroseconds(sfTime_asMicroseconds(a) + sfTime_asMicroseconds(b)));
97
184
  }
98
185
 
186
+ /* call-seq:
187
+ * self - other -> Time
188
+ *
189
+ * Subtracts +other+ from the duration, returning a new Time.
190
+ *
191
+ * @return [Time]
192
+ */
99
193
  static VALUE Time_sub(VALUE self, VALUE rb_other) {
100
- sfTime a = ((Time *) Get_Time_Struct(self))->time;
194
+ sfTime a = ((Time*)Get_Time_Struct(self))->time;
101
195
  sfTime b = time_from_rb(rb_other);
102
196
 
103
197
  return Time_wrap(sfMicroseconds(sfTime_asMicroseconds(a) - sfTime_asMicroseconds(b)));
104
198
  }
105
199
 
200
+ /* call-seq:
201
+ * self * scalar -> Time
202
+ *
203
+ * Scales the duration by +scalar+, returning a new Time.
204
+ *
205
+ * @return [Time]
206
+ */
106
207
  static VALUE Time_mul(VALUE self, VALUE rb_scalar) {
107
- sfTime a = ((Time *) Get_Time_Struct(self))->time;
208
+ sfTime a = ((Time*)Get_Time_Struct(self))->time;
108
209
 
109
- return Time_wrap(sfMicroseconds((int64_t) (sfTime_asMicroseconds(a) * NUM2DBL(rb_scalar))));
210
+ return Time_wrap(sfMicroseconds((int64_t)(sfTime_asMicroseconds(a) * NUM2DBL(rb_scalar))));
110
211
  }
111
212
 
213
+ /* call-seq:
214
+ * self / other -> Time or Float
215
+ *
216
+ * Dividing by a Time returns the (unitless) ratio of the two durations as a
217
+ * Float; dividing by a Number scales the duration.
218
+ *
219
+ * @return [Time, Float]
220
+ * @raise [ZeroDivError] if dividing by a zero Time
221
+ */
112
222
  static VALUE Time_div(VALUE self, VALUE rb_other) {
113
- sfTime a = ((Time *) Get_Time_Struct(self))->time;
223
+ sfTime a = ((Time*)Get_Time_Struct(self))->time;
114
224
 
115
225
  if (rb_obj_is_kind_of(rb_other, rb_cSFTime)) {
116
- int64_t b = sfTime_asMicroseconds(((Time *) Get_Time_Struct(rb_other))->time);
226
+ int64_t b = sfTime_asMicroseconds(((Time*)Get_Time_Struct(rb_other))->time);
117
227
 
118
228
  if (b == 0) {
119
229
  rb_raise(rb_eZeroDivError, "divided by 0");
120
230
  }
121
231
 
122
- return DBL2NUM((double) sfTime_asMicroseconds(a) / (double) b);
232
+ return DBL2NUM((double)sfTime_asMicroseconds(a) / (double)b);
123
233
  }
124
234
 
125
- return Time_wrap(sfMicroseconds((int64_t) (sfTime_asMicroseconds(a) / NUM2DBL(rb_other))));
235
+ return Time_wrap(sfMicroseconds((int64_t)(sfTime_asMicroseconds(a) / NUM2DBL(rb_other))));
126
236
  }
127
237
 
238
+ /* call-seq:
239
+ * self <=> other -> -1, 0 or 1
240
+ *
241
+ * Compares the duration with +other+, which may be a Time or a number.
242
+ *
243
+ * @return [Integer]
244
+ */
128
245
  static VALUE Time_cmp(VALUE self, VALUE rb_other) {
129
- sfTime a = ((Time *) Get_Time_Struct(self))->time;
246
+ sfTime a = ((Time*)Get_Time_Struct(self))->time;
130
247
  sfTime b = time_from_rb(rb_other);
131
248
  int64_t micro_a = sfTime_asMicroseconds(a);
132
249
  int64_t micro_b = sfTime_asMicroseconds(b);
@@ -142,25 +259,46 @@ static VALUE Time_cmp(VALUE self, VALUE rb_other) {
142
259
  return INT2NUM(0);
143
260
  }
144
261
 
262
+ /* call-seq:
263
+ * self == other -> true or false
264
+ *
265
+ * Returns +true+ if +other+ is a Time holding the same duration.
266
+ *
267
+ * @return [Boolean]
268
+ */
145
269
  static VALUE Time_eql(VALUE self, VALUE rb_other) {
146
270
  if (!rb_obj_is_kind_of(rb_other, rb_cSFTime)) {
147
271
  return Qfalse;
148
272
  }
149
273
 
150
- return BOOL2RB(sfTime_asMicroseconds(((Time *) Get_Time_Struct(self))->time) ==
151
- sfTime_asMicroseconds(((Time *) Get_Time_Struct(rb_other))->time));
274
+ return BOOL2RB(sfTime_asMicroseconds(((Time*)Get_Time_Struct(self))->time) ==
275
+ sfTime_asMicroseconds(((Time*)Get_Time_Struct(rb_other))->time));
152
276
  }
153
277
 
278
+ /* call-seq: to_s -> String
279
+ *
280
+ * Returns the duration formatted as a number of seconds.
281
+ *
282
+ * @return [String] +"N s"+, e.g. +"1.5 s"+
283
+ */
154
284
  static VALUE Time_to_s(VALUE self) {
155
285
  char buffer[64];
156
286
 
157
- snprintf(buffer, sizeof(buffer), "%g s", sfTime_asSeconds(((Time *) Get_Time_Struct(self))->time));
287
+ snprintf(buffer, sizeof(buffer), "%g s",
288
+ sfTime_asSeconds(((Time*)Get_Time_Struct(self))->time));
158
289
 
159
290
  return rb_str_new2(buffer);
160
291
  }
161
292
 
162
- void Init_Time(VALUE rb_module) {
163
- rb_cSFTime = rb_define_class_under(rb_module, "Time", rb_cObject);
293
+ /* Document-class: SFML::Time
294
+ * A time duration, with microsecond precision internally. Used throughout
295
+ * the library wherever a duration or timestamp is needed (Clock#elapsed_time,
296
+ * SoundSource#playing_offset, sleep, animation timers, ...).
297
+ *
298
+ * Includes +Comparable+.
299
+ */
300
+ void Init_Time(VALUE rb_mSFML) {
301
+ rb_cSFTime = rb_define_class_under(rb_mSFML, "Time", rb_cObject);
164
302
 
165
303
  rb_include_module(rb_cSFTime, rb_mComparable);
166
304
 
@@ -189,23 +327,23 @@ VALUE Get_Klass_Time(void) {
189
327
  return rb_cSFTime;
190
328
  }
191
329
 
192
- void *Get_Time_Struct(VALUE self) {
193
- Time *ptr;
330
+ void* Get_Time_Struct(VALUE self) {
331
+ Time* ptr;
194
332
  TypedData_Get_Struct(self, Time, &Time_data_type, ptr);
195
333
  return ptr;
196
334
  }
197
335
 
198
336
  sfTime time_from_rb(VALUE rb_time) {
199
337
  if (rb_obj_is_kind_of(rb_time, rb_cSFTime)) {
200
- return ((Time *) Get_Time_Struct(rb_time))->time;
338
+ return ((Time*)Get_Time_Struct(rb_time))->time;
201
339
  }
202
340
 
203
341
  if (RB_INTEGER_TYPE_P(rb_time)) {
204
- return sfMicroseconds((int64_t) NUM2LL(rb_time));
342
+ return sfMicroseconds((int64_t)NUM2LL(rb_time));
205
343
  }
206
344
 
207
345
  if (RB_FLOAT_TYPE_P(rb_time) || RB_TYPE_P(rb_time, T_RATIONAL)) {
208
- return sfSeconds((float) NUM2DBL(rb_time));
346
+ return sfSeconds((float)NUM2DBL(rb_time));
209
347
  }
210
348
 
211
349
  raise_invalid_argument_class(rb_cSFTime);
data/ext/system/vec2.c CHANGED
@@ -13,19 +13,31 @@ 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
- };
25
-
26
- static VALUE Vector2_new(int argc, VALUE *argv, VALUE klass) {
23
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
24
+
25
+ /* call-seq:
26
+ * Vector2.new -> Vector2(0, 0)
27
+ * Vector2.new(x, y) -> Vector2(x, y)
28
+ * Vector2.new([x, y]) -> Vector2(x, y)
29
+ * Vector2.new(other_vector2) -> copy of +other_vector2+
30
+ *
31
+ * Creates a new 2D vector from two coordinates, a 2-element Array, or
32
+ * another Vector2.
33
+ *
34
+ * @return [Vector2]
35
+ * @raise [ArgumentError] if given an Array shorter than 2 elements, or an
36
+ * argument count other than 0, 1 or 2
37
+ */
38
+ static VALUE Vector2_new(int argc, VALUE* argv, VALUE klass) {
27
39
  VALUE self;
28
- Vector2 *ptr;
40
+ Vector2* ptr;
29
41
  float x = 0;
30
42
  float y = 0;
31
43
 
@@ -48,6 +60,11 @@ static VALUE Vector2_new(int argc, VALUE *argv, VALUE klass) {
48
60
  }
49
61
 
50
62
  ptr = malloc(sizeof(Vector2));
63
+
64
+ if (ptr == NULL) {
65
+ rb_raise(rb_eNoMemError, "failed to allocate vector");
66
+ }
67
+
51
68
  ptr->vec.x = x;
52
69
  ptr->vec.y = y;
53
70
 
@@ -56,32 +73,70 @@ static VALUE Vector2_new(int argc, VALUE *argv, VALUE klass) {
56
73
  return self;
57
74
  }
58
75
 
76
+ /* call-seq: x -> Float
77
+ *
78
+ * Returns the X component of the vector.
79
+ *
80
+ * @return [Float] the X component
81
+ */
59
82
  static VALUE Vector2_get_x(VALUE self) {
60
- return DBL2NUM(((Vector2 *) Get_Vector2_Struct(self))->vec.x);
83
+ return DBL2NUM(((Vector2*)Get_Vector2_Struct(self))->vec.x);
61
84
  }
62
85
 
86
+ /* call-seq: y -> Float
87
+ *
88
+ * Returns the Y component of the vector.
89
+ *
90
+ * @return [Float] the Y component
91
+ */
63
92
  static VALUE Vector2_get_y(VALUE self) {
64
- return DBL2NUM(((Vector2 *) Get_Vector2_Struct(self))->vec.y);
93
+ return DBL2NUM(((Vector2*)Get_Vector2_Struct(self))->vec.y);
65
94
  }
66
95
 
96
+ /* call-seq:
97
+ * x=(value) -> Float
98
+ *
99
+ * Sets the X component. +value+ is any Float-convertible number.
100
+ *
101
+ * @return [Float] +value+
102
+ */
67
103
  static VALUE Vector2_set_x(VALUE self, VALUE rb_x) {
68
- ((Vector2 *) Get_Vector2_Struct(self))->vec.x = NUM2DBL(rb_x);
104
+ ((Vector2*)Get_Vector2_Struct(self))->vec.x = NUM2DBL(rb_x);
69
105
  return rb_x;
70
106
  }
71
107
 
108
+ /* call-seq:
109
+ * y=(value) -> Float
110
+ *
111
+ * Sets the Y component. +value+ is any Float-convertible number.
112
+ *
113
+ * @return [Float] +value+
114
+ */
72
115
  static VALUE Vector2_set_y(VALUE self, VALUE rb_y) {
73
- ((Vector2 *) Get_Vector2_Struct(self))->vec.y = NUM2DBL(rb_y);
116
+ ((Vector2*)Get_Vector2_Struct(self))->vec.y = NUM2DBL(rb_y);
74
117
  return rb_y;
75
118
  }
76
119
 
120
+ /* call-seq: to_a -> [Float, Float]
121
+ *
122
+ * Returns the vector's components as a two-element Array.
123
+ *
124
+ * @return [Array<Float>] +[x, y]+
125
+ */
77
126
  static VALUE Vector2_to_a(VALUE self) {
78
- Vector2 *vec = Get_Vector2_Struct(self);
127
+ Vector2* vec = Get_Vector2_Struct(self);
79
128
 
80
129
  return rb_ary_new_from_args(2, DBL2NUM(vec->vec.x), DBL2NUM(vec->vec.y));
81
130
  }
82
131
 
132
+ /* call-seq: each { |component| ... } -> self
133
+ *
134
+ * Yields +x+ then +y+.
135
+ *
136
+ * @return [self]
137
+ */
83
138
  static VALUE Vector2_each(VALUE self) {
84
- Vector2 *vec = Get_Vector2_Struct(self);
139
+ Vector2* vec = Get_Vector2_Struct(self);
85
140
 
86
141
  rb_yield(DBL2NUM(vec->vec.x));
87
142
  rb_yield(DBL2NUM(vec->vec.y));
@@ -89,20 +144,40 @@ static VALUE Vector2_each(VALUE self) {
89
144
  return self;
90
145
  }
91
146
 
147
+ /* call-seq:
148
+ * [](index) -> Float
149
+ *
150
+ * Returns the component stored at +index+.
151
+ *
152
+ * @return [Float] +x+ for index 0, +y+ for index 1
153
+ */
92
154
  static VALUE Vector2_aref(VALUE self, VALUE rb_index) {
93
155
  return rb_ary_entry(Vector2_to_a(self), NUM2LONG(rb_index));
94
156
  }
95
157
 
158
+ /* call-seq: size -> Integer
159
+ *
160
+ * Returns the number of components, always 2.
161
+ *
162
+ * @return [Integer] always 2
163
+ */
96
164
  static VALUE Vector2_size(VALUE self) {
97
165
  return INT2NUM(2);
98
166
  }
99
167
 
168
+ /* call-seq:
169
+ * self == other -> true or false
170
+ *
171
+ * +other+ may be a Vector2 or a 2-element Array.
172
+ *
173
+ * @return [Boolean]
174
+ */
100
175
  static VALUE Vector2_eql(VALUE self, VALUE rb_other) {
101
- Vector2 *a = Get_Vector2_Struct(self);
176
+ Vector2* a = Get_Vector2_Struct(self);
102
177
  sfVector2f b;
103
178
 
104
179
  if (rb_obj_is_kind_of(rb_other, rb_cVector2)) {
105
- b = ((Vector2 *) Get_Vector2_Struct(rb_other))->vec;
180
+ b = ((Vector2*)Get_Vector2_Struct(rb_other))->vec;
106
181
  } else if (RB_TYPE_P(rb_other, T_ARRAY) && RARRAY_LEN(rb_other) >= 2) {
107
182
  b = vec2f_from_rb(rb_other);
108
183
  } else {
@@ -112,29 +187,56 @@ static VALUE Vector2_eql(VALUE self, VALUE rb_other) {
112
187
  return BOOL2RB(a->vec.x == b.x && a->vec.y == b.y);
113
188
  }
114
189
 
190
+ /* call-seq:
191
+ * self + other -> Vector2
192
+ *
193
+ * +other+ may be a Vector2 or a 2-element Array.
194
+ *
195
+ * @return [Vector2] componentwise sum
196
+ */
115
197
  static VALUE Vector2_add(VALUE self, VALUE rb_other) {
116
- Vector2 *a = Get_Vector2_Struct(self);
198
+ Vector2* a = Get_Vector2_Struct(self);
117
199
  sfVector2f b = vec2f_from_rb(rb_other);
118
200
 
119
- return vec2f_to_rb((sfVector2f) {a->vec.x + b.x, a->vec.y + b.y});
201
+ return vec2f_to_rb((sfVector2f){a->vec.x + b.x, a->vec.y + b.y});
120
202
  }
121
203
 
204
+ /* call-seq:
205
+ * self - other -> Vector2
206
+ *
207
+ * +other+ may be a Vector2 or a 2-element Array.
208
+ *
209
+ * @return [Vector2] componentwise difference
210
+ */
122
211
  static VALUE Vector2_sub(VALUE self, VALUE rb_other) {
123
- Vector2 *a = Get_Vector2_Struct(self);
212
+ Vector2* a = Get_Vector2_Struct(self);
124
213
  sfVector2f b = vec2f_from_rb(rb_other);
125
214
 
126
- return vec2f_to_rb((sfVector2f) {a->vec.x - b.x, a->vec.y - b.y});
215
+ return vec2f_to_rb((sfVector2f){a->vec.x - b.x, a->vec.y - b.y});
127
216
  }
128
217
 
218
+ /* call-seq:
219
+ * self * scalar -> Vector2
220
+ *
221
+ * Multiplies both components by +scalar+.
222
+ *
223
+ * @return [Vector2]
224
+ */
129
225
  static VALUE Vector2_mul(VALUE self, VALUE rb_scalar) {
130
- Vector2 *a = Get_Vector2_Struct(self);
226
+ Vector2* a = Get_Vector2_Struct(self);
131
227
  float scalar = NUM2DBL(rb_scalar);
132
228
 
133
- return vec2f_to_rb((sfVector2f) {a->vec.x * scalar, a->vec.y * scalar});
229
+ return vec2f_to_rb((sfVector2f){a->vec.x * scalar, a->vec.y * scalar});
134
230
  }
135
231
 
232
+ /* call-seq: to_s -> String
233
+ *
234
+ * Returns a human-readable +"(x, y)"+ representation.
235
+ *
236
+ * @return [String] +"(x, y)"+
237
+ */
136
238
  static VALUE Vector2_to_s(VALUE self) {
137
- Vector2 *a = Get_Vector2_Struct(self);
239
+ Vector2* a = Get_Vector2_Struct(self);
138
240
  char buffer[64];
139
241
 
140
242
  snprintf(buffer, sizeof(buffer), "(%g, %g)", a->vec.x, a->vec.y);
@@ -142,8 +244,25 @@ static VALUE Vector2_to_s(VALUE self) {
142
244
  return rb_str_new2(buffer);
143
245
  }
144
246
 
145
- void Init_Vector2(VALUE rb_module) {
146
- rb_cVector2 = rb_define_class_under(rb_module, "Vector2", rb_cObject);
247
+ /* Document-class: SFML::Vector2
248
+ * A 2D vector of floats, used throughout the library for positions, sizes,
249
+ * scale factors and directions.
250
+ *
251
+ * Includes +Enumerable+ and behaves like a 2-element sequence: it responds to
252
+ * #each, #to_a and #[], and can be compared or combined with a plain
253
+ * +[x, y]+ Array anywhere a Vector2 is accepted.
254
+ *
255
+ * @!attribute x
256
+ * Returns the X component.
257
+ *
258
+ * @return [Float] the X component
259
+ * @!attribute y
260
+ * Returns the Y component.
261
+ *
262
+ * @return [Float] the Y component
263
+ */
264
+ void Init_Vector2(VALUE rb_mSFML) {
265
+ rb_cVector2 = rb_define_class_under(rb_mSFML, "Vector2", rb_cObject);
147
266
 
148
267
  rb_include_module(rb_cVector2, rb_mEnumerable);
149
268
 
@@ -171,15 +290,15 @@ VALUE Get_Klass_Vector2(void) {
171
290
  return rb_cVector2;
172
291
  }
173
292
 
174
- void *Get_Vector2_Struct(VALUE self) {
175
- Vector2 *ptr;
293
+ void* Get_Vector2_Struct(VALUE self) {
294
+ Vector2* ptr;
176
295
  TypedData_Get_Struct(self, Vector2, &Vector2_data_type, ptr);
177
296
  return ptr;
178
297
  }
179
298
 
180
299
  sfVector2f vec2f_from_rb(VALUE rb_vec) {
181
300
  if (rb_obj_is_kind_of(rb_vec, rb_cVector2)) {
182
- return ((Vector2 *) Get_Vector2_Struct(rb_vec))->vec;
301
+ return ((Vector2*)Get_Vector2_Struct(rb_vec))->vec;
183
302
  }
184
303
 
185
304
  if (RB_TYPE_P(rb_vec, T_ARRAY)) {
@@ -187,31 +306,33 @@ sfVector2f vec2f_from_rb(VALUE rb_vec) {
187
306
  raise_invalid_array_length(2);
188
307
  }
189
308
 
190
- return (sfVector2f) {
191
- (float) NUM2DBL(rb_ary_entry(rb_vec, 0)),
192
- (float) NUM2DBL(rb_ary_entry(rb_vec, 1))
193
- };
309
+ return (sfVector2f){(float)NUM2DBL(rb_ary_entry(rb_vec, 0)),
310
+ (float)NUM2DBL(rb_ary_entry(rb_vec, 1))};
194
311
  }
195
312
 
196
313
  raise_invalid_argument_class(rb_cVector2);
197
314
 
198
- return (sfVector2f) {0, 0};
315
+ return (sfVector2f){0, 0};
199
316
  }
200
317
 
201
318
  sfVector2i vec2i_from_rb(VALUE rb_vec) {
202
319
  sfVector2f vec = vec2f_from_rb(rb_vec);
203
320
 
204
- return (sfVector2i) {(int) vec.x, (int) vec.y};
321
+ return (sfVector2i){(int)vec.x, (int)vec.y};
205
322
  }
206
323
 
207
324
  sfVector2u vec2u_from_rb(VALUE rb_vec) {
208
325
  sfVector2f vec = vec2f_from_rb(rb_vec);
209
326
 
210
- return (sfVector2u) {(unsigned) vec.x, (unsigned) vec.y};
327
+ return (sfVector2u){(unsigned)vec.x, (unsigned)vec.y};
211
328
  }
212
329
 
213
330
  VALUE vec2f_to_rb(sfVector2f c_vec) {
214
- Vector2 *ptr = malloc(sizeof(Vector2));
331
+ Vector2* ptr = malloc(sizeof(Vector2));
332
+
333
+ if (ptr == NULL) {
334
+ rb_raise(rb_eNoMemError, "failed to allocate vector");
335
+ }
215
336
 
216
337
  ptr->vec = c_vec;
217
338
 
@@ -219,7 +340,7 @@ VALUE vec2f_to_rb(sfVector2f c_vec) {
219
340
  }
220
341
 
221
342
  VALUE vec2_new(float x, float y) {
222
- return vec2f_to_rb((sfVector2f) {x, y});
343
+ return vec2f_to_rb((sfVector2f){x, y});
223
344
  }
224
345
 
225
346
  void vec2_check(VALUE rb_arr) {