1 use std::fmt;
2 use std::hash::{Hash, Hasher};
3 use std::ops::Deref;
4 use std::ptr;
5 use winapi::ctypes::c_void;
6 use winapi::um::unknwnbase::IUnknown;
7 use winapi::Interface;
8 use D3DResult;
9 
10 #[repr(transparent)]
11 pub struct WeakPtr<T>(*mut T);
12 
13 impl<T> WeakPtr<T> {
null() -> Self14     pub fn null() -> Self {
15         WeakPtr(ptr::null_mut())
16     }
17 
from_raw(raw: *mut T) -> Self18     pub unsafe fn from_raw(raw: *mut T) -> Self {
19         WeakPtr(raw)
20     }
21 
is_null(&self) -> bool22     pub fn is_null(&self) -> bool {
23         self.0.is_null()
24     }
25 
as_ptr(&self) -> *const T26     pub fn as_ptr(&self) -> *const T {
27         self.0
28     }
29 
as_mut_ptr(&self) -> *mut T30     pub fn as_mut_ptr(&self) -> *mut T {
31         self.0
32     }
33 
mut_void(&mut self) -> *mut *mut c_void34     pub unsafe fn mut_void(&mut self) -> *mut *mut c_void {
35         &mut self.0 as *mut *mut _ as *mut *mut _
36     }
37 }
38 
39 impl<T: Interface> WeakPtr<T> {
as_unknown(&self) -> &IUnknown40     pub unsafe fn as_unknown(&self) -> &IUnknown {
41         debug_assert!(!self.is_null());
42         &*(self.0 as *mut IUnknown)
43     }
44 
45     // Cast creates a new WeakPtr requiring explicit destroy call.
cast<U>(&self) -> D3DResult<WeakPtr<U>> where U: Interface,46     pub unsafe fn cast<U>(&self) -> D3DResult<WeakPtr<U>>
47     where
48         U: Interface,
49     {
50         let mut obj = WeakPtr::<U>::null();
51         let hr = self
52             .as_unknown()
53             .QueryInterface(&U::uuidof(), obj.mut_void());
54         (obj, hr)
55     }
56 
57     // Destroying one instance of the WeakPtr will invalidate all
58     // copies and clones.
destroy(&self)59     pub unsafe fn destroy(&self) {
60         self.as_unknown().Release();
61     }
62 }
63 
64 impl<T> Clone for WeakPtr<T> {
clone(&self) -> Self65     fn clone(&self) -> Self {
66         WeakPtr(self.0)
67     }
68 }
69 
70 impl<T> Copy for WeakPtr<T> {}
71 
72 impl<T> Deref for WeakPtr<T> {
73     type Target = T;
deref(&self) -> &T74     fn deref(&self) -> &T {
75         debug_assert!(!self.is_null());
76         unsafe { &*self.0 }
77     }
78 }
79 
80 impl<T> fmt::Debug for WeakPtr<T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result81     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82         write!(f, "WeakPtr( ptr: {:?} )", self.0)
83     }
84 }
85 
86 impl<T> PartialEq<*mut T> for WeakPtr<T> {
eq(&self, other: &*mut T) -> bool87     fn eq(&self, other: &*mut T) -> bool {
88         self.0 == *other
89     }
90 }
91 
92 impl<T> PartialEq for WeakPtr<T> {
eq(&self, other: &Self) -> bool93     fn eq(&self, other: &Self) -> bool {
94         self.0 == other.0
95     }
96 }
97 
98 impl<T> Hash for WeakPtr<T> {
hash<H: Hasher>(&self, state: &mut H)99     fn hash<H: Hasher>(&self, state: &mut H) {
100         self.0.hash(state);
101     }
102 }
103