From aa97010889b1065f151a8e659a35cd982ac17df4 Mon Sep 17 00:00:00 2001 From: werecat Date: Fri, 8 Jan 2016 22:34:44 -0500 Subject: [PATCH] Added Sdl2ImageContext to automatically manage quitting sdl2_image. It runs IMG_Quit on drop instead of a user having to do it manually. I also changed the init function to handle errors internally instead of making a user have to write their own. --- src/demo/video.rs | 4 +--- src/sdl2_image/lib.rs | 55 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/demo/video.rs b/src/demo/video.rs index 3671114a..368617f4 100644 --- a/src/demo/video.rs +++ b/src/demo/video.rs @@ -8,7 +8,7 @@ pub fn main(png: &Path) { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); - sdl2_image::init(INIT_PNG | INIT_JPG); + let _image_context = sdl2_image::init(INIT_PNG | INIT_JPG).unwrap(); let window = video_subsystem.window("rust-sdl2 demo: Video", 800, 600) .position_centered() .build() @@ -30,6 +30,4 @@ pub fn main(png: &Path) { } } } - - sdl2_image::quit(); } diff --git a/src/sdl2_image/lib.rs b/src/sdl2_image/lib.rs index 61c79cd2..339fd3da 100755 --- a/src/sdl2_image/lib.rs +++ b/src/sdl2_image/lib.rs @@ -51,6 +51,27 @@ bitflags! { } } +// This is used for error message for init +impl ToString for InitFlag { + fn to_string(&self) -> String { + let mut string = "".to_string(); + if self.contains(INIT_JPG) { + string = string + &"INIT_JPG ".to_string(); + } + if self.contains(INIT_PNG) { + string = string + &"INIT_PNG ".to_string(); + } + if self.contains(INIT_TIF) { + string = string + &"INIT_TIF ".to_string(); + } + if self.contains(INIT_WEBP) { + string = string + &"INIT_WEBP ".to_string(); + } + string + } +} + + /// Static method extensions for creating Surfaces pub trait LoadSurface: Sized { // Self is only returned here to type hint to the compiler. @@ -138,18 +159,34 @@ impl<'a> LoadTexture for Renderer<'a> { } } -pub fn init(flags: InitFlag) -> InitFlag { - //! Initializes SDL2_image with InitFlags and returns which - //! InitFlags were actually used. - unsafe { - let used = ffi::IMG_Init(flags.bits() as c_int); - InitFlag::from_bits_truncate(used as u32) +/// Context manager for sdl2_image to manage quiting. Can't do much with it but +/// keep it alive while you are using it. +pub struct Sdl2ImageContext; + +impl Drop for Sdl2ImageContext { + fn drop(&mut self) { + unsafe { ffi::IMG_Quit(); } } } -pub fn quit() { - //! Teardown the SDL2_Image subsystem - unsafe { ffi::IMG_Quit(); } +pub fn init(flags: InitFlag) -> SdlResult { + //! Initializes SDL2_image with InitFlags. + //! If not every flag is set it returns an error + let return_flags = unsafe { + let used = ffi::IMG_Init(flags.bits() as c_int); + InitFlag::from_bits_truncate(used as u32) + }; + if !flags.intersects(return_flags) { + // According to docs, error message text is not always set + if get_error() == sdl2::ErrorMessage("".to_string()) { + let un_init_flags = return_flags ^ flags; + let error_str = &("Could not init: ".to_string() + &un_init_flags.to_string()); + sdl2::set_error(error_str); + } + Err(get_error()) + } else { + Ok(Sdl2ImageContext) + } } pub fn get_linked_version() -> Version {