mirror of
https://github.com/encounter/rust-sdl2.git
synced 2026-07-10 21:18:41 -07:00
Add Sdl type
This commit is contained in:
@@ -20,7 +20,7 @@ impl AudioCallback<f32> for MyCallback {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
sdl2::init(sdl2::INIT_AUDIO);
|
||||
let _sdl_context = sdl2::init(sdl2::INIT_AUDIO).unwrap();
|
||||
|
||||
let desired_spec = AudioSpecDesired {
|
||||
freq: 44100,
|
||||
|
||||
+1
-3
@@ -8,7 +8,7 @@ use sdl2::event::Event::{Quit, KeyDown};
|
||||
use sdl2::keycode::KeyCode;
|
||||
|
||||
pub fn main() {
|
||||
sdl2::init(sdl2::INIT_VIDEO);
|
||||
let sdl_context = sdl2::init(sdl2::INIT_VIDEO).unwrap();
|
||||
|
||||
let window = match Window::new("rust-sdl2 demo: Video", WindowPos::PosCentered, WindowPos::PosCentered, 800, 600, OPENGL) {
|
||||
Ok(window) => window,
|
||||
@@ -36,6 +36,4 @@ pub fn main() {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
sdl2::quit();
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::time::duration::Duration;
|
||||
use std::num::SignedInt;
|
||||
|
||||
fn main() {
|
||||
sdl2::init(sdl2::INIT_GAME_CONTROLLER);
|
||||
let sdl_context = sdl2::init(sdl2::INIT_GAME_CONTROLLER).unwrap();
|
||||
|
||||
let available =
|
||||
match joystick::num_joysticks() {
|
||||
@@ -73,6 +73,4 @@ fn main() {
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
sdl2::quit();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::time::duration::Duration;
|
||||
use std::num::SignedInt;
|
||||
|
||||
fn main() {
|
||||
sdl2::init(sdl2::INIT_JOYSTICK);
|
||||
let sdl_context = sdl2::init(sdl2::INIT_JOYSTICK).unwrap();
|
||||
|
||||
let available =
|
||||
match num_joysticks() {
|
||||
@@ -59,6 +59,4 @@ fn main() {
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
sdl2::quit();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use sdl2::event::Event::{Quit, KeyDown};
|
||||
use sdl2::keycode::KeyCode;
|
||||
|
||||
pub fn main() {
|
||||
sdl2::init(sdl2::INIT_VIDEO);
|
||||
let sdl_context = sdl2::init(sdl2::INIT_VIDEO).unwrap();
|
||||
|
||||
let window = match Window::new("rust-sdl2 demo: Renderer + Texture", WindowPos::PosCentered, WindowPos::PosCentered, 800, 600, OPENGL) {
|
||||
Ok(window) => window,
|
||||
@@ -51,6 +51,4 @@ pub fn main() {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
sdl2::quit();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use sdl2::event::Event::{Quit, KeyDown};
|
||||
use sdl2::keycode::KeyCode;
|
||||
|
||||
pub fn main() {
|
||||
sdl2::init(sdl2::INIT_VIDEO);
|
||||
let sdl_context = sdl2::init(sdl2::INIT_VIDEO).unwrap();
|
||||
|
||||
let window = match Window::new("rust-sdl2 demo: YUV", WindowPos::PosCentered, WindowPos::PosCentered, 800, 600, SHOWN) {
|
||||
Ok(window) => window,
|
||||
@@ -67,6 +67,4 @@ pub fn main() {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
sdl2::quit();
|
||||
}
|
||||
|
||||
+100
-13
@@ -1,4 +1,5 @@
|
||||
use std::ffi::{c_str_to_bytes, CString};
|
||||
use std::marker::{NoCopy, PhantomData};
|
||||
|
||||
use sys::sdl as ll;
|
||||
|
||||
@@ -27,30 +28,116 @@ pub enum Error {
|
||||
|
||||
pub type SdlResult<T> = Result<T, String>;
|
||||
|
||||
pub fn init(flags: InitFlag) -> bool {
|
||||
unsafe {
|
||||
ll::SDL_Init(flags.bits()) == 0
|
||||
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
|
||||
/// Only one Sdl context can be alive at a time.
|
||||
/// Set to false by default (not alive).
|
||||
static IS_SDL_CONTEXT_ALIVE: AtomicBool = ATOMIC_BOOL_INIT;
|
||||
|
||||
/// The SDL context type. Initialize with `sdl2::init()`.
|
||||
///
|
||||
/// From a thread-safety perspective, `Sdl` represents the main thread.
|
||||
/// Only one instance of `Sdl` is allowed per process, and cannot be moved or
|
||||
/// used across non-main threads.
|
||||
///
|
||||
/// As such, `Sdl` is a useful type for ensuring that SDL types that can only
|
||||
/// be used on the main thread are initialized that way.
|
||||
///
|
||||
/// For instance, `SDL_PumpEvents()` is not thread safe, and may only be
|
||||
/// called on the main thread.
|
||||
/// All functionality that calls `SDL_PumpEvents()` is thus put into an
|
||||
/// `EventPump` type, which can only be obtained through `Sdl`.
|
||||
/// This guarantees that the only way to call event-pumping functions is on
|
||||
/// the main thread.
|
||||
pub struct Sdl {
|
||||
_marker: NoCopy
|
||||
}
|
||||
|
||||
impl !Send for Sdl {}
|
||||
impl !Sync for Sdl {}
|
||||
|
||||
impl Sdl {
|
||||
/// Initializes specific SDL subsystems.
|
||||
pub fn init_subsystem(&self, flags: InitFlag) -> SdlResult<Subsystem> {
|
||||
unsafe {
|
||||
if ll::SDL_InitSubSystem(flags.bits()) == 0 {
|
||||
Ok(Subsystem {
|
||||
flags: flags,
|
||||
_marker: PhantomData
|
||||
})
|
||||
} else {
|
||||
Err(get_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the mask of the specified subsystems which have previously been initialized.
|
||||
pub fn was_init(&self, flags: InitFlag) -> InitFlag {
|
||||
unsafe {
|
||||
let raw = ll::SDL_WasInit(flags.bits());
|
||||
flags & InitFlag::from_bits(raw).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_subsystem(flags: InitFlag) -> bool {
|
||||
unsafe {
|
||||
ll::SDL_InitSubSystem(flags.bits()) == 0
|
||||
impl Drop for Sdl {
|
||||
fn drop(&mut self) {
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
let was_alive = IS_SDL_CONTEXT_ALIVE.swap(false, Ordering::Relaxed);
|
||||
assert!(was_alive);
|
||||
|
||||
unsafe { ll::SDL_Quit(); }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn quit_subsystem(flags: InitFlag) {
|
||||
unsafe { ll::SDL_QuitSubSystem(flags.bits()); }
|
||||
/// A RAII value representing initalized SDL subsystems. See `sdl2::Sdl::init_subsystem()`.
|
||||
///
|
||||
/// Subsystem initialization is ref-counted. Once `Subsystem::drop()` is called,
|
||||
/// the specified subsystems' ref-counts are decremented via `SDL_QuitSubSystem`.
|
||||
pub struct Subsystem<'sdl> {
|
||||
flags: InitFlag,
|
||||
_marker: PhantomData<&'sdl Sdl>
|
||||
}
|
||||
|
||||
pub fn quit() {
|
||||
unsafe { ll::SDL_Quit(); }
|
||||
#[unsafe_destructor]
|
||||
impl<'sdl> Drop for Subsystem<'sdl> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { ll::SDL_QuitSubSystem(self.flags.bits()); }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn was_inited(flags: InitFlag) -> InitFlag {
|
||||
/// Initializes the SDL library.
|
||||
/// This must be called before using any other SDL function.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// let sdl_context = sdl2::init(sdl2::INIT_EVERYTHING).unwrap();
|
||||
///
|
||||
/// let mut event_pump = sdl_context.event_pump();
|
||||
/// for event in event_pump.poll_iter() {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// // SDL_Quit() is called here as `sdl_context` is dropped.
|
||||
/// ```
|
||||
pub fn init(flags: InitFlag) -> SdlResult<Sdl> {
|
||||
unsafe {
|
||||
let raw = ll::SDL_WasInit(flags.bits());
|
||||
flags & InitFlag::from_bits(raw).unwrap()
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
// Atomically switch the `IS_SDL_CONTEXT_ALIVE` global to true
|
||||
let was_alive = IS_SDL_CONTEXT_ALIVE.swap(true, Ordering::Relaxed);
|
||||
|
||||
if was_alive {
|
||||
IS_SDL_CONTEXT_ALIVE.swap(false, Ordering::Relaxed);
|
||||
Err(format!("Cannot have more than one `Sdl` in use at the same time"))
|
||||
} else {
|
||||
if ll::SDL_Init(flags.bits()) == 0 {
|
||||
Ok(Sdl { _marker: NoCopy })
|
||||
} else {
|
||||
IS_SDL_CONTEXT_ALIVE.swap(false, Ordering::Relaxed);
|
||||
Err(get_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ extern crate sdl2;
|
||||
|
||||
#[test]
|
||||
fn audio_spec_wav() {
|
||||
sdl2::init(sdl2::INIT_AUDIO);
|
||||
|
||||
let wav = sdl2::audio::AudioSpecWAV::load_wav(&Path::new("./tests/sine.wav")).unwrap();
|
||||
|
||||
assert_eq!(wav.freq, 22050);
|
||||
@@ -14,6 +12,4 @@ fn audio_spec_wav() {
|
||||
|
||||
let buffer = wav.get_buffer();
|
||||
assert_eq!(buffer.len(), 4410);
|
||||
|
||||
sdl2::quit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user