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
@@ -13,26 +13,23 @@ typedef struct {
13
13
 
14
14
  static VALUE rb_cStencilMode;
15
15
 
16
- static const char *comparison_names[] = {
17
- "never", "less", "less_equal", "greater", "greater_equal", "equal", "not_equal", "always"
18
- };
16
+ static const char* comparison_names[] = {"never", "less", "less_equal", "greater",
17
+ "greater_equal", "equal", "not_equal", "always"};
19
18
 
20
- static const char *operation_names[] = {
21
- "keep", "zero", "replace", "increment", "decrement", "invert"
22
- };
19
+ static const char* operation_names[] = {"keep", "zero", "replace",
20
+ "increment", "decrement", "invert"};
23
21
 
24
- static void StencilMode_free(void *ptr) {
22
+ static void StencilMode_free(void* ptr) {
25
23
  free(ptr);
26
24
  }
27
25
 
28
26
  static const rb_data_type_t StencilMode_data_type = {
29
27
  .wrap_struct_name = "SFML::StencilMode",
30
28
  .function = {.dmark = NULL, .dfree = StencilMode_free, .dsize = NULL},
31
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
32
- };
29
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
33
30
 
34
31
  static VALUE StencilMode_wrap(sfStencilMode mode) {
35
- StencilMode *ptr = malloc(sizeof(StencilMode));
32
+ StencilMode* ptr = malloc(sizeof(StencilMode));
36
33
 
37
34
  ptr->mode = mode;
38
35
 
@@ -43,15 +40,15 @@ static sfStencilComparison comparison_from_rb(VALUE rb_value) {
43
40
  size_t i;
44
41
 
45
42
  if (RB_INTEGER_TYPE_P(rb_value)) {
46
- return (sfStencilComparison) NUM2INT(rb_value);
43
+ return (sfStencilComparison)NUM2INT(rb_value);
47
44
  }
48
45
 
49
46
  if (SYMBOL_P(rb_value)) {
50
- const char *name = rb_id2name(SYM2ID(rb_value));
47
+ const char* name = rb_id2name(SYM2ID(rb_value));
51
48
 
52
49
  for (i = 0; i < sizeof(comparison_names) / sizeof(comparison_names[0]); i++) {
53
50
  if (strcmp(name, comparison_names[i]) == 0) {
54
- return (sfStencilComparison) i;
51
+ return (sfStencilComparison)i;
55
52
  }
56
53
  }
57
54
  }
@@ -64,15 +61,15 @@ static sfStencilUpdateOperation operation_from_rb(VALUE rb_value) {
64
61
  size_t i;
65
62
 
66
63
  if (RB_INTEGER_TYPE_P(rb_value)) {
67
- return (sfStencilUpdateOperation) NUM2INT(rb_value);
64
+ return (sfStencilUpdateOperation)NUM2INT(rb_value);
68
65
  }
69
66
 
70
67
  if (SYMBOL_P(rb_value)) {
71
- const char *name = rb_id2name(SYM2ID(rb_value));
68
+ const char* name = rb_id2name(SYM2ID(rb_value));
72
69
 
73
70
  for (i = 0; i < sizeof(operation_names) / sizeof(operation_names[0]); i++) {
74
71
  if (strcmp(name, operation_names[i]) == 0) {
75
- return (sfStencilUpdateOperation) i;
72
+ return (sfStencilUpdateOperation)i;
76
73
  }
77
74
  }
78
75
  }
@@ -81,97 +78,217 @@ static sfStencilUpdateOperation operation_from_rb(VALUE rb_value) {
81
78
  return sfStencilUpdateOperationKeep;
82
79
  }
83
80
 
84
- static VALUE StencilMode_new(int argc, VALUE *argv, VALUE klass) {
85
- VALUE self;
86
- StencilMode *ptr;
81
+ static VALUE StencilMode_alloc(VALUE klass) {
82
+ StencilMode* ptr = malloc(sizeof(StencilMode));
83
+
84
+ if (ptr == NULL) {
85
+ rb_raise(rb_eNoMemError, "failed to allocate stencil mode");
86
+ }
87
+
88
+ ptr->mode = sfStencilMode_default;
89
+
90
+ return TypedData_Wrap_Struct(klass, &StencilMode_data_type, ptr);
91
+ }
92
+
93
+ /* call-seq:
94
+ * StencilMode.new -> StencilMode
95
+ * StencilMode.new(comparison, update_operation, reference, mask, stencil_only) -> StencilMode
96
+ *
97
+ * With no arguments, builds the default stencil mode (always passes,
98
+ * doesn't modify the stencil buffer). +comparison+ and +update_operation+
99
+ * accept either a Symbol (see #comparison and #update_operation) or the
100
+ * matching CSFML Integer constant.
101
+ *
102
+ * @return [StencilMode]
103
+ * @raise [ArgumentError] if given an argument count other than 0 or 5
104
+ */
105
+ static VALUE StencilMode_initialize(int argc, VALUE* argv, VALUE self) {
87
106
  sfStencilMode mode = sfStencilMode_default;
88
107
 
89
108
  if (argc == 5) {
90
109
  mode.stencilComparison = comparison_from_rb(argv[0]);
91
110
  mode.stencilUpdateOperation = operation_from_rb(argv[1]);
92
- mode.stencilReference.value = (unsigned int) NUM2UINT(argv[2]);
93
- mode.stencilMask.value = (unsigned int) NUM2UINT(argv[3]);
111
+ mode.stencilReference.value = (unsigned int)NUM2UINT(argv[2]);
112
+ mode.stencilMask.value = (unsigned int)NUM2UINT(argv[3]);
94
113
  mode.stencilOnly = RTEST(argv[4]);
95
114
  } else if (argc != 0) {
96
115
  raise_invalid_arguments_excepted(5, argc);
97
116
  }
98
117
 
99
- ptr = malloc(sizeof(StencilMode));
100
- ptr->mode = mode;
101
-
102
- self = TypedData_Wrap_Struct(klass, &StencilMode_data_type, ptr);
118
+ ((StencilMode*)Get_StencilMode_Struct(self))->mode = mode;
103
119
 
104
120
  return self;
105
121
  }
106
122
 
123
+ /* call-seq: comparison -> Symbol
124
+ *
125
+ * Returns the comparison used against the stencil buffer.
126
+ *
127
+ * @return [Symbol] one of :never, :less, :less_equal, :greater,
128
+ * :greater_equal, :equal, :not_equal, :always
129
+ */
107
130
  static VALUE StencilMode_get_comparison(VALUE self) {
108
- return ID2SYM(rb_intern(comparison_names[((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilComparison]));
131
+ return ID2SYM(rb_intern(
132
+ comparison_names[((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilComparison]));
109
133
  }
110
134
 
135
+ /* call-seq: update_operation -> Symbol
136
+ *
137
+ * Returns the operation applied when the stencil test passes or fails.
138
+ *
139
+ * @return [Symbol] one of :keep, :zero, :replace, :increment, :decrement,
140
+ * :invert
141
+ */
111
142
  static VALUE StencilMode_get_operation(VALUE self) {
112
- sfStencilMode mode = ((StencilMode *) Get_StencilMode_Struct(self))->mode;
143
+ sfStencilMode mode = ((StencilMode*)Get_StencilMode_Struct(self))->mode;
113
144
 
114
145
  return ID2SYM(rb_intern(operation_names[mode.stencilUpdateOperation]));
115
146
  }
116
147
 
148
+ /* call-seq: reference -> Integer
149
+ *
150
+ * Returns the reference value compared against the stencil buffer.
151
+ *
152
+ * @return [Integer]
153
+ */
117
154
  static VALUE StencilMode_get_reference(VALUE self) {
118
- return UINT2NUM(((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilReference.value);
155
+ return UINT2NUM(((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilReference.value);
119
156
  }
120
157
 
158
+ /* call-seq: mask -> Integer
159
+ *
160
+ * Returns the bitmask applied to the stencil values.
161
+ *
162
+ * @return [Integer]
163
+ */
121
164
  static VALUE StencilMode_get_mask(VALUE self) {
122
- return UINT2NUM(((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilMask.value);
165
+ return UINT2NUM(((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilMask.value);
123
166
  }
124
167
 
168
+ /* call-seq: stencil_only -> true or false
169
+ *
170
+ * Returns +true+ if only the stencil buffer is written to.
171
+ *
172
+ * @return [Boolean]
173
+ */
125
174
  static VALUE StencilMode_get_only(VALUE self) {
126
- return BOOL2RB(((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilOnly);
175
+ return BOOL2RB(((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilOnly);
127
176
  }
128
177
 
178
+ /* call-seq:
179
+ * comparison=(value) -> Symbol or Integer
180
+ *
181
+ * Sets the comparison used against the stencil buffer.
182
+ *
183
+ * @return [Symbol, Integer] +value+
184
+ */
129
185
  static VALUE StencilMode_set_comparison(VALUE self, VALUE rb_value) {
130
- ((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilComparison = comparison_from_rb(rb_value);
186
+ ((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilComparison =
187
+ comparison_from_rb(rb_value);
131
188
  return rb_value;
132
189
  }
133
190
 
191
+ /* call-seq:
192
+ * update_operation=(value) -> Symbol or Integer
193
+ *
194
+ * Sets the operation applied when the stencil test passes or fails.
195
+ *
196
+ * @return [Symbol, Integer] +value+
197
+ */
134
198
  static VALUE StencilMode_set_operation(VALUE self, VALUE rb_value) {
135
- ((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilUpdateOperation = operation_from_rb(rb_value);
199
+ ((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilUpdateOperation =
200
+ operation_from_rb(rb_value);
136
201
  return rb_value;
137
202
  }
138
203
 
204
+ /* call-seq:
205
+ * reference=(value) -> Integer
206
+ *
207
+ * Sets the reference value compared against the stencil buffer.
208
+ *
209
+ * @return [Integer] +value+
210
+ */
139
211
  static VALUE StencilMode_set_reference(VALUE self, VALUE rb_value) {
140
- ((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilReference.value = (unsigned int) NUM2UINT(rb_value);
212
+ ((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilReference.value =
213
+ (unsigned int)NUM2UINT(rb_value);
141
214
  return rb_value;
142
215
  }
143
216
 
217
+ /* call-seq:
218
+ * mask=(value) -> Integer
219
+ *
220
+ * Sets the bitmask applied to the stencil values.
221
+ *
222
+ * @return [Integer] +value+
223
+ */
144
224
  static VALUE StencilMode_set_mask(VALUE self, VALUE rb_value) {
145
- ((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilMask.value = (unsigned int) NUM2UINT(rb_value);
225
+ ((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilMask.value =
226
+ (unsigned int)NUM2UINT(rb_value);
146
227
  return rb_value;
147
228
  }
148
229
 
230
+ /* call-seq:
231
+ * stencil_only=(value) -> true or false
232
+ *
233
+ * Enables or disables writing only to the stencil buffer.
234
+ *
235
+ * @return [Boolean] +value+
236
+ */
149
237
  static VALUE StencilMode_set_only(VALUE self, VALUE rb_value) {
150
- ((StencilMode *) Get_StencilMode_Struct(self))->mode.stencilOnly = RTEST(rb_value);
238
+ ((StencilMode*)Get_StencilMode_Struct(self))->mode.stencilOnly = RTEST(rb_value);
151
239
  return rb_value;
152
240
  }
153
241
 
242
+ /* call-seq:
243
+ * self == other -> true or false
244
+ *
245
+ * Returns +true+ if the two objects are equal.
246
+ *
247
+ * @return [Boolean]
248
+ */
154
249
  static VALUE StencilMode_eql(VALUE self, VALUE rb_other) {
155
- sfStencilMode a = ((StencilMode *) Get_StencilMode_Struct(self))->mode;
250
+ sfStencilMode a = ((StencilMode*)Get_StencilMode_Struct(self))->mode;
156
251
  sfStencilMode b;
157
252
 
158
253
  if (!rb_obj_is_kind_of(rb_other, rb_cStencilMode)) {
159
254
  return Qfalse;
160
255
  }
161
256
 
162
- b = ((StencilMode *) Get_StencilMode_Struct(rb_other))->mode;
257
+ b = ((StencilMode*)Get_StencilMode_Struct(rb_other))->mode;
163
258
 
164
259
  return BOOL2RB(a.stencilComparison == b.stencilComparison &&
165
260
  a.stencilUpdateOperation == b.stencilUpdateOperation &&
166
261
  a.stencilReference.value == b.stencilReference.value &&
167
- a.stencilMask.value == b.stencilMask.value &&
168
- a.stencilOnly == b.stencilOnly);
262
+ a.stencilMask.value == b.stencilMask.value && a.stencilOnly == b.stencilOnly);
169
263
  }
170
264
 
171
- void Init_StencilMode(VALUE rb_module) {
172
- rb_cStencilMode = rb_define_class_under(rb_module, "StencilMode", rb_cObject);
173
-
174
- rb_define_singleton_method(rb_cStencilMode, "new", StencilMode_new, -1);
265
+ /* Document-class: SFML::StencilMode
266
+ * Configures how the stencil buffer is used and updated when drawing,
267
+ * carried on RenderState#stencil_mode.
268
+ *
269
+ * @!attribute comparison
270
+ * The comparison used against the stencil buffer.
271
+ * @return [Symbol] one of :never, :less, :less_equal, :greater,
272
+ * :greater_equal, :equal, :not_equal, :always
273
+ * @!attribute update_operation
274
+ * The operation applied when the stencil test passes or fails.
275
+ * @return [Symbol] one of :keep, :zero, :replace, :increment, :decrement,
276
+ * :invert
277
+ * @!attribute reference
278
+ * The reference value compared against the stencil buffer.
279
+ * @return [Integer]
280
+ * @!attribute mask
281
+ * The bitmask applied to the stencil values.
282
+ * @return [Integer]
283
+ * @!attribute stencil_only
284
+ * Whether only the stencil buffer is written to.
285
+ * @return [Boolean]
286
+ */
287
+ void Init_StencilMode(VALUE rb_mSFML) {
288
+ rb_cStencilMode = rb_define_class_under(rb_mSFML, "StencilMode", rb_cObject);
289
+
290
+ rb_define_alloc_func(rb_cStencilMode, StencilMode_alloc);
291
+ rb_define_method(rb_cStencilMode, "initialize", StencilMode_initialize, -1);
175
292
 
176
293
  rb_define_method(rb_cStencilMode, "comparison", StencilMode_get_comparison, 0);
177
294
  rb_define_method(rb_cStencilMode, "update_operation", StencilMode_get_operation, 0);
@@ -192,15 +309,15 @@ VALUE Get_Klass_StencilMode(void) {
192
309
  return rb_cStencilMode;
193
310
  }
194
311
 
195
- void *Get_StencilMode_Struct(VALUE self) {
196
- StencilMode *ptr;
312
+ void* Get_StencilMode_Struct(VALUE self) {
313
+ StencilMode* ptr;
197
314
  TypedData_Get_Struct(self, StencilMode, &StencilMode_data_type, ptr);
198
315
  return ptr;
199
316
  }
200
317
 
201
318
  sfStencilMode stencil_mode_from_rb(VALUE rb_mode) {
202
319
  if (rb_obj_is_kind_of(rb_mode, rb_cStencilMode)) {
203
- return ((StencilMode *) Get_StencilMode_Struct(rb_mode))->mode;
320
+ return ((StencilMode*)Get_StencilMode_Struct(rb_mode))->mode;
204
321
  }
205
322
 
206
323
  return sfStencilMode_default;
@@ -5,52 +5,83 @@
5
5
 
6
6
  #include "graphics/render_state.h"
7
7
  #include "graphics/render_texture.h"
8
+ #include "graphics/render_window.h"
8
9
  #include "graphics/view.h"
9
10
  #include "window/window.h"
10
11
  #include "core/exceptions.h"
11
12
  #include "core/macros.h"
12
13
 
13
14
  static VALUE rb_cTarget;
15
+ static VALUE rb_mRenderTarget;
14
16
 
15
- static Target *Target_create(TargetType type, void *handle) {
16
- Target *target = malloc(sizeof(Target));
17
+ static Target* Target_create(TargetType type, void* handle, VALUE rb_source) {
18
+ Target* target = malloc(sizeof(Target));
19
+
20
+ if (target == NULL) {
21
+ rb_raise(rb_eNoMemError, "failed to allocate render target");
22
+ }
17
23
 
18
24
  target->type = type;
19
25
  target->handle = handle;
26
+ target->rb_source = rb_source;
20
27
 
21
28
  return target;
22
29
  }
23
30
 
24
- static void RenderTarget_free(void *ptr) {
31
+ static void RenderTarget_mark(void* ptr) {
32
+ rb_gc_mark(((Target*)ptr)->rb_source);
33
+ }
34
+
35
+ static void RenderTarget_free(void* ptr) {
25
36
  free(ptr);
26
37
  }
27
38
 
28
39
  static const rb_data_type_t RenderTarget_data_type = {
29
40
  .wrap_struct_name = "SFML::Target",
30
- .function = {.dmark = NULL, .dfree = RenderTarget_free, .dsize = NULL},
31
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
32
- };
41
+ .function = {.dmark = RenderTarget_mark, .dfree = RenderTarget_free, .dsize = NULL},
42
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
43
+
44
+ static VALUE RenderTarget_wrap(VALUE klass, TargetType type, void* handle, VALUE rb_source) {
45
+ return TypedData_Wrap_Struct(klass, &RenderTarget_data_type,
46
+ Target_create(type, handle, rb_source));
47
+ }
48
+
49
+ static VALUE RenderTarget_alloc(VALUE klass) {
50
+ return RenderTarget_wrap(klass, SFML_TARGET_WINDOW, NULL, Qnil);
51
+ }
33
52
 
34
- static VALUE RenderTarget_new(VALUE klass, VALUE rb_window) {
35
- VALUE self;
36
- Target *target;
53
+ /* call-seq:
54
+ * Target.new(window) -> Target
55
+ *
56
+ * Wraps +window+ (a Window) as a generic render target.
57
+ *
58
+ * @return [Target]
59
+ * @raise [TypeError] if +window+ is not a Window
60
+ */
61
+ static VALUE RenderTarget_initialize(VALUE self, VALUE rb_window) {
62
+ Target* target;
37
63
 
38
64
  if (!rb_obj_is_kind_of(rb_window, Get_Klass_Window())) {
39
65
  raise_invalid_argument_class(Get_Klass_Window());
40
66
  }
41
67
 
42
- target = Target_create(SFML_TARGET_WINDOW, Get_Window_Struct(rb_window));
43
- self = TypedData_Wrap_Struct(klass, &RenderTarget_data_type, target);
44
-
45
- rb_obj_call_init(self, 0, NULL);
68
+ target = Get_Target_Struct(self);
69
+ target->type = SFML_TARGET_WINDOW;
70
+ target->handle = Get_Window_Struct(rb_window);
71
+ target->rb_source = rb_window;
46
72
 
47
73
  return self;
48
74
  }
49
75
 
50
- static VALUE RenderTarget_init(VALUE self) {
51
- return self;
52
- }
53
-
76
+ /* call-seq:
77
+ * draw(drawable, state) -> void
78
+ *
79
+ * Draws +drawable+ (any object responding to +#draw+, i.e. including
80
+ * Drawable) onto this target using +state+ (a RenderState).
81
+ *
82
+ * @return [nil]
83
+ * @raise [TypeError] if +state+ is not a RenderState
84
+ */
54
85
  static VALUE RenderTarget_draw(VALUE self, VALUE rb_drawable, VALUE rb_state) {
55
86
  if (!rb_obj_is_kind_of(rb_state, Get_Klass_RenderState())) {
56
87
  raise_invalid_argument_class(Get_Klass_RenderState());
@@ -59,42 +90,94 @@ static VALUE RenderTarget_draw(VALUE self, VALUE rb_drawable, VALUE rb_state) {
59
90
  return rb_funcall(rb_drawable, rb_intern("draw"), 2, self, rb_state);
60
91
  }
61
92
 
93
+ /* call-seq:
94
+ * view=(value) -> nil
95
+ *
96
+ * Sets the target's current view.
97
+ *
98
+ * @return [nil]
99
+ * @raise [TypeError] if +value+ is not a View
100
+ */
62
101
  static VALUE RenderTarget_set_view(VALUE self, VALUE rb_view) {
63
- Target *target = Get_Target_Struct(self);
102
+ Target* target = Get_Target_Struct(self);
64
103
 
65
104
  if (!rb_obj_is_kind_of(rb_view, Get_Klass_View())) {
66
105
  raise_invalid_argument_class(Get_Klass_View());
67
106
  }
68
107
 
69
108
  if (target->type == SFML_TARGET_WINDOW) {
70
- sfRenderWindow_setView((sfRenderWindow *) target->handle, Get_View_Struct(rb_view));
109
+ sfRenderWindow_setView((sfRenderWindow*)target->handle, Get_View_Struct(rb_view));
71
110
  } else {
72
- sfRenderTexture_setView((sfRenderTexture *) target->handle, Get_View_Struct(rb_view));
111
+ sfRenderTexture_setView((sfRenderTexture*)target->handle, Get_View_Struct(rb_view));
73
112
  }
74
113
 
75
114
  return Qnil;
76
115
  }
77
116
 
117
+ /* call-seq: view -> View
118
+ *
119
+ * Returns the target's current view.
120
+ *
121
+ * @return [View] a copy of the target's current view
122
+ */
78
123
  static VALUE RenderTarget_get_view(VALUE self) {
79
- Target *target = Get_Target_Struct(self);
80
- sfView *view;
124
+ Target* target = Get_Target_Struct(self);
125
+ sfView* view;
81
126
 
82
127
  if (target->type == SFML_TARGET_WINDOW) {
83
- view = sfView_copy(sfRenderWindow_getView((sfRenderWindow *) target->handle));
128
+ view = sfView_copy(sfRenderWindow_getView((sfRenderWindow*)target->handle));
84
129
  } else {
85
- view = sfView_copy(sfRenderTexture_getView((sfRenderTexture *) target->handle));
130
+ view = sfView_copy(sfRenderTexture_getView((sfRenderTexture*)target->handle));
86
131
  }
87
132
 
88
133
  return Get_Casting_View(view);
89
134
  }
90
135
 
91
- void Init_Target(VALUE rb_module) {
92
- rb_cTarget = rb_define_class_under(rb_module, "Target", rb_cObject);
136
+ TargetView Get_RenderTarget_View(VALUE self) {
137
+ TargetView view;
138
+
139
+ if (rb_obj_is_kind_of(self, Get_Klass_Target())) {
140
+ Target* target = Get_Target_Struct(self);
141
+
142
+ view.type = target->type;
143
+ view.handle = target->handle;
144
+ return view;
145
+ }
146
+
147
+ if (rb_obj_is_kind_of(self, rb_mRenderTarget)) {
148
+ if (rb_obj_is_kind_of(self, Get_Klass_RenderWindow())) {
149
+ view.type = SFML_TARGET_WINDOW;
150
+ view.handle = Get_Window_Struct(self);
151
+ } else {
152
+ view.type = SFML_TARGET_TEXTURE;
153
+ view.handle = Get_RenderTexture_Struct(self);
154
+ }
155
+ return view;
156
+ }
93
157
 
94
- rb_define_singleton_method(rb_cTarget, "new", RenderTarget_new, 1);
158
+ rb_raise(rb_eArgError, "expected a RenderTarget (RenderWindow or RenderTexture)");
159
+ }
160
+
161
+ /* Document-class: SFML::Target
162
+ * A legacy generic handle onto whatever can be drawn to -- a Window or a
163
+ * RenderTexture -- used by Drawable#draw so drawable objects don't need to
164
+ * know which concrete kind of target they're being drawn onto.
165
+ *
166
+ * New code should pass a SFML::RenderWindow or SFML::RenderTexture (both
167
+ * include SFML::RenderTarget) straight to a drawable's #draw.
168
+ *
169
+ * @!attribute view
170
+ * The target's current view.
171
+ * @return [View]
172
+ */
173
+ void Init_Target(VALUE rb_mSFML) {
174
+ rb_cTarget = rb_define_class_under(rb_mSFML, "Target", rb_cObject);
175
+ rb_mRenderTarget = rb_define_module_under(rb_mSFML, "RenderTarget");
176
+
177
+ rb_define_alloc_func(rb_cTarget, RenderTarget_alloc);
95
178
 
96
179
  // methods
97
- rb_define_method(rb_cTarget, "initialize", RenderTarget_init, 0);
180
+ rb_define_method(rb_cTarget, "initialize", RenderTarget_initialize, 1);
98
181
  rb_define_method(rb_cTarget, "draw", RenderTarget_draw, 2);
99
182
 
100
183
  // setters
@@ -108,26 +191,21 @@ VALUE Get_Klass_Target(void) {
108
191
  return rb_cTarget;
109
192
  }
110
193
 
111
- Target *Get_Target_Struct(VALUE self) {
112
- Target *ptr;
194
+ VALUE Get_Module_RenderTarget(void) {
195
+ return rb_mRenderTarget;
196
+ }
197
+
198
+ Target* Get_Target_Struct(VALUE self) {
199
+ Target* ptr;
113
200
  TypedData_Get_Struct(self, Target, &RenderTarget_data_type, ptr);
114
201
  return ptr;
115
202
  }
116
203
 
117
204
  VALUE Get_New_Target(VALUE rb_window) {
118
- return RenderTarget_new(Get_Klass_Target(), rb_window);
119
- }
120
-
121
- VALUE Get_New_Target_From_RenderTexture(VALUE rb_render_texture) {
122
- VALUE self;
123
- Target *target;
124
-
125
- if (!rb_obj_is_kind_of(rb_render_texture, Get_Klass_RenderTexture())) {
126
- raise_invalid_argument_class(Get_Klass_RenderTexture());
205
+ if (!rb_obj_is_kind_of(rb_window, Get_Klass_Window())) {
206
+ raise_invalid_argument_class(Get_Klass_Window());
127
207
  }
128
208
 
129
- target = Target_create(SFML_TARGET_TEXTURE, Get_RenderTexture_Struct(rb_render_texture));
130
- self = TypedData_Wrap_Struct(rb_cTarget, &RenderTarget_data_type, target);
131
-
132
- return self;
209
+ return RenderTarget_wrap(Get_Klass_Target(), SFML_TARGET_WINDOW, Get_Window_Struct(rb_window),
210
+ rb_window);
133
211
  }
@@ -5,36 +5,50 @@
5
5
 
6
6
  #include "core/sfml.h"
7
7
 
8
- typedef enum {
9
- SFML_TARGET_WINDOW,
10
- SFML_TARGET_TEXTURE
11
- } TargetType;
8
+ typedef enum { SFML_TARGET_WINDOW, SFML_TARGET_TEXTURE } TargetType;
12
9
 
10
+ /* A borrowed view onto whatever a draw call is headed for: the kind plus the
11
+ opaque handle. Built on the stack by Get_RenderTarget_View, never owned. */
13
12
  typedef struct {
14
13
  TargetType type;
15
- void *handle;
14
+ void* handle;
15
+ } TargetView;
16
+
17
+ /* The legacy generic wrapper behind SFML::Target. It owns only the borrow, so
18
+ it keeps its source alive for as long as it references it. */
19
+ typedef struct {
20
+ TargetType type;
21
+ void* handle;
22
+ /* The Window/RenderWindow/RenderTexture `handle` is borrowed from, kept
23
+ alive for as long as this Target references it -- see Target_mark. */
24
+ VALUE rb_source;
16
25
  } Target;
17
26
 
18
- /* Dispatch a draw call to whichever underlying render surface this target
27
+ /* Dispatch a draw call to whichever underlying render surface this view
19
28
  wraps. Pass NULL states to use the defaults; never hand CSFML a NULL. */
20
- #define TARGET_DRAW(target, window_fn, texture_fn, object, states) \
21
- do { \
22
- const sfRenderStates *sfml_states = (states) ? (states) : &sfRenderStates_default; \
23
- if ((target)->type == SFML_TARGET_WINDOW) { \
24
- window_fn((sfRenderWindow *) (target)->handle, (object), sfml_states); \
25
- } else { \
26
- texture_fn((sfRenderTexture *) (target)->handle, (object), sfml_states); \
27
- } \
29
+ #define TARGET_DRAW(view, window_fn, texture_fn, object, states) \
30
+ do { \
31
+ const sfRenderStates* sfml_states = (states) ? (states) : &sfRenderStates_default; \
32
+ if ((view).type == SFML_TARGET_WINDOW) { \
33
+ window_fn((sfRenderWindow*)(view).handle, (object), sfml_states); \
34
+ } else { \
35
+ texture_fn((sfRenderTexture*)(view).handle, (object), sfml_states); \
36
+ } \
28
37
  } while (0)
29
38
 
30
39
  void Init_Target(VALUE rb_module);
31
40
 
32
41
  VALUE Get_Klass_Target(void);
33
42
 
34
- Target *Get_Target_Struct(VALUE self);
43
+ Target* Get_Target_Struct(VALUE self);
35
44
 
36
45
  VALUE Get_New_Target(VALUE rb_window);
37
46
 
38
- VALUE Get_New_Target_From_RenderTexture(VALUE rb_render_texture);
47
+ /* The SFML::RenderTarget module, included by RenderWindow and RenderTexture. */
48
+ VALUE Get_Module_RenderTarget(void);
49
+
50
+ /* Resolves any accepted draw target -- a legacy Target, a RenderWindow or a
51
+ RenderTexture -- to its kind and handle, raising TypeError otherwise. */
52
+ TargetView Get_RenderTarget_View(VALUE self);
39
53
 
40
- #endif //SFML_RB_GRAPHICS_TARGET_H
54
+ #endif // SFML_RB_GRAPHICS_TARGET_H