From 75ef7ca5d8748d195068e40a39a5ac305b248ee7 Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 13:04:48 -0700 Subject: [PATCH 1/9] Add error-chain as a dependency --- Cargo.toml | 1 + src/sdl2/lib.rs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 8643914d4d1..2f7d6431ffa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ bitflags = "0.7" libc = "0.2" rand = "0.3" lazy_static="0.2" +error-chain = "0.10" [dependencies.num] version = "0.1" diff --git a/src/sdl2/lib.rs b/src/sdl2/lib.rs index 3b73545d962..6e8068c2535 100644 --- a/src/sdl2/lib.rs +++ b/src/sdl2/lib.rs @@ -11,6 +11,9 @@ extern crate lazy_static; extern crate bitflags; pub extern crate sdl2_sys as sys; +#[macro_use] +extern crate error_chain; + #[cfg(feature = "gfx")] extern crate c_vec; From f9a89d8717767ab08a7217133f94c736f67f6420 Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 13:06:08 -0700 Subject: [PATCH 2/9] Remove a panic! from pixels. This required also updating code in render and surface. Update surrounding code to prefer bail! over explicit Err. --- src/sdl2/pixels.rs | 44 +++++++------- src/sdl2/render.rs | 136 ++++++++++++++++++++++---------------------- src/sdl2/surface.rs | 18 +++--- 3 files changed, 99 insertions(+), 99 deletions(-) diff --git a/src/sdl2/pixels.rs b/src/sdl2/pixels.rs index e41a04c12bb..3ec16118652 100644 --- a/src/sdl2/pixels.rs +++ b/src/sdl2/pixels.rs @@ -26,14 +26,14 @@ impl Palette { match validate_int(capacity as u32, "capacity") { Ok(len) => len, - Err(e) => return Err(format!("{}", e)), + Err(e) => bail!("{}", e), } }; let raw = unsafe { ll::SDL_AllocPalette(ncolors) }; if raw.is_null() { - Err(get_error()) + bail!(get_error()) } else { Ok(Palette { raw: raw, @@ -59,7 +59,7 @@ impl Palette { }; if result < 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(pal) } @@ -240,7 +240,7 @@ impl PixelFormatEnum { }; if result == 0 { // SDL_FALSE - Err(get_error()) + bail!(get_error()) } else { Ok(PixelMasks { bpp: bpp as u8, @@ -267,10 +267,10 @@ impl PixelFormatEnum { } } - pub fn byte_size_of_pixels(&self, num_of_pixels: usize) -> usize { + pub fn byte_size_of_pixels(&self, num_of_pixels: usize) -> Result { match *self { PixelFormatEnum::RGB332 - => num_of_pixels, + => Ok(num_of_pixels), PixelFormatEnum::RGB444 | PixelFormatEnum::RGB555 | PixelFormatEnum::BGR555 | PixelFormatEnum::ARGB4444 | PixelFormatEnum::RGBA4444 | PixelFormatEnum::ABGR4444 | @@ -278,36 +278,36 @@ impl PixelFormatEnum { PixelFormatEnum::RGBA5551 | PixelFormatEnum::ABGR1555 | PixelFormatEnum::BGRA5551 | PixelFormatEnum::RGB565 | PixelFormatEnum::BGR565 - => num_of_pixels * 2, + => Ok(num_of_pixels * 2), PixelFormatEnum::RGB24 | PixelFormatEnum::BGR24 - => num_of_pixels * 3, + => Ok(num_of_pixels * 3), PixelFormatEnum::RGB888 | PixelFormatEnum::RGBX8888 | PixelFormatEnum::BGR888 | PixelFormatEnum::BGRX8888 | PixelFormatEnum::ARGB8888 | PixelFormatEnum::RGBA8888 | PixelFormatEnum::ABGR8888 | PixelFormatEnum::BGRA8888 | PixelFormatEnum::ARGB2101010 - => num_of_pixels * 4, + => Ok(num_of_pixels * 4), // YUV formats // FIXME: rounding error here? PixelFormatEnum::YV12 | PixelFormatEnum::IYUV - => num_of_pixels / 2 * 3, + => Ok(num_of_pixels / 2 * 3), PixelFormatEnum::YUY2 | PixelFormatEnum::UYVY | PixelFormatEnum::YVYU - => num_of_pixels * 2, + => Ok(num_of_pixels * 2), // Unsupported formats PixelFormatEnum::Index8 - => num_of_pixels, + => Ok(num_of_pixels), PixelFormatEnum::Unknown | PixelFormatEnum::Index1LSB | PixelFormatEnum::Index1MSB | PixelFormatEnum::Index4LSB | PixelFormatEnum::Index4MSB - => panic!("not supported format: {:?}", *self), + => bail!("not supported format: {:?}", *self), } } - pub fn byte_size_per_pixel(&self) -> usize { + pub fn byte_size_per_pixel(&self) -> Result { match *self { PixelFormatEnum::RGB332 - => 1, + => Ok(1), PixelFormatEnum::RGB444 | PixelFormatEnum::RGB555 | PixelFormatEnum::BGR555 | PixelFormatEnum::ARGB4444 | PixelFormatEnum::RGBA4444 | PixelFormatEnum::ABGR4444 | @@ -315,28 +315,28 @@ impl PixelFormatEnum { PixelFormatEnum::RGBA5551 | PixelFormatEnum::ABGR1555 | PixelFormatEnum::BGRA5551 | PixelFormatEnum::RGB565 | PixelFormatEnum::BGR565 - => 2, + => Ok(2), PixelFormatEnum::RGB24 | PixelFormatEnum::BGR24 - => 3, + => Ok(3), PixelFormatEnum::RGB888 | PixelFormatEnum::RGBX8888 | PixelFormatEnum::BGR888 | PixelFormatEnum::BGRX8888 | PixelFormatEnum::ARGB8888 | PixelFormatEnum::RGBA8888 | PixelFormatEnum::ABGR8888 | PixelFormatEnum::BGRA8888 | PixelFormatEnum::ARGB2101010 - => 4, + => Ok(4), // YUV formats PixelFormatEnum::YV12 | PixelFormatEnum::IYUV - => 2, + => Ok(2), PixelFormatEnum::YUY2 | PixelFormatEnum::UYVY | PixelFormatEnum::YVYU - => 2, + => Ok(2), // Unsupported formats PixelFormatEnum::Index8 - => 1, + => Ok(1), PixelFormatEnum::Unknown | PixelFormatEnum::Index1LSB | PixelFormatEnum::Index1MSB | PixelFormatEnum::Index4LSB | PixelFormatEnum::Index4MSB - => panic!("not supported format: {:?}", *self), + => bail!("not supported format: {:?}", *self), } } diff --git a/src/sdl2/render.rs b/src/sdl2/render.rs index 266708b7c6c..1c3f4312b05 100644 --- a/src/sdl2/render.rs +++ b/src/sdl2/render.rs @@ -229,7 +229,7 @@ impl RendererContext { if ll::SDL_SetRenderTarget(self.raw, raw_texture) == 0 { Ok(()) } else { - Err(SdlError(get_error())) + bail!(SdlError(get_error())) } } @@ -338,7 +338,7 @@ impl<'s> Canvas> { context: context, }) } else { - Err(get_error()) + bail!(get_error()) } } @@ -496,7 +496,7 @@ impl Canvas { .map_err(|e| TargetRenderError::SdlError(e))?; Ok(()) } else { - Err(TargetRenderError::NotSupported) + bail!(TargetRenderError::NotSupported) } } @@ -571,7 +571,7 @@ impl Canvas { .map_err(|e| TargetRenderError::SdlError(e))?; Ok(()) } else { - Err(TargetRenderError::NotSupported) + bail!(TargetRenderError::NotSupported) } } } @@ -627,7 +627,7 @@ impl CanvasBuilder { let raw = unsafe { ll::SDL_CreateRenderer(self.window.raw(), index, self.renderer_flags) }; if raw.is_null() { - Err(SdlError(get_error())) + bail!(SdlError(get_error())) } else { let context = Rc::new(unsafe { RendererContext::from_ll(raw, self.window.context()) }); Ok(Canvas { @@ -746,11 +746,11 @@ impl TextureCreator { use self::TextureValueError::*; let w = match validate_int(width, "width") { Ok(w) => w, - Err(_) => return Err(WidthOverflows(width)), + Err(_) => bail!(WidthOverflows(width)), }; let h = match validate_int(height, "height") { Ok(h) => h, - Err(_) => return Err(HeightOverflows(height)), + Err(_) => bail!(HeightOverflows(height)), }; let format: PixelFormatEnum = format.into().unwrap_or(self.default_pixel_format); @@ -760,7 +760,7 @@ impl TextureCreator { PixelFormatEnum::YV12 | PixelFormatEnum::IYUV => { if w % 2 != 0 || h % 2 != 0 { - return Err(WidthMustBeMultipleOfTwoForFormat(width, format)); + bail!(WidthMustBeMultipleOfTwoForFormat(width, format)); } } _ => (), @@ -770,7 +770,7 @@ impl TextureCreator { ll::SDL_CreateTexture(self.context.raw, format as uint32_t, access as c_int, w, h) }; if result.is_null() { - Err(SdlError(get_error())) + bail!(SdlError(get_error())) } else { unsafe { Ok(self.raw_create_texture(result)) } } @@ -820,7 +820,7 @@ impl TextureCreator { let result = unsafe { ll::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) }; if result.is_null() { - Err(SdlError(get_error())) + bail!(SdlError(get_error())) } else { unsafe { Ok(self.raw_create_texture(result)) } } @@ -925,7 +925,7 @@ impl Canvas { if result == 0 { Ok((width as u32, height as u32)) } else { - Err(get_error()) + bail!(get_error()) } } @@ -937,7 +937,7 @@ impl Canvas { let result = unsafe { ll::SDL_RenderSetLogicalSize(self.context.raw, width, height) }; match result { 0 => Ok(()), - _ => Err(SdlError(get_error())), + _ => bail!(SdlError(get_error())), } } @@ -1003,7 +1003,7 @@ impl Canvas { pub fn set_scale(&mut self, scale_x: f32, scale_y: f32) -> Result<(), String> { let ret = unsafe { ll::SDL_RenderSetScale(self.context.raw, scale_x, scale_y) }; // Should only fail on an invalid renderer - if ret != 0 { Err(get_error()) } else { Ok(()) } + if ret != 0 { bail!(get_error()) } else { Ok(()) } } /// Gets the drawing scale for the current target. @@ -1020,7 +1020,7 @@ impl Canvas { let point = point.into(); let result = unsafe { ll::SDL_RenderDrawPoint(self.context.raw, point.x(), point.y()) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1036,7 +1036,7 @@ impl Canvas { points.len() as c_int) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1054,7 +1054,7 @@ impl Canvas { ll::SDL_RenderDrawLine(self.context.raw, start.x(), start.y(), end.x(), end.y()) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1070,7 +1070,7 @@ impl Canvas { points.len() as c_int) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1081,7 +1081,7 @@ impl Canvas { pub fn draw_rect(&mut self, rect: Rect) -> Result<(), String> { let result = unsafe { ll::SDL_RenderDrawRect(self.context.raw, rect.raw()) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1096,7 +1096,7 @@ impl Canvas { rects.len() as c_int) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1115,7 +1115,7 @@ impl Canvas { .unwrap_or(ptr::null())) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1131,7 +1131,7 @@ impl Canvas { rects.len() as c_int) }; if result != 0 { - Err(get_error()) + bail!(get_error()) } else { Ok(()) } @@ -1162,7 +1162,7 @@ impl Canvas { }) }; - if ret != 0 { Err(get_error()) } else { Ok(()) } + if ret != 0 { bail!(get_error()) } else { Ok(()) } } /// Copies a portion of the texture to the current rendering target, @@ -1217,7 +1217,7 @@ impl Canvas { flip) }; - if ret != 0 { Err(get_error()) } else { Ok(()) } + if ret != 0 { bail!(get_error()) } else { Ok(()) } } /// Reads pixels from the current rendering target. @@ -1237,8 +1237,8 @@ impl Canvas { } }; - let pitch = w * format.byte_size_per_pixel(); // calculated pitch - let size = format.byte_size_of_pixels(w * h); + let pitch = w * format.byte_size_per_pixel()?; // calculated pitch + let size = format.byte_size_of_pixels(w * h)?; let mut pixels = Vec::with_capacity(size); pixels.set_len(size); @@ -1254,7 +1254,7 @@ impl Canvas { if ret == 0 { Ok(pixels) } else { - Err(get_error()) + bail!(get_error()) } } } @@ -1546,19 +1546,19 @@ impl<'r> Texture<'r> { match rect { Some(r) => { if r.x() % 2 != 0 { - return Err(XMustBeMultipleOfTwoForFormat(r.x(), format)); + bail!(XMustBeMultipleOfTwoForFormat(r.x(), format)); } else if r.y() % 2 != 0 { - return Err(YMustBeMultipleOfTwoForFormat(r.y(), format)); + bail!(YMustBeMultipleOfTwoForFormat(r.y(), format)); } else if r.width() % 2 != 0 { - return Err(WidthMustBeMultipleOfTwoForFormat(r.width(), format)); + bail!(WidthMustBeMultipleOfTwoForFormat(r.width(), format)); } else if r.height() % 2 != 0 { - return Err(HeightMustBeMultipleOfTwoForFormat(r.height(), format)); + bail!(HeightMustBeMultipleOfTwoForFormat(r.height(), format)); } } _ => {} }; if pitch % 2 != 0 { - return Err(PitchMustBeMultipleOfTwoForFormat(pitch, format)); + bail!(PitchMustBeMultipleOfTwoForFormat(pitch, format)); } } _ => {} @@ -1566,7 +1566,7 @@ impl<'r> Texture<'r> { let pitch = match validate_int(pitch as u32, "pitch") { Ok(p) => p, - Err(_) => return Err(PitchOverflows(pitch)), + Err(_) => bail!(PitchOverflows(pitch)), }; let result = unsafe { @@ -1577,7 +1577,7 @@ impl<'r> Texture<'r> { }; if result != 0 { - Err(SdlError(get_error())) + bail!(SdlError(get_error())) } else { Ok(()) } @@ -1607,13 +1607,13 @@ impl<'r> Texture<'r> { match rect { Some(ref r) => { if r.x() % 2 != 0 { - return Err(XMustBeMultipleOfTwoForFormat(r.x())); + bail!(XMustBeMultipleOfTwoForFormat(r.x())); } else if r.y() % 2 != 0 { - return Err(YMustBeMultipleOfTwoForFormat(r.y())); + bail!(YMustBeMultipleOfTwoForFormat(r.y())); } else if r.width() % 2 != 0 { - return Err(WidthMustBeMultipleOfTwoForFormat(r.width())); + bail!(WidthMustBeMultipleOfTwoForFormat(r.width())); } else if r.height() % 2 != 0 { - return Err(HeightMustBeMultipleOfTwoForFormat(r.height())); + bail!(HeightMustBeMultipleOfTwoForFormat(r.height())); } } _ => {} @@ -1630,7 +1630,7 @@ impl<'r> Texture<'r> { }; // The destination rectangle cannot lie outside the texture boundaries if !inside { - return Err(RectNotInsideTexture(r.clone())); + bail!(RectNotInsideTexture(r.clone())); } } @@ -1643,55 +1643,55 @@ impl<'r> Texture<'r> { //let wrong_length = if y_plane.len() != (y_pitch * height) { - return Err(InvalidPlaneLength { - plane: "y", - length: y_plane.len(), - pitch: y_pitch, - height: height, - }); + bail!(InvalidPlaneLength { + plane: "y", + length: y_plane.len(), + pitch: y_pitch, + height: height, + }); } if u_plane.len() != (u_pitch * height / 2) { - return Err(InvalidPlaneLength { - plane: "u", - length: u_plane.len(), - pitch: u_pitch, - height: height / 2, - }); + bail!(InvalidPlaneLength { + plane: "u", + length: u_plane.len(), + pitch: u_pitch, + height: height / 2, + }); } if v_plane.len() != (v_pitch * height / 2) { - return Err(InvalidPlaneLength { - plane: "v", - length: v_plane.len(), - pitch: v_pitch, - height: height / 2, - }); + bail!(InvalidPlaneLength { + plane: "v", + length: v_plane.len(), + pitch: v_pitch, + height: height / 2, + }); } let y_pitch = match validate_int(y_pitch as u32, "y_pitch") { Ok(p) => p, Err(_) => { - return Err(PitchOverflows { + bail!(PitchOverflows { plane: "y", value: y_pitch, - }) + }) } }; let u_pitch = match validate_int(u_pitch as u32, "u_pitch") { Ok(p) => p, Err(_) => { - return Err(PitchOverflows { - plane: "u", - value: u_pitch, - }) + bail!(PitchOverflows { + plane: "u", + value: u_pitch, + }) } }; let v_pitch = match validate_int(v_pitch as u32, "v_pitch") { Ok(p) => p, Err(_) => { - return Err(PitchOverflows { - plane: "v", - value: v_pitch, - }) + bail!(PitchOverflows { + plane: "v", + value: v_pitch, + }) } }; @@ -1706,7 +1706,7 @@ impl<'r> Texture<'r> { v_pitch) }; if result != 0 { - Err(SdlError(get_error())) + bail!(SdlError(get_error())) } else { Ok(()) } @@ -1743,7 +1743,7 @@ impl<'r> Texture<'r> { .byte_size_from_pitch_and_height(pitch as usize, height); Ok((::std::slice::from_raw_parts_mut(pixels as *mut u8, size), pitch)) } else { - Err(get_error()) + bail!(get_error()) } }; diff --git a/src/sdl2/surface.rs b/src/sdl2/surface.rs index aaa17240724..279cab01cbe 100644 --- a/src/sdl2/surface.rs +++ b/src/sdl2/surface.rs @@ -131,13 +131,13 @@ impl<'a> Surface<'a> { pub fn from_pixelmasks(width: u32, height: u32, masks: pixels::PixelMasks) -> Result, String> { unsafe { if width >= (1<<31) || height >= (1<<31) { - Err("Image is too large.".to_owned()) + bail!("Image is too large.".to_owned()) } else { let raw = ll::SDL_CreateRGBSurface(0, width as c_int, height as c_int, masks.bpp as c_int, masks.rmask, masks.gmask, masks.bmask, masks.amask); if raw.is_null() { - Err(get_error()) + bail!(get_error()) } else { Ok(Surface::from_ll(raw)) } @@ -155,16 +155,16 @@ impl<'a> Surface<'a> { pub fn from_data_pixelmasks(data: &'a mut [u8], width: u32, height: u32, pitch: u32, masks: pixels::PixelMasks) -> Result, String> { unsafe { if width >= (1<<31) || height >= (1<<31) { - Err("Image is too large.".to_owned()) + bail!("Image is too large.".to_owned()) } else if pitch >= (1<<31) { - Err("Pitch is too large.".to_owned()) + bail!("Pitch is too large.".to_owned()) } else { let raw = ll::SDL_CreateRGBSurfaceFrom( data.as_mut_ptr() as *mut _, width as c_int, height as c_int, masks.bpp as c_int, pitch as c_int, masks.rmask, masks.gmask, masks.bmask, masks.amask); if raw.is_null() { - Err(get_error()) + bail!(get_error()) } else { Ok(Surface::from_ll(raw)) } @@ -178,7 +178,7 @@ impl<'a> Surface<'a> { }; if raw.is_null() { - Err(get_error()) + bail!(get_error()) } else { Ok( unsafe{ Surface::from_ll(raw) } ) } @@ -327,7 +327,7 @@ impl SurfaceRef { ll::SDL_SaveBMP_RW(self.raw(), rwops.raw(), 0) }; if ret == 0 { Ok(()) } - else { Err(get_error()) } + else { bail!(get_error()) } } pub fn save_bmp>(&self, path: P) -> Result<(), String> { @@ -340,7 +340,7 @@ impl SurfaceRef { match result { 0 => Ok(()), - _ => Err(get_error()) + _ => bail!(get_error()) } } @@ -389,7 +389,7 @@ impl SurfaceRef { if result == 0 { Ok(pixels::Color::from_u32(&self.pixel_format(), key)) } else { - Err(get_error()) + bail!(get_error()) } } From 63362e7cca45a35f2ad6f3d6d916c4a21eaf28a5 Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 14:06:17 -0700 Subject: [PATCH 3/9] Remove panics from joystick --- src/sdl2/joystick.rs | 62 +++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/sdl2/joystick.rs b/src/sdl2/joystick.rs index 8c7cccd63dc..ea552d4d0c7 100644 --- a/src/sdl2/joystick.rs +++ b/src/sdl2/joystick.rs @@ -115,40 +115,40 @@ impl Joystick { unsafe { ll::SDL_JoystickGetAttached(self.raw) != 0 } } - pub fn instance_id(&self) -> i32 { + pub fn instance_id(&self) -> Result { let result = unsafe { ll::SDL_JoystickInstanceID(self.raw) }; if result < 0 { // Should only fail if the joystick is NULL. - panic!(get_error()) + bail!(get_error()) } else { - result + Ok(result) } } /// Retreive the joystick's GUID - pub fn guid(&self) -> Guid { + pub fn guid(&self) -> Result { let raw = unsafe { ll::SDL_JoystickGetGUID(self.raw) }; let guid = Guid { raw: raw }; if guid.is_zero() { // Should only fail if the joystick is NULL. - panic!(get_error()) + bail!(get_error()) } else { - guid + Ok(guid) } } /// Retreive the number of axes for this joystick - pub fn num_axes(&self) -> u32 { + pub fn num_axes(&self) -> Result { let result = unsafe { ll::SDL_JoystickNumAxes(self.raw) }; if result < 0 { // Should only fail if the joystick is NULL. - panic!(get_error()) + bail!(get_error()) } else { - result as u32 + Ok(result as u32) } } @@ -180,14 +180,14 @@ impl Joystick { } /// Retreive the number of buttons for this joystick - pub fn num_buttons(&self) -> u32 { + pub fn num_buttons(&self) -> Result { let result = unsafe { ll::SDL_JoystickNumButtons(self.raw) }; if result < 0 { // Should only fail if the joystick is NULL. - panic!(get_error()) + bail!(get_error()) } else { - result as u32 + Ok(result as u32) } } @@ -221,14 +221,14 @@ impl Joystick { } /// Retreive the number of balls for this joystick - pub fn num_balls(&self) -> u32 { + pub fn num_balls(&self) -> Result { let result = unsafe { ll::SDL_JoystickNumBalls(self.raw) }; if result < 0 { // Should only fail if the joystick is NULL. - panic!(get_error()) + bail!(get_error()) } else { - result as u32 + Ok(result as u32) } } @@ -250,14 +250,14 @@ impl Joystick { } /// Retreive the number of balls for this joystick - pub fn num_hats(&self) -> u32 { + pub fn num_hats(&self) -> Result { let result = unsafe { ll::SDL_JoystickNumHats(self.raw) }; if result < 0 { // Should only fail if the joystick is NULL. - panic!(get_error()) + bail!(get_error()) } else { - result as u32 + Ok(result as u32) } } @@ -365,18 +365,21 @@ impl Display for Guid { /// This is represented in SDL2 as a bitfield but obviously not all /// combinations make sense: 5 for instance would mean up and down at /// the same time... To simplify things I turn it into an enum which -/// is how the SDL2 docs present it anyway (using macros). +/// is how the SDL2 docs present it anyway (using macros). The remaining +/// (unlikely) cases are encoded with the special constructor Unknown +/// which just holds the u8. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub enum HatState { - Centered = 0, - Up = 0x01, - Right = 0x02, - Down = 0x04, - Left = 0x08, - RightUp = 0x02 | 0x01, - RightDown = 0x02 | 0x04, - LeftUp = 0x08 | 0x01, - Leftdown = 0x08 | 0x04, + Centered, + Up, + Right, + Down, + Left, + RightUp, + RightDown, + LeftUp, + Leftdown, + Unknown(u8), } impl HatState { @@ -391,7 +394,7 @@ impl HatState { 6 => HatState::RightDown, 9 => HatState::LeftUp, 12 => HatState::Leftdown, - _ => panic!("Unexpected hat position: {}", raw), + n => HatState::Unknown(n), } } @@ -406,6 +409,7 @@ impl HatState { HatState::RightDown => 6, HatState::LeftUp => 9, HatState::Leftdown => 12, + HatState::Unknown(n) => n, } } From b55b4b9688699543ca9103ef510e666379f318d4 Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 14:49:21 -0700 Subject: [PATCH 4/9] Remove some panics in controller and event --- src/sdl2/controller.rs | 6 +++--- src/sdl2/event.rs | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sdl2/controller.rs b/src/sdl2/controller.rs index 3de44efc6b6..e0aa2716e87 100644 --- a/src/sdl2/controller.rs +++ b/src/sdl2/controller.rs @@ -346,7 +346,7 @@ impl GameController { } /// Return the joystick id of this controller - pub fn instance_id(&self) -> i32 { + pub fn instance_id(&self) -> Result { let result = unsafe { let joystick = ll::SDL_GameControllerGetJoystick(self.raw); ::sys::joystick::SDL_JoystickInstanceID(joystick) @@ -354,9 +354,9 @@ impl GameController { if result < 0 { // Should only fail if the joystick is NULL. - panic!(get_error()) + bail!(get_error()) } else { - result + Ok(result) } } diff --git a/src/sdl2/event.rs b/src/sdl2/event.rs index 3201df37bd9..7e5c0772c5f 100644 --- a/src/sdl2/event.rs +++ b/src/sdl2/event.rs @@ -79,7 +79,7 @@ impl ::EventSubsystem { /// println!("{:?}", event); /// } /// ``` - pub fn peek_events(&self, max_amount: u32) -> B + pub fn peek_events(&self, max_amount: u32) -> Result where B: FromIterator { unsafe { @@ -99,13 +99,13 @@ impl ::EventSubsystem { if result < 0 { // The only error possible is "Couldn't lock event queue" - panic!(get_error()); + bail!(get_error()); } else { events.set_len(result as usize); - events.into_iter().map(|event_raw| { + Ok(events.into_iter().map(|event_raw| { Event::from_ll(event_raw) - }).collect() + }).collect()) } } } @@ -1678,12 +1678,12 @@ unsafe fn poll_event() -> Option { else { None } } -unsafe fn wait_event() -> Event { +unsafe fn wait_event() -> Result { let mut raw = mem::uninitialized(); let success = ll::SDL_WaitEvent(&mut raw) == 1; - if success { Event::from_ll(raw) } - else { panic!(get_error()) } + if success { Ok(Event::from_ll(raw)) } + else { bail!(get_error()) } } unsafe fn wait_event_timeout(timeout: u32) -> Option { @@ -1751,7 +1751,7 @@ impl ::EventPump { } /// Waits indefinitely for the next available event. - pub fn wait_event(&mut self) -> Event { + pub fn wait_event(&mut self) -> Result { unsafe { wait_event() } } @@ -1815,8 +1815,8 @@ pub struct EventWaitIterator<'a> { } impl<'a> Iterator for EventWaitIterator<'a> { - type Item = Event; - fn next(&mut self) -> Option { unsafe { Some(wait_event()) } } + type Item = Result; + fn next(&mut self) -> Option> { unsafe { Some(wait_event()) } } } /// An iterator that calls `EventPump::wait_event_timeout()`. From 17663e4cb8cb3e451fd401502ba14294599d4062 Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 15:27:14 -0700 Subject: [PATCH 5/9] Change From impl for PixelFormat to try_from Curently, TryFrom is unstable only so I put a custom try_from method on the Impl for PixelFormatEnum. --- src/sdl2/pixels.rs | 21 ++++++++++----------- src/sdl2/render.rs | 8 ++++---- src/sdl2/surface.rs | 4 ++-- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/sdl2/pixels.rs b/src/sdl2/pixels.rs index 3ec16118652..907d93105b5 100644 --- a/src/sdl2/pixels.rs +++ b/src/sdl2/pixels.rs @@ -350,24 +350,23 @@ impl PixelFormatEnum { _ => false } } -} - -impl Into for PixelFormatEnum { - fn into(self) -> ll::SDL_PixelFormatEnum { - self as libc::uint32_t - } -} -impl From for PixelFormatEnum { - fn from(pf: PixelFormat) -> PixelFormatEnum { + pub fn try_from(pf: PixelFormat) -> Result { unsafe { let ref sdl_pf = *pf.raw; match PixelFormatEnum::from_u64(sdl_pf.format as u64) { - Some(pfe) => pfe, - None => panic!("Unknown pixel format: {:?}", sdl_pf.format) + Some(pfe) => Ok(pfe), + None => bail!("Unknown pixel format: {:?}", sdl_pf.format) } } } + +} + +impl Into for PixelFormatEnum { + fn into(self) -> ll::SDL_PixelFormatEnum { + self as libc::uint32_t + } } impl FromPrimitive for PixelFormatEnum { diff --git a/src/sdl2/render.rs b/src/sdl2/render.rs index 1c3f4312b05..eb7d078eaab 100644 --- a/src/sdl2/render.rs +++ b/src/sdl2/render.rs @@ -366,11 +366,11 @@ impl<'s> Canvas> { /// /// The target (i.e., `Window`) will not be destroyed and the SDL_Renderer will not be /// destroyed if the `TextureCreator` is still in scope. - pub fn texture_creator(&self) -> TextureCreator> { - TextureCreator { + pub fn texture_creator(&self) -> Result>, String> { + Ok(TextureCreator { context: self.context.clone(), - default_pixel_format: self.surface().pixel_format_enum(), - } + default_pixel_format: self.surface().pixel_format_enum()?, + }) } } diff --git a/src/sdl2/surface.rs b/src/sdl2/surface.rs index 279cab01cbe..a82d5827465 100644 --- a/src/sdl2/surface.rs +++ b/src/sdl2/surface.rs @@ -254,8 +254,8 @@ impl SurfaceRef { } } - pub fn pixel_format_enum(&self) -> pixels::PixelFormatEnum { - pixels::PixelFormatEnum::from(self.pixel_format()) + pub fn pixel_format_enum(&self) -> Result { + pixels::PixelFormatEnum::try_from(self.pixel_format()) } /// Locks a surface so that the pixels can be directly accessed safely. From ea48f78b0889bb308f1a25961efb6aa8632b334b Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 15:52:48 -0700 Subject: [PATCH 6/9] Remove a panic from video --- src/sdl2/video.rs | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/sdl2/video.rs b/src/sdl2/video.rs index 666063bbf19..64d9977bfe8 100644 --- a/src/sdl2/video.rs +++ b/src/sdl2/video.rs @@ -134,16 +134,17 @@ macro_rules! attrs { #[doc = "**Sets** the attribute: "] #[doc = $doc] #[inline] - pub fn $set_property(&self, value: $t) { + pub fn $set_property(&self, value: $t) -> Result<(), String> { gl_set_attribute!($attr_name, value.to_gl_value()); + Ok(()) } #[doc = "**Gets** the attribute: "] #[doc = $doc] #[inline] - pub fn $get_property(&self) -> $t { + pub fn $get_property(&self) -> Result<$t, String> { let value = gl_get_attribute!($attr_name); - GLAttrTypeUtil::from_gl_value(value) + Ok(GLAttrTypeUtil::from_gl_value(value)) } )* ); @@ -207,7 +208,7 @@ pub mod gl_attr { if result != 0 { // Panic and print the attribute that failed. - panic!("couldn't set attribute {}: {}", stringify!($attr), get_error()); + bail!("couldn't set attribute {}: {}", stringify!($attr), get_error()) } }) } @@ -220,7 +221,7 @@ pub mod gl_attr { }; if result != 0 { // Panic and print the attribute that failed. - panic!("couldn't get attribute {}: {}", stringify!($attr), get_error()); + bail!("couldn't get attribute {}: {}", stringify!($attr), get_error()); } value }) @@ -297,15 +298,18 @@ pub mod gl_attr { /// **Sets** the OpenGL context major and minor versions. #[inline] - pub fn set_context_version(&self, major: u8, minor: u8) { - self.set_context_major_version(major); - self.set_context_minor_version(minor); + pub fn set_context_version(&self, major: u8, minor: u8) -> Result<(), String> { + self.set_context_major_version(major)?; + self.set_context_minor_version(minor)?; + Ok(()) } /// **Gets** the OpenGL context major and minor versions as a tuple. #[inline] - pub fn context_version(&self) -> (u8, u8) { - (self.context_major_version(), self.context_minor_version()) + pub fn context_version(&self) -> Result<(u8, u8), String> { + let major = self.context_major_version()?; + let minor = self.context_minor_version()?; + Ok((major, minor)) } } @@ -319,8 +323,9 @@ pub mod gl_attr { impl<'a> ContextFlagsBuilder<'a> { /// Finishes the builder and applies the GL context flags to the GL context. #[inline] - pub fn set(&self) { + pub fn set(&self) -> Result<(), String> { gl_set_attribute!(SDL_GL_CONTEXT_FLAGS, self.flags); + Ok(()) } /// Sets the context into "debug" mode. @@ -403,12 +408,12 @@ pub mod gl_attr { /// println!("Debug mode"); /// } /// ``` - pub fn context_flags(&self) -> ContextFlags { + pub fn context_flags(&self) -> Result { let flags = gl_get_attribute!(SDL_GL_CONTEXT_FLAGS); - ContextFlags { + Ok(ContextFlags { flags: flags - } + }) } } From 23e080c76fcb5c603fc5d91f04327a3a42bc8596 Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 15:56:57 -0700 Subject: [PATCH 7/9] Remove From impl for SwapInterval in favor of custom try_from --- src/sdl2/video.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sdl2/video.rs b/src/sdl2/video.rs index 64d9977bfe8..9d84cb9cdd5 100644 --- a/src/sdl2/video.rs +++ b/src/sdl2/video.rs @@ -546,14 +546,14 @@ pub enum SwapInterval { LateSwapTearing = -1, } -impl From for SwapInterval { - fn from(i: i32) -> Self { - match i { +impl SwapInterval { + pub fn try_from(i: i32) -> Result { + Ok(match i { -1 => SwapInterval::LateSwapTearing, 0 => SwapInterval::Immediate, 1 => SwapInterval::VSync, - other => panic!("Invalid value for SwapInterval: {}; valid values are -1, 0, 1", other), - } + other => bail!("Invalid value for SwapInterval: {}; valid values are -1, 0, 1", other), + }) } } From 392533266dbae427ed30509cdbb3ed7f532084e2 Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 16:06:20 -0700 Subject: [PATCH 8/9] Remove panics from surface --- src/sdl2/surface.rs | 54 ++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/sdl2/surface.rs b/src/sdl2/surface.rs index a82d5827465..977ce08f636 100644 --- a/src/sdl2/surface.rs +++ b/src/sdl2/surface.rs @@ -259,30 +259,30 @@ impl SurfaceRef { } /// Locks a surface so that the pixels can be directly accessed safely. - pub fn with_lock R>(&self, f: F) -> R { + pub fn with_lock R>(&self, f: F) -> Result { unsafe { - if ll::SDL_LockSurface(self.raw()) != 0 { panic!("could not lock surface"); } + if ll::SDL_LockSurface(self.raw()) != 0 { bail!("could not lock surface"); } let raw_pixels = self.raw_ref().pixels as *const _; let len = self.raw_ref().pitch as usize * (self.raw_ref().h as usize); let pixels = ::std::slice::from_raw_parts(raw_pixels, len); let rv = f(pixels); ll::SDL_UnlockSurface(self.raw()); - rv + Ok(rv) } } /// Locks a surface so that the pixels can be directly accessed safely. - pub fn with_lock_mut R>(&mut self, f: F) -> R { + pub fn with_lock_mut R>(&mut self, f: F) -> Result { unsafe { - if ll::SDL_LockSurface(self.raw()) != 0 { panic!("could not lock surface"); } + if ll::SDL_LockSurface(self.raw()) != 0 { bail!("could not lock surface"); } let raw_pixels = self.raw_ref().pixels as *mut _; let len = self.raw_ref().pitch as usize * (self.raw_ref().h as usize); let pixels = ::std::slice::from_raw_parts_mut(raw_pixels, len); let rv = f(pixels); ll::SDL_UnlockSurface(self.raw()); - rv + Ok(rv) } } @@ -345,23 +345,25 @@ impl SurfaceRef { } #[allow(non_snake_case)] - pub fn enable_RLE(&mut self) { + pub fn enable_RLE(&mut self) -> Result<(), String> { let result = unsafe { ll::SDL_SetSurfaceRLE(self.raw(), 1) }; if result != 0 { // Should only panic on a null Surface - panic!(get_error()); + bail!(get_error()); } + Ok(()) } #[allow(non_snake_case)] - pub fn disable_RLE(&mut self) { + pub fn disable_RLE(&mut self) -> Result<(), String> { let result = unsafe { ll::SDL_SetSurfaceRLE(self.raw(), 0) }; if result != 0 { // Should only panic on a null Surface - panic!(get_error()); + bail!(get_error()); } + Ok(()) } pub fn set_color_key(&mut self, enable: bool, color: pixels::Color) -> Result<(), String> { @@ -393,17 +395,18 @@ impl SurfaceRef { } } - pub fn set_color_mod(&mut self, color: pixels::Color) { + pub fn set_color_mod(&mut self, color: pixels::Color) -> Result<(), String> { let (r, g, b) = color.rgb(); let result = unsafe { ll::SDL_SetSurfaceColorMod(self.raw(), r, g, b) }; if result != 0 { // Should only fail on a null Surface - panic!(get_error()); + bail!(get_error()); } + Ok(()) } - pub fn color_mod(&self) -> pixels::Color { + pub fn color_mod(&self) -> Result { let mut r = 0; let mut g = 0; let mut b = 0; @@ -415,10 +418,10 @@ impl SurfaceRef { }; if result { - pixels::Color::RGB(r, g, b) + Ok(pixels::Color::RGB(r, g, b)) } else { // Should only fail on a null Surface - panic!(get_error()) + bail!(get_error()) } } @@ -451,28 +454,29 @@ impl SurfaceRef { Ok(()) } - pub fn set_alpha_mod(&mut self, alpha: u8) { + pub fn set_alpha_mod(&mut self, alpha: u8) -> Result<(), String> { let result = unsafe { ll::SDL_SetSurfaceAlphaMod(self.raw(), alpha) }; if result != 0 { // Should only fail on a null Surface - panic!(get_error()); + bail!(get_error()); } + Ok(()) } - pub fn alpha_mod(&self) -> u8 { + pub fn alpha_mod(&self) -> Result { let mut alpha = 0; let result = unsafe { ll::SDL_GetSurfaceAlphaMod(self.raw(), &mut alpha) }; - match result { + Ok(match result { 0 => alpha, // Should only fail on a null Surface - _ => panic!(get_error()) - } + _ => bail!(get_error()) + }) } /// The function will fail if the blend mode is not supported by SDL. @@ -487,17 +491,17 @@ impl SurfaceRef { } } - pub fn blend_mode(&self) -> BlendMode { + pub fn blend_mode(&self) -> Result { let mut mode: ::sys::SDL_BlendMode = 0; let result = unsafe { ll::SDL_GetSurfaceBlendMode(self.raw(), &mut mode) }; - match result { + Ok(match result { 0 => FromPrimitive::from_i32(mode as i32).unwrap(), // Should only fail on a null Surface - _ => panic!(get_error()) - } + _ => bail!(get_error()) + }) } /// Sets the clip rectangle for the surface. From 5eec573afb91760373d28a395bc255211bd9faaa Mon Sep 17 00:00:00 2001 From: Jason Dagit Date: Mon, 4 Sep 2017 16:29:05 -0700 Subject: [PATCH 9/9] Remove panics from render --- src/sdl2/render.rs | 107 ++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/src/sdl2/render.rs b/src/sdl2/render.rs index eb7d078eaab..124894aa4d4 100644 --- a/src/sdl2/render.rs +++ b/src/sdl2/render.rs @@ -201,14 +201,14 @@ impl Drop for RendererContext { impl RendererContext { /// Gets information about the rendering context. - pub fn info(&self) -> RendererInfo { + pub fn info(&self) -> Result { unsafe { let mut renderer_info_raw = mem::uninitialized(); if ll::SDL_GetRendererInfo(self.raw, &mut renderer_info_raw) != 0 { // Should only fail on an invalid renderer - panic!(); + bail!("Invalid renderer"); } else { - RendererInfo::from_ll(&renderer_info_raw) + Ok(RendererInfo::from_ll(&renderer_info_raw)) } } } @@ -849,58 +849,61 @@ impl Canvas { } /// Sets the color used for drawing operations (Rect, Line and Clear). - pub fn set_draw_color(&mut self, color: pixels::Color) { + pub fn set_draw_color(&mut self, color: pixels::Color) -> Result<(), String> { let (r, g, b, a) = color.rgba(); let ret = unsafe { ll::SDL_SetRenderDrawColor(self.raw, r, g, b, a) }; // Should only fail on an invalid renderer if ret != 0 { - panic!(get_error()) + bail!(get_error()) } + Ok(()) } /// Gets the color used for drawing operations (Rect, Line and Clear). - pub fn draw_color(&self) -> pixels::Color { + pub fn draw_color(&self) -> Result { let (mut r, mut g, mut b, mut a) = (0, 0, 0, 0); let ret = unsafe { ll::SDL_GetRenderDrawColor(self.context.raw, &mut r, &mut g, &mut b, &mut a) }; // Should only fail on an invalid renderer if ret != 0 { - panic!(get_error()) + bail!(get_error()) } else { - pixels::Color::RGBA(r, g, b, a) + Ok(pixels::Color::RGBA(r, g, b, a)) } } /// Sets the blend mode used for drawing operations (Fill and Line). - pub fn set_blend_mode(&mut self, blend: BlendMode) { + pub fn set_blend_mode(&mut self, blend: BlendMode) -> Result<(), String> { let ret = unsafe { ll::SDL_SetRenderDrawBlendMode(self.context.raw, FromPrimitive::from_i64(blend as i64).unwrap()) }; // Should only fail on an invalid renderer if ret != 0 { - panic!(get_error()) + bail!(get_error()) } + Ok(()) } /// Gets the blend mode used for drawing operations. - pub fn blend_mode(&self) -> BlendMode { + pub fn blend_mode(&self) -> Result { let mut blend = 0; let ret = unsafe { ll::SDL_GetRenderDrawBlendMode(self.context.raw, &mut blend) }; // Should only fail on an invalid renderer if ret != 0 { - panic!(get_error()) + bail!(get_error()) } else { - FromPrimitive::from_i64(blend as i64).unwrap() + FromPrimitive::from_i64(blend as i64).ok_or_else(||"blend mode".to_string()) } } /// Clears the current rendering target with the drawing color. - pub fn clear(&mut self) { + pub fn clear(&mut self) -> Result<(), String> { let ret = unsafe { ll::SDL_RenderClear(self.context.raw) }; if ret != 0 { - panic!("Could not clear: {}", get_error()) + bail!("Could not clear: {}", get_error()) } + Ok(()) } /// Updates the screen with any rendering performed since the previous call. @@ -952,15 +955,16 @@ impl Canvas { } /// Sets the drawing area for rendering on the current target. - pub fn set_viewport>>(&mut self, rect: R) { + pub fn set_viewport>>(&mut self, rect: R) -> Result<(), String> { let ptr = match rect.into() { Some(ref rect) => rect.raw(), None => ptr::null(), }; let ret = unsafe { ll::SDL_RenderSetViewport(self.context.raw, ptr) }; if ret != 0 { - panic!("Could not set viewport: {}", get_error()) + bail!("Could not set viewport: {}", get_error()) } + Ok(()) } /// Gets the drawing area for the current target. @@ -973,7 +977,7 @@ impl Canvas { /// Sets the clip rectangle for rendering on the specified target. /// /// If the rectangle is `None`, clipping will be disabled. - pub fn set_clip_rect>>(&mut self, rect: R) { + pub fn set_clip_rect>>(&mut self, rect: R) -> Result<(), String> { let ret = unsafe { ll::SDL_RenderSetClipRect(self.context.raw, match rect.into() { @@ -982,8 +986,9 @@ impl Canvas { }) }; if ret != 0 { - panic!("Could not set clip rect: {}", get_error()) + bail!("Could not set clip rect: {}", get_error()) } + Ok(()) } /// Gets the clip rectangle for the current target. @@ -1430,7 +1435,7 @@ impl Error for UpdateTextureYUVError { impl<'r> Texture<'r> { /// Queries the attributes of the texture. - pub fn query(&self) -> TextureQuery { + pub fn query(&self) -> Result { let mut format = 0; let mut access = 0; let mut width = 0; @@ -1441,78 +1446,81 @@ impl<'r> Texture<'r> { }; // Should only fail on an invalid texture if ret != 0 { - panic!(get_error()) + bail!(get_error()) } else { - TextureQuery { + Ok(TextureQuery { format: FromPrimitive::from_i64(format as i64).unwrap(), access: FromPrimitive::from_i64(access as i64).unwrap(), width: width as u32, height: height as u32, - } + }) } } /// Sets an additional color value multiplied into render copy operations. - pub fn set_color_mod(&mut self, red: u8, green: u8, blue: u8) { + pub fn set_color_mod(&mut self, red: u8, green: u8, blue: u8) -> Result<(), String> { let ret = unsafe { ll::SDL_SetTextureColorMod(self.raw, red, green, blue) }; if ret != 0 { - panic!("Error setting color mod: {}", get_error()) + bail!("Error setting color mod: {}", get_error()) } + Ok(()) } /// Gets the additional color value multiplied into render copy operations. - pub fn color_mod(&self) -> (u8, u8, u8) { + pub fn color_mod(&self) -> Result<(u8, u8, u8), String> { let (mut r, mut g, mut b) = (0, 0, 0); let ret = unsafe { ll::SDL_GetTextureColorMod(self.raw, &mut r, &mut g, &mut b) }; // Should only fail on an invalid texture if ret != 0 { - panic!(get_error()) + bail!(get_error()) } else { - (r, g, b) + Ok((r, g, b)) } } /// Sets an additional alpha value multiplied into render copy operations. - pub fn set_alpha_mod(&mut self, alpha: u8) { + pub fn set_alpha_mod(&mut self, alpha: u8) -> Result<(), String>{ let ret = unsafe { ll::SDL_SetTextureAlphaMod(self.raw, alpha) }; if ret != 0 { - panic!("Error setting alpha mod: {}", get_error()) + bail!("Error setting alpha mod: {}", get_error()) } + Ok(()) } /// Gets the additional alpha value multiplied into render copy operations. - pub fn alpha_mod(&self) -> u8 { + pub fn alpha_mod(&self) -> Result { let mut alpha = 0; let ret = unsafe { ll::SDL_GetTextureAlphaMod(self.raw, &mut alpha) }; // Should only fail on an invalid texture - if ret != 0 { panic!(get_error()) } else { alpha } + if ret != 0 { bail!(get_error()) } else { Ok(alpha) } } /// Sets the blend mode for a texture, used by `Renderer::copy()`. - pub fn set_blend_mode(&mut self, blend: BlendMode) { + pub fn set_blend_mode(&mut self, blend: BlendMode) -> Result<(), String> { let ret = unsafe { ll::SDL_SetTextureBlendMode(self.raw, FromPrimitive::from_i64(blend as i64).unwrap()) }; if ret != 0 { - panic!("Error setting blend: {}", get_error()) + bail!("Error setting blend: {}", get_error()) } + Ok(()) } /// Gets the blend mode used for texture copy operations. - pub fn blend_mode(&self) -> BlendMode { + pub fn blend_mode(&self) -> Result { let mut blend = 0; let ret = unsafe { ll::SDL_GetTextureBlendMode(self.raw, &mut blend) }; // Should only fail on an invalid texture if ret != 0 { - panic!(get_error()) + bail!(get_error()) } else { - FromPrimitive::from_i64(blend as i64).unwrap() + FromPrimitive::from_i64(blend as i64).ok_or_else(||"blend mode".to_string()) } } @@ -1539,7 +1547,7 @@ impl<'r> Texture<'r> { // Check if the rectangle's position or size is odd, and if the pitch is odd. // This needs to be done in case the texture's pixel format is planar YUV. // See issue #334 for details. - let TextureQuery { format, .. } = self.query(); + let TextureQuery { format, .. } = self.query().unwrap(); match format { PixelFormatEnum::YV12 | PixelFormatEnum::IYUV => { @@ -1621,7 +1629,7 @@ impl<'r> Texture<'r> { // If the destination rectangle lies outside the texture boundaries, // SDL_UpdateYUVTexture will write outside allocated texture memory. - let tex_info = self.query(); + let tex_info = self.query().unwrap(); if let Some(ref r) = rect { let tex_rect = Rect::new(0, 0, tex_info.width, tex_info.height); let inside = match r.intersection(tex_rect) { @@ -1728,7 +1736,7 @@ impl<'r> Texture<'r> { { // Call to SDL to populate pixel data let loaded = unsafe { - let q = self.query(); + let q = self.query()?; let mut pixels = ptr::null_mut(); let mut pitch = 0; @@ -1762,26 +1770,27 @@ impl<'r> Texture<'r> { /// Binds an OpenGL/ES/ES2 texture to the current /// context for use with when rendering OpenGL primitives directly. - pub unsafe fn gl_bind_texture(&mut self) -> (f32, f32) { + pub unsafe fn gl_bind_texture(&mut self) -> Result<(f32, f32), String> { let mut texw = 0.0; let mut texh = 0.0; if ll::SDL_GL_BindTexture(self.raw, &mut texw, &mut texh) == 0 { - (texw, texh) + Ok((texw, texh)) } else { - panic!("OpenGL texture binding not supported"); + bail!("OpenGL texture binding not supported"); } } /// Unbinds an OpenGL/ES/ES2 texture from the current context. - pub unsafe fn gl_unbind_texture(&mut self) { + pub unsafe fn gl_unbind_texture(&mut self) -> Result<(), String> { if ll::SDL_GL_UnbindTexture(self.raw) != 0 { - panic!("OpenGL texture unbinding not supported"); + bail!("OpenGL texture unbinding not supported"); } + Ok(()) } /// Binds and unbinds an OpenGL/ES/ES2 texture from the current context. - pub fn gl_with_bind R>(&mut self, f: F) -> R { + pub fn gl_with_bind R>(&mut self, f: F) -> Result { unsafe { let mut texw = 0.0; let mut texh = 0.0; @@ -1790,13 +1799,13 @@ impl<'r> Texture<'r> { let return_value = f(texw, texh); if ll::SDL_GL_UnbindTexture(self.raw) == 0 { - return_value + Ok(return_value) } else { // This should never happen... - panic!(); + bail!("gl_with_bind: the impossible happened"); } } else { - panic!("OpenGL texture binding not supported"); + bail!("OpenGL texture binding not supported"); } } }