sfml3-rb 0.2.2-aarch64-linux-gnu → 0.3.1-aarch64-linux-gnu

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 (79) 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/lib/sfml/3.1/sfml_ext.so +0 -0
  7. data/lib/sfml/3.2/sfml_ext.so +0 -0
  8. data/lib/sfml/3.3/sfml_ext.so +0 -0
  9. data/lib/sfml/3.4/sfml_ext.so +0 -0
  10. data/lib/sfml/4.0/sfml_ext.so +0 -0
  11. data/lib/sfml/version.rb +1 -1
  12. data/sig/audio/audio_enums.rbs +30 -0
  13. data/sig/audio/listener.rbs +16 -0
  14. data/sig/audio/music.rbs +56 -0
  15. data/sig/audio/sound.rbs +51 -0
  16. data/sig/audio/sound_buffer.rbs +17 -0
  17. data/sig/audio/sound_buffer_recorder.rbs +14 -0
  18. data/sig/audio/sound_recorder.rbs +17 -0
  19. data/sig/audio/sound_source_cone.rbs +14 -0
  20. data/sig/audio/sound_stream.rbs +51 -0
  21. data/sig/graphics/blend_mode.rbs +29 -0
  22. data/sig/graphics/circle.rbs +44 -0
  23. data/sig/graphics/color.rbs +39 -0
  24. data/sig/graphics/drawable.rbs +5 -0
  25. data/sig/graphics/font.rbs +20 -0
  26. data/sig/graphics/glyph.rbs +7 -0
  27. data/sig/graphics/image.rbs +22 -0
  28. data/sig/graphics/polygon.rbs +42 -0
  29. data/sig/graphics/rect.rbs +33 -0
  30. data/sig/graphics/rectangle.rbs +42 -0
  31. data/sig/graphics/render_state.rbs +21 -0
  32. data/sig/graphics/render_target.rbs +18 -0
  33. data/sig/graphics/render_texture.rbs +39 -0
  34. data/sig/graphics/render_window.rbs +7 -0
  35. data/sig/graphics/shader.rbs +39 -0
  36. data/sig/graphics/shape.rbs +38 -0
  37. data/sig/graphics/sprite.rbs +34 -0
  38. data/sig/graphics/stencil_mode.rbs +18 -0
  39. data/sig/graphics/target.rbs +8 -0
  40. data/sig/graphics/text.rbs +48 -0
  41. data/sig/graphics/texture.rbs +34 -0
  42. data/sig/graphics/transform.rbs +37 -0
  43. data/sig/graphics/transformable.rbs +25 -0
  44. data/sig/graphics/vertex.rbs +17 -0
  45. data/sig/graphics/vertex_array.rbs +17 -0
  46. data/sig/graphics/vertex_buffer.rbs +22 -0
  47. data/sig/graphics/view.rbs +23 -0
  48. data/sig/network/ftp.rbs +46 -0
  49. data/sig/network/http.rbs +27 -0
  50. data/sig/network/ip_address.rbs +22 -0
  51. data/sig/network/network_enums.rbs +95 -0
  52. data/sig/network/packet.rbs +40 -0
  53. data/sig/network/socket_selector.rbs +14 -0
  54. data/sig/network/tcp_listener.rbs +13 -0
  55. data/sig/network/tcp_socket.rbs +18 -0
  56. data/sig/network/udp_socket.rbs +17 -0
  57. data/sig/sfml/version.rbs +3 -0
  58. data/sig/system/buffer.rbs +11 -0
  59. data/sig/system/clock.rbs +13 -0
  60. data/sig/system/input_stream.rbs +7 -0
  61. data/sig/system/sleep.rbs +3 -0
  62. data/sig/system/time.rbs +28 -0
  63. data/sig/system/vec2.rbs +26 -0
  64. data/sig/system/vec3.rbs +27 -0
  65. data/sig/window/clipboard.rbs +8 -0
  66. data/sig/window/context.rbs +11 -0
  67. data/sig/window/context_settings.rbs +20 -0
  68. data/sig/window/cursor.rbs +6 -0
  69. data/sig/window/event.rbs +20 -0
  70. data/sig/window/joystick.rbs +15 -0
  71. data/sig/window/keyboard.rbs +10 -0
  72. data/sig/window/mouse.rbs +9 -0
  73. data/sig/window/sensor.rbs +8 -0
  74. data/sig/window/touch.rbs +6 -0
  75. data/sig/window/video_mode.rbs +16 -0
  76. data/sig/window/vulkan.rbs +7 -0
  77. data/sig/window/window.rbs +34 -0
  78. data/sig/window/window_base.rbs +33 -0
  79. metadata +70 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4510ed5456ddaa1b76a30674c1ca53c60349ce1f459cec7923758519ffc04df9
4
- data.tar.gz: 1b1090177c5003a49b8fb963195dfcca0394c749455c7b72e2b5891bdb0a8934
3
+ metadata.gz: '0739aa4a9f14de7f4ac493544541c772796f84793dee69e7986c4aed4f01f088'
4
+ data.tar.gz: '01988ef4500d202539e22566355f42b2b07db3c1c58b62dc31361eb4b64c079f'
5
5
  SHA512:
6
- metadata.gz: cacfaeff7b81db0c13dd6b92d8825929951e2468d9f63250bc91c6297d3f9500461f93dda996b4e7cfaa65164a66ee675c966ff8d5e9c20f81847e43eb41b823
7
- data.tar.gz: 6d13836c3c9cc017fa632650e1b4a040edac6b32dc5d30f781f207343ea89d1eead28d3fcde46548409e0585c83a6b46f3ab55174f9c4058e3f32062c5249f3f
6
+ metadata.gz: 1c1e6ac6cbd377bd2c0966806010dcc45a9f08c5da676749c9d1f5a8547f3ae280e10d2adaf66936bcc755282fcf650d86336438eed56b96a774f5029c7bbc26
7
+ data.tar.gz: 01f3ce3ae5305736174617f1a74f0dbf04e6cca6010734b657637c54cc01a52413f39439a2176f810037b3ae9a5c3cefe108141884e29eca108ea7c88b869f7b
data/.yardopts ADDED
@@ -0,0 +1,9 @@
1
+ --markup markdown
2
+ --output-dir doc
3
+ --title sfml3-rb
4
+ --readme README.md
5
+ ext/**/*.c
6
+ -
7
+ CHANGELOG.md
8
+ TODO.md
9
+ LICENSE.md
data/CHANGELOG.md CHANGED
@@ -6,26 +6,77 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.3.1] - 2026-09-19
10
+
9
11
  ### Added
10
- * **Full YARD API documentation and RBS type signatures**, covering every
11
- bound class, module, method and constant. Doc comments live in-place in
12
- the `ext/**/*.c` sources (YARD's C parser, the same convention RDoc uses),
13
- so they're published automatically to
14
- [rubydoc.info](https://rubydoc.info/gems/sfml3-rb) on release; `rake yard`
15
- builds them locally into `doc/`. `sig/**/*.rbs` ships in the gem alongside
16
- the extension sources, for IDE completion (Solargraph, RubyMine) and
17
- static type-checking (Sorbet, Steep). Run `rake rbs` to validate the
18
- signatures.
12
+ * **`SFML::WindowBase`, `SFML::RenderWindow` and the `SFML::RenderTarget` module**, mirroring
13
+ SFML 3's own hierarchy. `WindowBase` wraps `sfWindowBase` -- an OS window and event queue with
14
+ no OpenGL context -- and is constructible, with `Window` and `RenderWindow` derived from it.
15
+ `Window` keeps its existing `sfRenderWindow` behaviour; `RenderWindow` is the same renderable
16
+ window under the name that also includes `RenderTarget`. `RenderTexture` includes
17
+ `RenderTarget` too, so a drawable's `#draw` now accepts a `RenderWindow` or a `RenderTexture`
18
+ directly (the legacy `Target` still works). The shared window surface is generated once, in
19
+ `ext/window/window_base.inc`.
20
+ * **RBS signatures are now checked against the code.** `sig/**/*.rbs` declares `SFML::VERSION`, and
21
+ a `Steepfile` plus the `steep` development gem add `rake steep` to type-check `lib/` against the
22
+ signatures. `check.yaml` runs both `rake rbs` and `rake steep`, on `main` and on `release/**`
23
+ PRs, which previously ran no workflow at all.
24
+
25
+ ### Changed
26
+ * `Mouse.position`, `Mouse.set_position` and `Touch.position` dispatch to the
27
+ `*RenderWindow` or `*WindowBase` CSFML entry point depending on whether the argument is a
28
+ Window/RenderWindow or a WindowBase, instead of passing an `sfRenderWindow*` where an
29
+ `sfWindowBase*` is expected.
30
+ * **RBS constructors use `def initialize`.** Every `def self.new` became
31
+ `def initialize: (…) -> void`, the form RubyMine links to `Foo.new` and Steep checks, and which
32
+ matches the C extension, where every constructor is an `initialize`.
19
33
 
20
- ## [0.2.2]
34
+ ## [0.3.0] - 2026-09-19
35
+
36
+ ### Added
37
+ * **Four more experimental binary-gem targets**: `aarch64-linux-musl`, `arm-linux-gnu`
38
+ (ARMv7 hard-float), `arm-linux-musl`, and `aarch64-mingw-ucrt` (64-bit Windows on ARM).
39
+ All four ride the same rake-compiler-dock cross-compilation this project already uses for
40
+ its other targets; none has been run on its target hardware yet, so all are
41
+ `experimental` in `publish.yaml` like `aarch64-linux-gnu`, `x86_64-darwin` and
42
+ `arm64-darwin` already were. `script/provision.sh` gained matching cases for the two new
43
+ glibc/musl Linux targets.
44
+ * `rakelib/package.rake`'s `EXPECTED_ABIS` gained an entry for `aarch64-mingw-ucrt`: its
45
+ rake-compiler-dock image carries no cross Ruby older than 3.4, so that gem has no floor
46
+ below it — the same kind of upstream gap `x86-mingw32` already has at the top end.
47
+ * `aarch64-linux-gnu` is now additionally run — not just cross-compiled — by a new
48
+ `test-arm64.yaml` workflow, on GitHub's hosted `ubuntu-24.04-arm` runner. It stays
49
+ `experimental` in `publish.yaml` for now; this is the evidence that will eventually
50
+ justify dropping that flag.
51
+ * ARMv6 (32-bit), RISC-V (rv64gc), PowerPC (ppc64le), and any BSD are deliberately not
52
+ covered by a binary gem: rake-compiler-dock ships no cross-compilation image for any of
53
+ them, and building custom cross-toolchain infrastructure for them is a much larger,
54
+ separate undertaking. The source-gem fallback remains the only path there, unchanged.
21
55
 
22
56
  ### Fixed
23
- * **The macOS binary gems now build.** SFML 3.0.2 defaults
24
- `CMAKE_OSX_DEPLOYMENT_TARGET` to 13.0, but the osxcross SDK in the
25
- rake-compiler-dock image is 11.1 and rejects a newer target, so both Darwin
26
- builds aborted while configuring SFML. The ports toolchain now pins the
27
- deployment target to macOS 11.0, which is the floor Apple Silicon requires
28
- anyway.
57
+ * **A GC race in the audio bindings aborted the process on arm64.** `Sound`, `Music` and
58
+ `SoundStream` released the GVL inside their `dfree`, but their data types were marked
59
+ `RUBY_TYPED_FREE_IMMEDIATELY`, so the free could run *during* garbage collection: another
60
+ thread (Ruby's `Timeout` thread, in the test suite) could then allocate while GC was mid-cycle
61
+ and Ruby aborted with "object allocation during garbage collection phase". Dropping the flag
62
+ defers the free to a safe point; releasing the GVL is still what keeps `sf*_destroy` from
63
+ deadlocking against the audio thread.
64
+
65
+ ### Documentation
66
+ * **Every public class, module, method and constant is documented**, with the
67
+ result rendered on [rubydoc.info](https://rubydoc.info/gems/sfml3-rb). The
68
+ comments live beside each binding in `ext/**/*.c`; `rake yard` builds them
69
+ into `doc/`. Previously the comments carried `call-seq` and `@return` tags
70
+ but little prose, so rubydoc.info showed a signature with a blank
71
+ description; every such method now has a sentence of its own.
72
+ * RBS type signatures for the same surface ship in `sig/**/*.rbs`, for IDE
73
+ completion (Solargraph, RubyMine) and static checking (Sorbet, Steep);
74
+ `rake rbs` validates them.
75
+ * `.yardopts` ships in the gem, so rubydoc.info generates with the same title,
76
+ README and extra files as `rake yard`.
77
+ * `rake doc:undoc` fails when a method is left without a description, so the
78
+ coverage cannot regress silently (`yard stats` uses `blank?` and passes for
79
+ tag-only comments, which is how the blanks went unnoticed).
29
80
 
30
81
  ## [0.2.1]
31
82
 
data/README.md CHANGED
@@ -2,17 +2,42 @@
2
2
 
3
3
  Ruby bindings for [SFML 3](https://www.sfml-dev.org/), via its C API, [CSFML](https://github.com/SFML/CSFML).
4
4
 
5
- ## Status
6
-
7
- Latest release: **0.2.2**. Bound against **CSFML 3**. See [TODO.md](TODO.md) for which parts of the
8
- SFML 3 API are ported so far, and [CHANGELOG.md](CHANGELOG.md) for what changed recently.
9
-
10
- API docs (every class, module, method and constant) are on
11
- [rubydoc.info](https://rubydoc.info/gems/sfml3-rb). The gem also ships RBS type signatures
12
- (`sig/**/*.rbs`) alongside the extension sources, for IDE completion (Solargraph, RubyMine) and
13
- static type-checking (Sorbet, Steep).
14
-
15
- ## Install
5
+ [![Ruby](https://img.shields.io/badge/ruby-3.1%2B-red?style=flat-square)](https://www.ruby-lang.org/)
6
+ [![Test](https://img.shields.io/github/actions/workflow/status/algaves/sfml3.rb/test.yaml?style=flat-square)](https://img.shields.io/github/actions/workflow/status/algaves/sfml3.rb/test.yaml?style=flat-square)
7
+ [![Check](https://img.shields.io/github/actions/workflow/status/algaves/sfml3.rb/check.yaml?style=flat-square)](https://img.shields.io/github/actions/workflow/status/algaves/sfml3.rb/check.yaml?style=flat-square)
8
+ [![Docs](https://img.shields.io/badge/docs-GitHub%20Pages-4c9a2a?style=flat-square)](https://algaves.github.io/sfml3.rb/)
9
+ [![Gem Version](https://img.shields.io/gem/v/sfml3-rb?style=flat-square)](https://rubygems.org/gems/sfml3-rb)
10
+ [![Gem Downloads](https://img.shields.io/gem/dt/sfml3-rb?style=flat-square)](https://rubygems.org/gems/sfml3-rb)
11
+ [![License](https://img.shields.io/badge/license-0BSD-green?style=flat-square)](LICENSE.md)
12
+
13
+ Latest release: **0.3.1**, bound against **CSFML 3**.
14
+
15
+ ## Features
16
+
17
+ * **Broad coverage of SFML 3**, bound through CSFML: windows and events, graphics, audio, network,
18
+ and the system layer, with every `sf*` entry point tracked in [TODO.md](TODO.md).
19
+ * **Precompiled binary gems** for common platforms, with FreeType, SFML 3 and CSFML 3 statically
20
+ linked in — no toolchain and nothing to install system-wide.
21
+ * **A source fallback everywhere else**, which downloads and builds the pinned, checksum-verified
22
+ dependencies at install time, so the gem works on macOS, ARM and the BSDs out of the box.
23
+ * **Complete API documentation and types**: every class, module, method and constant is documented
24
+ on the [docs site](https://algaves.github.io/sfml3.rb/) and covered by RBS signatures shipped in
25
+ the gem.
26
+ * **A close fit to SFML's own model**: classes mirror the C++ types (WindowBase, Window,
27
+ RenderWindow, Texture, Sprite, Sound, ...) minus the parts that only exist in C++, like
28
+ `std::string` and exceptions.
29
+
30
+ ## Table of Contents
31
+
32
+ * [Installation](#installation)
33
+ * [Quick Start](#quick-start)
34
+ * [Documentation](#documentation)
35
+ * [Development](#development)
36
+ * [Contributing](#contributing)
37
+ * [Acknowledgements](#acknowledgements)
38
+ * [License](#license)
39
+
40
+ ## Installation
16
41
 
17
42
  ```sh
18
43
  gem install sfml3-rb
@@ -29,11 +54,18 @@ already linked in — no toolchain, no build, nothing to install system-wide:
29
54
  | `x86-linux-musl` | 3.1 – 4.0 | 32-bit musl |
30
55
  | `x64-mingw-ucrt` | 3.1 – 4.0 | 64-bit Windows, RubyInstaller 3.1+ |
31
56
  | `x86-mingw32` | 3.1 – **3.4** | 32-bit Windows |
32
- | `aarch64-linux-gnu`, `x86_64-darwin`, `arm64-darwin` | 3.1 – 4.0 | experimental, not yet built |
57
+ | `aarch64-linux-gnu` | 3.1 – 4.0 | experimental, cross-built and run on a native arm64 CI runner |
58
+ | `aarch64-linux-musl`, `arm-linux-gnu`, `arm-linux-musl` | 3.1 – 4.0 | experimental, not yet built |
59
+ | `aarch64-mingw-ucrt` | 3.4 – **4.0** | experimental, 64-bit Windows on ARM |
60
+ | `x86_64-darwin`, `arm64-darwin` | 3.1 – 4.0 | experimental, not yet built |
33
61
 
34
- Each gem carries one extension per Ruby ABI. Two gaps come from upstream rather than from this
35
- project: **RubyInstaller publishes no 32-bit Ruby 4.0**, so `x86-mingw32` stops at 3.4; and 64-bit
36
- Windows before Ruby 3.1 used a different platform (`x64-mingw32`), which is not built.
62
+ Each gem carries one extension per Ruby ABI. Three gaps come from upstream rather than from this
63
+ project: **RubyInstaller publishes no 32-bit Ruby 4.0**, so `x86-mingw32` stops at 3.4; 64-bit
64
+ Windows before Ruby 3.1 used a different platform (`x64-mingw32`), which is not built; and the
65
+ cross-compilation image for `aarch64-mingw-ucrt` carries no cross Ruby older than 3.4, so that
66
+ gem has no floor below it.
67
+
68
+ ### Building from source
37
69
 
38
70
  Anywhere else — macOS, ARM, the BSDs — RubyGems falls back to the source gem, which downloads and
39
71
  builds FreeType, SFML 3 and CSFML 3 from pinned, checksum-verified tarballs at install time. That
@@ -42,36 +74,39 @@ takes a few minutes and needs:
42
74
  * Ruby >= 3.1
43
75
  * A C/C++ toolchain and CMake >= 3.22
44
76
  * On Linux, the X11/udev/OpenGL development headers SFML links against — these can't be bundled.
45
- On Fedora:
46
77
 
47
- ```sh
48
- sudo dnf install cmake gcc-c++ libX11-devel \
49
- libXrandr-devel libXcursor-devel libXi-devel systemd-devel libglvnd-devel
50
- ```
78
+ On Fedora:
79
+
80
+ ```sh
81
+ sudo dnf install cmake gcc-c++ libX11-devel \
82
+ libXrandr-devel libXcursor-devel libXi-devel systemd-devel libglvnd-devel
83
+ ```
51
84
 
52
- or on Debian/Ubuntu:
85
+ On Debian/Ubuntu:
53
86
 
54
- ```sh
55
- sudo apt-get install cmake build-essential libx11-dev \
56
- libxrandr-dev libxcursor-dev libxi-dev libudev-dev libgl1-mesa-dev
57
- ```
87
+ ```sh
88
+ sudo apt-get install cmake build-essential libx11-dev \
89
+ libxrandr-dev libxcursor-dev libxi-dev libudev-dev libgl1-mesa-dev
90
+ ```
58
91
 
59
92
  Each installed gem version builds its own copy; there's no build cache shared across versions.
60
93
 
94
+ ### Linking against system libraries
95
+
61
96
  To link against a system CSFML 3 instead (no download, no build):
62
97
 
63
98
  ```sh
64
99
  gem install sfml3-rb -- --enable-system-libraries
65
100
  ```
66
101
 
67
- ## Usage
102
+ ## Quick Start
68
103
 
69
104
  ```ruby
70
105
  require 'sfml'
71
106
  include SFML
72
107
 
73
108
  window = Window.new VideoMode.new(640, 480, 32), 'SFML'
74
- event = Event.new
109
+ event = Event.new
75
110
 
76
111
  while window.is_open?
77
112
  while window.poll_event! event
@@ -83,7 +118,37 @@ while window.is_open?
83
118
  end
84
119
  ```
85
120
 
86
- See [`test/hello-world.rb`](test/hello-world.rb) for a fuller example with shapes and transforms.
121
+ Event types are strings (`'closed'`, `'resized'`, `'key-pressed'`, ...); keys and buttons are enums.
122
+
123
+ See [`test/hello-world.rb`](test/hello-world.rb) for a fuller example with shapes and transforms,
124
+ and [`test/matrix-transformable.rb`](test/matrix-transformable.rb) for a visual demo. Neither is
125
+ part of the test suite.
126
+
127
+ ## Documentation
128
+
129
+ * [API reference](https://algaves.github.io/sfml3.rb/) — every class, module, method and constant,
130
+ built from the YARD comments in `ext/**/*.c` and deployed to GitHub Pages by CI. The same docs
131
+ are also generated on [RubyDoc.info](https://rubydoc.info/gems/sfml3-rb).
132
+ * RBS type signatures (`sig/**/*.rbs`) describe the whole API, including the native classes, for
133
+ RBS-aware editors. `rake rbs` validates the signatures and `rake steep` type-checks `lib/`
134
+ against them.
135
+ * [CHANGELOG.md](CHANGELOG.md) — what changed in each release.
136
+ * [TODO.md](TODO.md) — module-by-module porting coverage and what is deliberately unbound.
137
+
138
+ ### IDE setup (RubyMine)
139
+
140
+ `sig/**/*.rbs` is the only machine-readable description of the API: the native extension cannot be
141
+ introspected, so an editor either reads the signatures or sees nothing. RBS support lives in
142
+ **RubyMine** (and IntelliJ IDEA Ultimate with the Ruby plugin); CLion and other C/C++ IDEs show
143
+ `.rbs` files as plain text.
144
+
145
+ 1. Open the project in RubyMine and point **Settings → Languages & Frameworks → Ruby SDK** at the
146
+ interpreter you build against (Ruby 3.1+). Keep the C sources in CLion/clangd.
147
+ 2. Run `bundle install` so the `rbs` gem (3.2+) is available to that interpreter.
148
+ 3. RubyMine indexes `sig/` automatically; completion, type info (`Ctrl+Shift+P`), parameter info
149
+ and *Navigate → Type Signature* then work for `Window.new` and the rest of the API.
150
+ 4. For a full type check, run `steep check` from *Run anything* (`Ctrl` twice); `Steepfile` points
151
+ it at `lib/` and `sig/`.
87
152
 
88
153
  ## Development
89
154
 
@@ -94,6 +159,7 @@ rake test # compile, then run the test suite
94
159
  rake gem # build the source gem into pkg/
95
160
  rake yard # build API docs into doc/
96
161
  rake rbs # validate sig/**/*.rbs
162
+ rake steep # type-check lib/ against sig/**/*.rbs
97
163
  ```
98
164
 
99
165
  `rake githooks:install` points your checkout at the committed `.githooks/` pre-commit hook, which
@@ -109,9 +175,12 @@ side by side: `core/` (CSFML umbrella header, macros, exceptions, UTF-32 convers
109
175
  devices), `graphics/` (shapes, Color, Transform, View, Texture, Text, Shader, the render targets),
110
176
  `audio/` and `network/`. Includes are subsystem-relative, e.g. `#include "graphics/circle.h"`.
111
177
 
112
- Two `.inc` files hold method bodies shared by several classes and are included once per class with
113
- a different macro prefix: `audio/sound_source.inc` (Sound, Music, SoundStream) and
114
- `graphics/render_target.inc` (Window, RenderTexture).
178
+ Three `.inc` files hold method bodies shared by several classes and are included once per class
179
+ with a different macro prefix: `audio/sound_source.inc` (Sound, Music, SoundStream),
180
+ `window/window_base.inc` (WindowBase, Window) and `graphics/render_target.inc` (Window,
181
+ RenderTexture). `SFML::RenderWindow < SFML::Window < SFML::WindowBase` and includes the
182
+ `SFML::RenderTarget` module, so a drawable's `#draw` accepts a `RenderWindow` or a
183
+ `RenderTexture` directly; `SFML::Target` remains as the legacy generic wrapper.
115
184
 
116
185
  Note that mkmf flattens object files to their basenames, so every `.c` filename has to stay
117
186
  unique across the whole tree — and that `$srcs` is baked into the generated Makefile, so after
@@ -138,9 +207,31 @@ mingw toolchain and the osxcross SDK already provide.
138
207
  Binary gems carry one extension per Ruby ABI under `lib/sfml/<major.minor>/`; `lib/sfml.rb` prefers
139
208
  that and falls back to the single `lib/sfml/sfml_ext.so` a source build installs.
140
209
 
210
+ ## Contributing
211
+
212
+ Bug reports and pull requests are welcome on
213
+ [GitHub](https://github.com/algaves/sfml3.rb/issues). Before opening a pull request:
214
+
215
+ ```sh
216
+ bundle install
217
+ bundle exec rake test # build the extension and run the suite
218
+ bundle exec rubocop # lint Ruby (CI enforces this)
219
+ ```
220
+
221
+ Install the pre-commit hook with `bundle exec rake githooks:install` so staged Ruby is linted and
222
+ staged C is formatted automatically. The C build is warning-clean under `SFML_STRICT=1`; keep it
223
+ that way.
224
+
225
+ ## Acknowledgements
226
+
227
+ This gem would not exist without [SFML](https://www.sfml-dev.org/) and its C binding,
228
+ [CSFML](https://github.com/SFML/CSFML), both maintained by the SFML team. The source build also
229
+ vendors and links FreeType, Ogg, Vorbis and FLAC; see [`ext/ports.rb`](ext/ports.rb) and the
230
+ [LICENSE](LICENSE.md) for their terms.
231
+
141
232
  ## License
142
233
 
143
- [0BSD](LICENSE.md)
234
+ This project is licensed under the BSD Zero Clause License (0BSD) - see the [LICENSE](LICENSE.md) file for details.
144
235
 
145
236
  ---
146
237
 
data/TODO.md CHANGED
@@ -51,9 +51,14 @@ Base module: time, vectors, clocks, streams.
51
51
 
52
52
  OpenGL-based windows, events, input handling.
53
53
 
54
- - [x] **Window** — `SFML::Window` (`ext/window/window.c`); wraps `sfRenderWindow`, so this single
55
- class covers what SFML splits into `WindowBase` + `Window` + `RenderWindow`. Accepts style,
56
- state and `ContextSettings`; exposes min/max size, icon, cursor, native handle, settings.
54
+ - [x] **WindowBase** — `SFML::WindowBase` (`ext/window/window_base.c`); wraps `sfWindowBase`, an OS
55
+ window and event queue with no OpenGL context. The methods shared with `Window` are generated
56
+ from `ext/window/window_base.inc`.
57
+ - [x] **Window** — `SFML::Window` (`ext/window/window.c`); wraps `sfRenderWindow` and derives from
58
+ `WindowBase`, overriding every base method with the matching `sfRenderWindow_*` entry point.
59
+ Accepts style, state and `ContextSettings`; exposes min/max size, icon, cursor, native handle,
60
+ settings, display, and the render-target surface. Deliberately still renderable, so existing
61
+ `Window.new(...).clear` code keeps working.
57
62
  - [x] **VideoMode** — `SFML::VideoMode` (`ext/window/video_mode.c`); includes `desktop_mode` and
58
63
  `fullscreen_modes`
59
64
  - [x] **Event** — `SFML::Event` (`ext/window/event.c`, `ext/window/event_name.c`); every payload is
@@ -87,13 +92,16 @@ OpenGL-based windows, events, input handling.
87
92
  - [x] **Drawable** — `SFML::Drawable` mixin (`ext/graphics/drawable.c`)
88
93
  - [x] **RenderStates** — `SFML::RenderState` (`ext/graphics/render_state.c`); blend mode, stencil
89
94
  mode, coordinate type, texture, shader and transform are all settable
90
- - [x] **RenderTarget** — `SFML::Target` (`ext/graphics/target.c`) dispatches to `sfRenderWindow_*`
91
- or `sfRenderTexture_*` at runtime for `Drawable#draw`. The methods each concrete target owns
92
- directly — `map_pixel_to_coords`, `map_coords_to_pixel`, `push_gl_states`, `pop_gl_states`,
95
+ - [x] **RenderTarget** — `SFML::RenderTarget` module (`ext/graphics/target.c`), included by
96
+ `RenderWindow` and `RenderTexture`, so a drawable's `#draw` accepts either directly. The
97
+ methods — `map_pixel_to_coords`, `map_coords_to_pixel`, `push_gl_states`, `pop_gl_states`,
93
98
  `reset_gl_states`, `draw_primitives`, `draw_vertex_buffer_range`, `clear_stencil`,
94
99
  `clear_color_and_stencil`, `viewport`, `scissor`, `srgb?` — are generated once for both
95
- `Window` and `RenderTexture` from `ext/graphics/render_target.inc`
96
- - [x] **RenderWindow** — folded into `SFML::Window` (see Window module above)
100
+ `Window` and `RenderTexture` from `ext/graphics/render_target.inc`. `SFML::Target` remains
101
+ as the legacy runtime-dispatch wrapper for `Drawable#draw`.
102
+ - [x] **RenderWindow** — `SFML::RenderWindow` (`ext/graphics/render_window.c`); derives from
103
+ `Window` and includes `RenderTarget`. Creation, events and the window surface come from
104
+ `Window` / `WindowBase`.
97
105
  - [x] **RenderTexture** — `SFML::RenderTexture` (`ext/graphics/render_texture.c`)
98
106
  - [x] **View** — `SFML::View` (`ext/graphics/view.c`); including `View.from_rect` and
99
107
  `scissor`/`scissor=`
@@ -179,9 +187,8 @@ without re-deriving the reasoning each time.
179
187
 
180
188
  | Symbols | Why |
181
189
  | --- | --- |
182
- | `sfWindow_*`, `sfWindowBase_*` (~55 functions) | `SFML::Window` wraps `sfRenderWindow`, which subsumes both a plain window and a base window. |
183
- | `sfMouse_*WindowBase`, `sfTouch_getPositionWindowBase` | Superseded by the `*RenderWindow` forms, which need no downcast. |
184
- | `sfRenderWindow_create`, `sfText_getString`/`setString`, `sfRenderWindow_setTitle`, `sfFtpDirectoryResponse_getDirectory` | Superseded by their `*Unicode` counterparts; the narrow forms decode through the C locale and mangle non-ASCII. |
190
+ | `sfWindow_*` (~26 functions) | A plain `sfWindow` (an OpenGL context with no render-target surface); `SFML::Window` wraps `sfRenderWindow` and `SFML::WindowBase` wraps `sfWindowBase`. |
191
+ | `sfRenderWindow_create`, `sfWindowBase_create`, `sfText_getString`/`setString`, `sfRenderWindow_setTitle`, `sfWindowBase_setTitle`, `sfFtpDirectoryResponse_getDirectory` | Superseded by their `*Unicode` counterparts; the narrow forms decode through the C locale and mangle non-ASCII. |
185
192
  | `sfColor_add`/`subtract`/`modulate`/`fromRGB`/`fromRGBA`/`fromInteger`/`toInteger`, `sfIntRect_contains`/`intersects` | Reimplemented directly in C in `color.c` / `rect.c`; the Ruby methods exist. |
186
193
  | `sfSprite_getTexture`, `sfText_getFont`, `sf*Shape_getTexture` | The Ruby getters return the cached wrapper object. CSFML returns a non-owning pointer, so re-wrapping it would hand Ruby an object it must not free. |
187
194
  | `sfShape_getPoint`, `sfShape_getPointCount` | `SFML::Shape` reads these from the Ruby subclass, which is where they are defined. |
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/sfml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SFML
4
- VERSION = '0.2.2'
4
+ VERSION = '0.3.1'
5
5
  end
@@ -0,0 +1,30 @@
1
+ module SFML
2
+ module SoundStatus
3
+ STOPPED: Integer
4
+ PAUSED: Integer
5
+ PLAYING: Integer
6
+ end
7
+
8
+ module SoundChannel
9
+ UNSPECIFIED: Integer
10
+ MONO: Integer
11
+ FRONT_LEFT: Integer
12
+ FRONT_RIGHT: Integer
13
+ FRONT_CENTER: Integer
14
+ FRONT_LEFT_OF_CENTER: Integer
15
+ FRONT_RIGHT_OF_CENTER: Integer
16
+ LOW_FREQUENCY_EFFECTS: Integer
17
+ BACK_LEFT: Integer
18
+ BACK_RIGHT: Integer
19
+ BACK_CENTER: Integer
20
+ SIDE_LEFT: Integer
21
+ SIDE_RIGHT: Integer
22
+ TOP_CENTER: Integer
23
+ TOP_FRONT_LEFT: Integer
24
+ TOP_FRONT_RIGHT: Integer
25
+ TOP_FRONT_CENTER: Integer
26
+ TOP_BACK_LEFT: Integer
27
+ TOP_BACK_RIGHT: Integer
28
+ TOP_BACK_CENTER: Integer
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ module SFML
2
+ module Listener
3
+ def self.global_volume: () -> Float
4
+ def self.global_volume=: (Float value) -> Float
5
+ def self.position: () -> Vector3
6
+ def self.position=: (Vector3 value) -> Vector3
7
+ def self.direction: () -> Vector3
8
+ def self.direction=: (Vector3 value) -> Vector3
9
+ def self.velocity: () -> Vector3
10
+ def self.velocity=: (Vector3 value) -> Vector3
11
+ def self.up_vector: () -> Vector3
12
+ def self.up_vector=: (Vector3 value) -> Vector3
13
+ def self.cone: () -> SoundSourceCone
14
+ def self.cone=: (SoundSourceCone value) -> SoundSourceCone
15
+ end
16
+ end
@@ -0,0 +1,56 @@
1
+ module SFML
2
+ class Music
3
+ def self.from_file: (String path) -> Music
4
+ def self.from_memory: (String data) -> Music
5
+ def self.from_stream: (untyped stream) -> Music
6
+
7
+ def duration: () -> Time
8
+ def channel_count: () -> Integer
9
+ def sample_rate: () -> Integer
10
+ def channel_map: () -> Array[Symbol]
11
+ def loop_points: () -> [Time, Time]
12
+ def loop_points=: ([Time, Time] value) -> [Time, Time]
13
+
14
+ def play: () -> self
15
+ def pause: () -> self
16
+ def stop: () -> self
17
+ def status: () -> (:stopped | :paused | :playing)
18
+ def looping?: () -> bool
19
+ def looping=: (bool value) -> bool
20
+ def pitch: () -> Float
21
+ def pitch=: (Float value) -> Float
22
+ def pan: () -> Float
23
+ def pan=: (Float value) -> Float
24
+ def volume: () -> Float
25
+ def volume=: (Float value) -> Float
26
+ def spatialization_enabled?: () -> bool
27
+ def spatialization_enabled=: (bool value) -> bool
28
+ def position: () -> Vector3
29
+ def position=: (Vector3 value) -> Vector3
30
+ def direction: () -> Vector3
31
+ def direction=: (Vector3 value) -> Vector3
32
+ def velocity: () -> Vector3
33
+ def velocity=: (Vector3 value) -> Vector3
34
+ def cone: () -> SoundSourceCone
35
+ def cone=: (SoundSourceCone value) -> SoundSourceCone
36
+ def doppler_factor: () -> Float
37
+ def doppler_factor=: (Float value) -> Float
38
+ def directional_attenuation_factor: () -> Float
39
+ def directional_attenuation_factor=: (Float value) -> Float
40
+ def relative_to_listener?: () -> bool
41
+ def relative_to_listener=: (bool value) -> bool
42
+ def min_distance: () -> Float
43
+ def min_distance=: (Float value) -> Float
44
+ def max_distance: () -> Float
45
+ def max_distance=: (Float value) -> Float
46
+ def min_gain: () -> Float
47
+ def min_gain=: (Float value) -> Float
48
+ def max_gain: () -> Float
49
+ def max_gain=: (Float value) -> Float
50
+ def attenuation: () -> Float
51
+ def attenuation=: (Float value) -> Float
52
+ def playing_offset: () -> Time
53
+ def playing_offset=: (Time value) -> Time
54
+ def effect_processor=: (Proc proc) -> Proc
55
+ end
56
+ end
@@ -0,0 +1,51 @@
1
+ module SFML
2
+ class Sound
3
+ def initialize: (SoundBuffer buffer) -> void
4
+
5
+ def copy: () -> Sound
6
+ def buffer: () -> SoundBuffer
7
+ def buffer=: (SoundBuffer value) -> SoundBuffer
8
+
9
+ def play: () -> self
10
+ def pause: () -> self
11
+ def stop: () -> self
12
+ def status: () -> (:stopped | :paused | :playing)
13
+ def looping?: () -> bool
14
+ def looping=: (bool value) -> bool
15
+ def pitch: () -> Float
16
+ def pitch=: (Float value) -> Float
17
+ def pan: () -> Float
18
+ def pan=: (Float value) -> Float
19
+ def volume: () -> Float
20
+ def volume=: (Float value) -> Float
21
+ def spatialization_enabled?: () -> bool
22
+ def spatialization_enabled=: (bool value) -> bool
23
+ def position: () -> Vector3
24
+ def position=: (Vector3 value) -> Vector3
25
+ def direction: () -> Vector3
26
+ def direction=: (Vector3 value) -> Vector3
27
+ def velocity: () -> Vector3
28
+ def velocity=: (Vector3 value) -> Vector3
29
+ def cone: () -> SoundSourceCone
30
+ def cone=: (SoundSourceCone value) -> SoundSourceCone
31
+ def doppler_factor: () -> Float
32
+ def doppler_factor=: (Float value) -> Float
33
+ def directional_attenuation_factor: () -> Float
34
+ def directional_attenuation_factor=: (Float value) -> Float
35
+ def relative_to_listener?: () -> bool
36
+ def relative_to_listener=: (bool value) -> bool
37
+ def min_distance: () -> Float
38
+ def min_distance=: (Float value) -> Float
39
+ def max_distance: () -> Float
40
+ def max_distance=: (Float value) -> Float
41
+ def min_gain: () -> Float
42
+ def min_gain=: (Float value) -> Float
43
+ def max_gain: () -> Float
44
+ def max_gain=: (Float value) -> Float
45
+ def attenuation: () -> Float
46
+ def attenuation=: (Float value) -> Float
47
+ def playing_offset: () -> Time
48
+ def playing_offset=: (Time value) -> Time
49
+ def effect_processor=: (Proc proc) -> Proc
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ module SFML
2
+ class SoundBuffer
3
+ def self.from_file: (String path) -> SoundBuffer
4
+ def self.from_memory: (String data) -> SoundBuffer
5
+ def self.from_stream: (untyped stream) -> SoundBuffer
6
+ def self.from_samples: (Array[Integer] | String samples, Integer channel_count, Integer sample_rate, ?Array[Symbol] channel_map) -> SoundBuffer
7
+
8
+ def copy: () -> SoundBuffer
9
+ def save_to_file: (String path) -> bool
10
+ def samples: () -> Array[Integer]
11
+ def sample_count: () -> Integer
12
+ def sample_rate: () -> Integer
13
+ def channel_count: () -> Integer
14
+ def channel_map: () -> Array[Symbol]
15
+ def duration: () -> Time
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module SFML
2
+ class SoundBufferRecorder
3
+ def initialize: () -> void
4
+
5
+ def start: (Integer sample_rate) -> bool
6
+ def stop: () -> self
7
+ def sample_rate: () -> Integer
8
+ def buffer: () -> SoundBuffer
9
+ def device: () -> String
10
+ def device=: (String value) -> bool
11
+ def channel_count: () -> Integer
12
+ def channel_count=: (Integer value) -> Integer
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module SFML
2
+ class SoundRecorder
3
+ def initialize: () -> void
4
+ def self.available?: () -> bool
5
+ def self.available_devices: () -> Array[String]
6
+ def self.default_device: () -> String?
7
+
8
+ def start: (Integer sample_rate) -> bool
9
+ def stop: () -> self
10
+ def sample_rate: () -> Integer
11
+ def device: () -> String?
12
+ def device=: (String value) -> bool
13
+ def channel_count: () -> Integer
14
+ def channel_count=: (Integer value) -> Integer
15
+ def channel_map: () -> Array[Symbol]
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module SFML
2
+ class SoundSourceCone
3
+ def initialize: (Float inner_angle, Float outer_angle, Float outer_gain) -> void
4
+
5
+ def inner_angle: () -> Float
6
+ def inner_angle=: (Float value) -> Float
7
+ def outer_angle: () -> Float
8
+ def outer_angle=: (Float value) -> Float
9
+ def outer_gain: () -> Float
10
+ def outer_gain=: (Float value) -> Float
11
+ def to_a: () -> [Float, Float, Float]
12
+ def ==: (untyped other) -> bool
13
+ end
14
+ end