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