Add Sdl type

This commit is contained in:
Dan Spencer
2015-02-21 21:42:58 -07:00
parent a30799babd
commit 2a5ce5f1bf
8 changed files with 106 additions and 33 deletions
+1 -1
View File
@@ -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
View File
@@ -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();
}
+1 -3
View File
@@ -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();
}
+1 -3
View File
@@ -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();
}
+1 -3
View File
@@ -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();
}
+1 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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();
}