Add lifetimes to Surface and Renderer.

* `Surface` requires a lifetime because of the `Surface::from_data()`
   method. The method does not copy the buffer passed to it, and thus
   must live no longer than the buffer.
* `Renderer` now takes a lifetime in accordance with `Surface`'s new
  lifetime requirement.
This commit is contained in:
Dan Spencer
2015-04-11 06:23:57 -06:00
parent 7d27c53c54
commit 74656f4651
2 changed files with 54 additions and 31 deletions
+12 -12
View File
@@ -141,19 +141,19 @@ impl RendererInfo {
}
}
pub enum RendererParent {
Surface(Surface),
pub enum RendererParent<'a> {
Surface(Surface<'a>),
Window(Window)
}
/// 2D rendering context
pub struct Renderer {
pub struct Renderer<'a> {
raw: *const ll::SDL_Renderer,
parent: Option<RendererParent>,
parent: Option<RendererParent<'a>>,
is_alive: Rc<UnsafeCell<bool>>
}
impl Drop for Renderer {
impl<'a> Drop for Renderer<'a> {
fn drop(&mut self) {
unsafe {
*self.is_alive.get() = false;
@@ -162,9 +162,9 @@ impl Drop for Renderer {
}
}
impl Renderer {
impl<'a> Renderer<'a> {
/// Creates a 2D rendering context for a window.
pub fn from_window(window: Window, index: RenderDriverIndex, renderer_flags: RendererFlags) -> SdlResult<Renderer> {
pub fn from_window(window: Window, index: RenderDriverIndex, renderer_flags: RendererFlags) -> SdlResult<Renderer<'static>> {
let index = match index {
RenderDriverIndex::Auto => -1,
RenderDriverIndex::Index(x) => x
@@ -184,7 +184,7 @@ impl Renderer {
}
/// Creates a window and default renderer.
pub fn new_with_window(_sdl: &Sdl, width: i32, height: i32, window_flags: video::WindowFlags) -> SdlResult<Renderer> {
pub fn new_with_window(_sdl: &Sdl, width: i32, height: i32, window_flags: video::WindowFlags) -> SdlResult<Renderer<'static>> {
use sys::video::SDL_Window;
let raw_window: *const SDL_Window = ptr::null();
@@ -201,7 +201,7 @@ impl Renderer {
}
/// Creates a 2D software rendering context for a surface.
pub fn from_surface(surface: surface::Surface) -> SdlResult<Renderer> {
pub fn from_surface(surface: surface::Surface<'a>) -> SdlResult<Renderer<'a>> {
let raw_renderer = unsafe { ll::SDL_CreateSoftwareRenderer(surface.raw()) };
if raw_renderer != ptr::null() {
unsafe {
@@ -256,7 +256,7 @@ impl Renderer {
}
#[inline]
pub fn unwrap_parent(mut self) -> RendererParent {
pub fn unwrap_parent(mut self) -> RendererParent<'a> {
use std::mem;
mem::replace(&mut self.parent, None).unwrap()
}
@@ -270,7 +270,7 @@ impl Renderer {
}
#[inline]
pub fn unwrap_parent_as_surface(self) -> Option<Surface> {
pub fn unwrap_parent_as_surface(self) -> Option<Surface<'a>> {
match self.unwrap_parent() {
RendererParent::Surface(surface) => Some(surface),
_ => None
@@ -310,7 +310,7 @@ impl Renderer {
}
/// Texture-creating methods for the renderer
impl Renderer {
impl<'a> Renderer<'a> {
/// Creates a texture for a rendering context.
///
/// `size` is the width and height of the texture.
+42 -19
View File
@@ -1,3 +1,4 @@
use std::marker::PhantomData;
use std::mem;
use std::path::Path;
use rect::Rect;
@@ -21,14 +22,13 @@ bitflags! {
}
}
#[derive(PartialEq)]
#[allow(raw_pointer_derive, missing_copy_implementations)]
pub struct Surface {
pub struct Surface<'a> {
raw: *const ll::SDL_Surface,
owned: bool
owned: bool,
_marker: PhantomData<&'a ()>
}
impl Drop for Surface {
impl<'a> Drop for Surface<'a> {
fn drop(&mut self) {
if self.owned {
unsafe {
@@ -38,13 +38,21 @@ impl Drop for Surface {
}
}
impl_raw_accessors!((Surface, *const ll::SDL_Surface));
impl_owned_accessors!((Surface, owned));
impl_raw_constructor!((Surface, Surface (raw: *const ll::SDL_Surface, owned: bool)));
impl<'a> Surface<'a> {
pub unsafe fn raw(&self) -> *const ll::SDL_Surface { self.raw }
pub unsafe fn owned(&self) -> bool { self.owned }
pub unsafe fn from_ll<'b>(raw: *const ll::SDL_Surface, owned: bool) -> Surface<'b> {
Surface {
raw: raw,
owned: owned,
_marker: PhantomData
}
}
impl Surface {
pub fn new(surface_flags: SurfaceFlag, width: i32, height: i32, bpp: i32,
rmask: u32, gmask: u32, bmask: u32, amask: u32) -> SdlResult<Surface> {
rmask: u32, gmask: u32, bmask: u32, amask: u32) -> SdlResult<Surface<'static>> {
unsafe {
let raw = ll::SDL_CreateRGBSurface(surface_flags.bits(), width as c_int, height as c_int, bpp as c_int,
rmask, gmask, bmask, amask);
@@ -52,13 +60,17 @@ impl Surface {
if raw == ptr::null() {
Err(get_error())
} else {
Ok(Surface { raw: raw, owned: true })
Ok(Surface {
raw: raw,
owned: true,
_marker: PhantomData
})
}
}
}
pub fn from_data(data: &mut [u8], width: i32, height: i32, bpp: i32, pitch: i32,
rmask: u32, gmask: u32, bmask: u32, amask: u32) -> SdlResult<Surface> {
pub fn from_data(data: &'a mut [u8], width: i32, height: i32, bpp: i32, pitch: i32,
rmask: u32, gmask: u32, bmask: u32, amask: u32) -> SdlResult<Surface<'a>> {
unsafe {
let raw = ll::SDL_CreateRGBSurfaceFrom(
@@ -68,7 +80,11 @@ impl Surface {
if raw == ptr::null() {
Err(get_error())
} else {
Ok(Surface { raw: raw, owned: true })
Ok(Surface {
raw: raw,
owned: true,
_marker: PhantomData
})
}
}
}
@@ -126,13 +142,20 @@ impl Surface {
unsafe { ll::SDL_UnlockSurface(self.raw); }
}
pub fn from_bmp(path: &Path) -> SdlResult<Surface> {
pub fn from_bmp(path: &Path) -> SdlResult<Surface<'static>> {
let raw = unsafe {
ll::SDL_LoadBMP_RW(try!(rwops::RWops::from_file(path, "rb")).raw(), 0)
};
if raw.is_null() { Err(get_error()) }
else { Ok(Surface{raw: raw, owned: true}) }
if raw.is_null() {
Err(get_error())
} else {
Ok(Surface {
raw: raw,
owned: true,
_marker: PhantomData
})
}
}
pub fn save_bmp(&self, path: &Path) -> SdlResult<()> {
@@ -307,7 +330,7 @@ impl Surface {
rect
}
pub fn convert(&self, format: &pixels::PixelFormat) -> SdlResult<Surface> {
pub fn convert(&self, format: &pixels::PixelFormat) -> SdlResult<Surface<'static>> {
// SDL_ConvertSurface takes a flag as the last parameter, which should be 0 by the docs.
let surface_ptr = unsafe { ll::SDL_ConvertSurface(self.raw, format.raw(), 0u32) };
@@ -318,7 +341,7 @@ impl Surface {
}
}
pub fn convert_format(&self, format: pixels::PixelFormatEnum) -> SdlResult<Surface> {
pub fn convert_format(&self, format: pixels::PixelFormatEnum) -> SdlResult<Surface<'static>> {
let surface_ptr = unsafe { ll::SDL_ConvertSurfaceFormat(self.raw, format as uint32_t, 0u32) };
if surface_ptr == ptr::null() {