1
1
use std:: marker:: PhantomData ;
2
2
use std:: mem;
3
+ use std:: ops:: { Deref , DerefMut } ;
3
4
use std:: path:: Path ;
4
5
use std:: rc:: Rc ;
5
6
@@ -17,21 +18,13 @@ use sys::surface as ll;
17
18
/// Holds a `SDL_Surface`
18
19
///
19
20
/// When the `SurfaceContext` is dropped, it frees the `SDL_Surface`
21
+ ///
22
+ /// *INTERNAL USE ONLY*
20
23
pub struct SurfaceContext < ' a > {
21
24
raw : * mut ll:: SDL_Surface ,
22
25
_marker : PhantomData < & ' a ( ) >
23
26
}
24
27
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
-
35
28
impl < ' a > Drop for SurfaceContext < ' a > {
36
29
#[ inline]
37
30
fn drop ( & mut self ) {
@@ -47,20 +40,68 @@ pub struct Surface<'a> {
47
40
context : Rc < SurfaceContext < ' a > > ,
48
41
}
49
42
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
53
58
}
54
59
}
55
60
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 ) }
60
87
}
88
+ }
61
89
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) }
64
105
}
65
106
66
107
/// Creates a new surface using a pixel format.
@@ -151,15 +192,27 @@ impl<'a> Surface<'a> {
151
192
pub fn context ( & self ) -> Rc < SurfaceContext < ' a > > {
152
193
self . context . clone ( )
153
194
}
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
+ }
154
207
155
208
#[ inline]
156
209
pub fn raw ( & self ) -> * mut ll:: SDL_Surface {
157
- self . context . raw
210
+ unsafe { mem :: transmute ( self ) }
158
211
}
159
212
160
213
#[ inline]
161
214
fn raw_ref ( & self ) -> & ll:: SDL_Surface {
162
- unsafe { & * self . context . raw }
215
+ unsafe { mem :: transmute ( self ) }
163
216
}
164
217
165
218
pub fn width ( & self ) -> u32 {
@@ -485,8 +538,8 @@ impl<'a> Surface<'a> {
485
538
/// Performs surface blitting (surface copying).
486
539
///
487
540
/// 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 )
490
543
-> Result < Option < Rect > , String >
491
544
where R1 : Into < Option < Rect > > ,
492
545
R2 : Into < Option < Rect > > ,
@@ -518,8 +571,8 @@ impl<'a> Surface<'a> {
518
571
///
519
572
/// Unless you know what you're doing, use `blit()` instead, which will clip the input rectangles.
520
573
/// 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 >
523
576
where R1 : Into < Option < Rect > > ,
524
577
R2 : Into < Option < Rect > > ,
525
578
{
@@ -542,8 +595,8 @@ impl<'a> Surface<'a> {
542
595
/// Performs scaled surface bliting (surface copying).
543
596
///
544
597
/// 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 >
547
600
where R1 : Into < Option < Rect > > ,
548
601
R2 : Into < Option < Rect > > ,
549
602
{
@@ -569,8 +622,8 @@ impl<'a> Surface<'a> {
569
622
///
570
623
/// Unless you know what you're doing, use `blit_scaled()` instead, which will clip the input rectangles.
571
624
/// 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 >
574
627
where R1 : Into < Option < Rect > > ,
575
628
R2 : Into < Option < Rect > >
576
629
{
0 commit comments