Skip to content

Commit 8e8a291

Browse files
committed
reverted combination of Surface+SurfaceRef
1 parent 09153e5 commit 8e8a291

File tree

4 files changed

+109
-44
lines changed

4 files changed

+109
-44
lines changed

src/sdl2/mouse/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ptr;
22

33
use get_error;
4-
use surface::Surface;
4+
use surface::SurfaceRef;
55
use video;
66
use EventPump;
77

@@ -55,9 +55,9 @@ impl Cursor {
5555
}
5656

5757
// TODO: figure out how to pass Surface in here correctly
58-
pub fn from_surface<'a>(surface: &Surface<'a>, hot_x: i32, hot_y: i32) -> Result<Cursor, String> {
58+
pub fn from_surface<S: AsRef<SurfaceRef>>(surface: S, hot_x: i32, hot_y: i32) -> Result<Cursor, String> {
5959
unsafe {
60-
let raw = ll::SDL_CreateColorCursor(surface.raw(), hot_x, hot_y);
60+
let raw = ll::SDL_CreateColorCursor(surface.as_ref().raw(), hot_x, hot_y);
6161

6262
if raw == ptr::null_mut() {
6363
Err(get_error())

src/sdl2/render.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
3131
use video::{Window, WindowContext};
3232
use surface;
33-
use surface::{Surface, SurfaceContext};
33+
use surface::{Surface, SurfaceRef, SurfaceContext};
3434
use pixels;
3535
use pixels::PixelFormatEnum;
3636
use get_error;
@@ -286,13 +286,13 @@ impl<'s> Canvas<Surface<'s>, SurfaceContext<'s>> {
286286

287287
/// Gets a reference to the associated surface of the Canvas
288288
#[inline]
289-
pub fn surface(&self) -> &Surface<'s> {
289+
pub fn surface(&self) -> &SurfaceRef {
290290
&self.target
291291
}
292292

293293
/// Gets a mutable reference to the associated surface of the Canvas
294294
#[inline]
295-
pub fn surface_mut(&mut self) -> &mut Surface<'s> {
295+
pub fn surface_mut(&mut self) -> &mut SurfaceRef {
296296
&mut self.target
297297
}
298298

@@ -602,11 +602,13 @@ impl<T> TextureCreator<T> {
602602
/// Creates a texture from an existing surface.
603603
/// # Remarks
604604
/// The access hint for the created texture is `TextureAccess::Static`.
605-
pub fn create_texture_from_surface<'a>(&self,
606-
surface: &Surface<'a>)
607-
-> Result<Texture, TextureValueError> {
605+
pub fn create_texture_from_surface<S: AsRef<SurfaceRef>>
606+
(&self,
607+
surface: S)
608+
-> Result<Texture, TextureValueError> {
608609
use self::TextureValueError::*;
609-
let result = unsafe { ll::SDL_CreateTextureFromSurface(self.context.raw, surface.raw()) };
610+
let result =
611+
unsafe { ll::SDL_CreateTextureFromSurface(self.context.raw, surface.as_ref().raw()) };
610612
if result == ptr::null_mut() {
611613
Err(SdlError(get_error()))
612614
} else {

src/sdl2/surface.rs

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::marker::PhantomData;
22
use std::mem;
3+
use std::ops::{Deref, DerefMut};
34
use std::path::Path;
45
use std::rc::Rc;
56

@@ -17,21 +18,13 @@ use sys::surface as ll;
1718
/// Holds a `SDL_Surface`
1819
///
1920
/// When the `SurfaceContext` is dropped, it frees the `SDL_Surface`
21+
///
22+
/// *INTERNAL USE ONLY*
2023
pub struct SurfaceContext<'a> {
2124
raw: *mut ll::SDL_Surface,
2225
_marker: PhantomData<&'a ()>
2326
}
2427

25-
/// Unsafe if the `*mut SDL_Surface` is used after the `SurfaceContext` is dropped
26-
impl<'a> SurfaceContext<'a> {
27-
pub unsafe fn from_ll(raw: *mut ll::SDL_Surface) -> SurfaceContext<'a> {
28-
SurfaceContext {
29-
raw: raw,
30-
_marker: PhantomData,
31-
}
32-
}
33-
}
34-
3528
impl<'a> Drop for SurfaceContext<'a> {
3629
#[inline]
3730
fn drop(&mut self) {
@@ -47,20 +40,68 @@ pub struct Surface<'a> {
4740
context: Rc<SurfaceContext<'a>>,
4841
}
4942

50-
impl<'a> From<SurfaceContext<'a>> for Surface<'a> {
51-
fn from(context: SurfaceContext<'a>) -> Surface<'a> {
52-
Surface { context: Rc::new(context) }
43+
/// An unsized Surface reference.
44+
///
45+
/// This type is used whenever Surfaces need to be borrowed from the SDL library, without concern
46+
/// for freeing the Surface.
47+
pub struct SurfaceRef {
48+
// It's nothing! (it gets transmuted to SDL_Surface later).
49+
// The empty private field is need to a) make `std::mem::swap()` copy nothing instead of
50+
// clobbering two surfaces (SDL_Surface's size could change in the future),
51+
// and b) prevent user initialization of this type.
52+
_raw: ()
53+
}
54+
55+
impl AsRef<SurfaceRef> for SurfaceRef {
56+
fn as_ref(&self) -> &SurfaceRef {
57+
self
5358
}
5459
}
5560

56-
impl<'a> Surface<'a> {
57-
pub unsafe fn from_ll<'b>(raw: *mut ll::SDL_Surface) -> Surface<'b> {
58-
let context = SurfaceContext::from_ll(raw);
59-
context.into()
61+
#[test]
62+
fn test_surface_ref_size() {
63+
// `SurfaceRef` must be 0 bytes.
64+
assert_eq!(::std::mem::size_of::<SurfaceRef>(), 0);
65+
}
66+
67+
impl<'a> Deref for Surface<'a> {
68+
type Target = SurfaceRef;
69+
70+
#[inline]
71+
fn deref(&self) -> &SurfaceRef {
72+
unsafe { mem::transmute(self.context.raw) }
73+
}
74+
}
75+
76+
impl<'a> DerefMut for Surface<'a> {
77+
#[inline]
78+
fn deref_mut(&mut self) -> &mut SurfaceRef {
79+
unsafe { mem::transmute(self.context.raw) }
80+
}
81+
}
82+
83+
impl<'a> AsRef<SurfaceRef> for Surface<'a> {
84+
#[inline]
85+
fn as_ref(&self) -> &SurfaceRef {
86+
unsafe { mem::transmute(self.context.raw) }
6087
}
88+
}
6189

62-
pub unsafe fn from_ref(context: Rc<SurfaceContext<'a>>) -> Surface<'a> {
63-
Surface { context: context }
90+
impl<'a> AsMut<SurfaceRef> for Surface<'a> {
91+
#[inline]
92+
fn as_mut(&mut self) -> &mut SurfaceRef {
93+
unsafe { mem::transmute(self.context.raw) }
94+
}
95+
}
96+
97+
98+
impl<'a> Surface<'a> {
99+
pub unsafe fn from_ll<'b>(raw: *mut ll::SDL_Surface) -> Surface<'b> {
100+
let context = SurfaceContext {
101+
raw: raw,
102+
_marker: PhantomData,
103+
};
104+
Surface { context: Rc::new(context) }
64105
}
65106

66107
/// Creates a new surface using a pixel format.
@@ -151,15 +192,27 @@ impl<'a> Surface<'a> {
151192
pub fn context(&self) -> Rc<SurfaceContext<'a>> {
152193
self.context.clone()
153194
}
195+
}
196+
197+
impl SurfaceRef {
198+
#[inline]
199+
pub unsafe fn from_ll<'a>(raw: *mut ll::SDL_Surface) -> &'a SurfaceRef {
200+
mem::transmute(raw)
201+
}
202+
203+
#[inline]
204+
pub unsafe fn from_ll_mut<'a>(raw: *mut ll::SDL_Surface) -> &'a mut SurfaceRef {
205+
mem::transmute(raw)
206+
}
154207

155208
#[inline]
156209
pub fn raw(&self) -> *mut ll::SDL_Surface {
157-
self.context.raw
210+
unsafe { mem::transmute(self) }
158211
}
159212

160213
#[inline]
161214
fn raw_ref(&self) -> &ll::SDL_Surface {
162-
unsafe { &*self.context.raw }
215+
unsafe { mem::transmute(self) }
163216
}
164217

165218
pub fn width(&self) -> u32 {
@@ -485,8 +538,8 @@ impl<'a> Surface<'a> {
485538
/// Performs surface blitting (surface copying).
486539
///
487540
/// Returns the final blit rectangle, if a `dst_rect` was provided.
488-
pub fn blit<'b, R1, R2>(&self, src_rect: R1,
489-
dst: &mut Surface<'b>, dst_rect: R2)
541+
pub fn blit<R1, R2>(&self, src_rect: R1,
542+
dst: &mut SurfaceRef, dst_rect: R2)
490543
-> Result<Option<Rect>, String>
491544
where R1: Into<Option<Rect>>,
492545
R2: Into<Option<Rect>>,
@@ -518,8 +571,8 @@ impl<'a> Surface<'a> {
518571
///
519572
/// Unless you know what you're doing, use `blit()` instead, which will clip the input rectangles.
520573
/// This function could crash if the rectangles aren't pre-clipped to the surface, and is therefore unsafe.
521-
pub unsafe fn lower_blit<'b, R1, R2>(&self, src_rect: R1,
522-
dst: &mut Surface<'b>, dst_rect: R2) -> Result<(), String>
574+
pub unsafe fn lower_blit<R1, R2>(&self, src_rect: R1,
575+
dst: &mut SurfaceRef, dst_rect: R2) -> Result<(), String>
523576
where R1: Into<Option<Rect>>,
524577
R2: Into<Option<Rect>>,
525578
{
@@ -542,8 +595,8 @@ impl<'a> Surface<'a> {
542595
/// Performs scaled surface bliting (surface copying).
543596
///
544597
/// Returns the final blit rectangle, if a `dst_rect` was provided.
545-
pub fn blit_scaled<'b, R1, R2>(&self, src_rect: R1,
546-
dst: &mut Surface<'b>, dst_rect: R2) -> Result<Option<Rect>, String>
598+
pub fn blit_scaled<R1, R2>(&self, src_rect: R1,
599+
dst: &mut SurfaceRef, dst_rect: R2) -> Result<Option<Rect>, String>
547600
where R1: Into<Option<Rect>>,
548601
R2: Into<Option<Rect>>,
549602
{
@@ -569,8 +622,8 @@ impl<'a> Surface<'a> {
569622
///
570623
/// Unless you know what you're doing, use `blit_scaled()` instead, which will clip the input rectangles.
571624
/// This function could crash if the rectangles aren't pre-clipped to the surface, and is therefore unsafe.
572-
pub unsafe fn lower_blit_scaled<'b, R1, R2>(&self, src_rect: R1,
573-
dst: &mut Surface<'b>, dst_rect: R2) -> Result<(), String>
625+
pub unsafe fn lower_blit_scaled<R1, R2>(&self, src_rect: R1,
626+
dst: &mut SurfaceRef, dst_rect: R2) -> Result<(), String>
574627
where R1: Into<Option<Rect>>,
575628
R2: Into<Option<Rect>>
576629
{

src/sdl2/video.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::error::Error;
66

77
use rect::Rect;
88
use render::CanvasBuilder;
9-
use surface::Surface;
9+
use surface::SurfaceRef;
1010
use pixels::PixelFormatEnum;
1111
use VideoSubsystem;
1212
use EventPump;
@@ -1045,9 +1045,9 @@ impl Window {
10451045
}
10461046
}
10471047

1048-
pub fn set_icon<'b>(&mut self, icon: &Surface<'b>) {
1048+
pub fn set_icon<S: AsRef<SurfaceRef>>(&mut self, icon: S) {
10491049
unsafe {
1050-
ll::SDL_SetWindowIcon(self.context.raw, icon.raw())
1050+
ll::SDL_SetWindowIcon(self.context.raw, icon.as_ref().raw())
10511051
}
10521052
}
10531053

@@ -1177,13 +1177,23 @@ impl Window {
11771177
}
11781178
}
11791179

1180-
pub fn surface<'a>(&'a mut self, _e: &'a EventPump) -> Result<Surface<'a>, String> {
1180+
pub fn surface<'a>(&'a self, _e: &'a EventPump) -> Result<&'a SurfaceRef, String> {
11811181
let raw = unsafe { ll::SDL_GetWindowSurface(self.context.raw) };
11821182

11831183
if raw.is_null() {
11841184
Err(get_error())
11851185
} else {
1186-
unsafe { Ok(Surface::from_ll(raw)) }
1186+
unsafe { Ok(SurfaceRef::from_ll(raw)) }
1187+
}
1188+
}
1189+
1190+
pub fn surface_mut<'a>(&'a mut self, _e: &'a EventPump) -> Result<&'a mut SurfaceRef, String> {
1191+
let raw = unsafe { ll::SDL_GetWindowSurface(self.context.raw) };
1192+
1193+
if raw.is_null() {
1194+
Err(get_error())
1195+
} else {
1196+
unsafe { Ok(SurfaceRef::from_ll_mut(raw)) }
11871197
}
11881198
}
11891199

0 commit comments

Comments
 (0)