commonlibsse_ng\re\b/
BSPointerHandle.rs1use core::marker::PhantomData;
2
3use crate::re::Actor::Actor;
4use crate::re::NiSmartPointer::{NiPointer, RefCountable};
5use crate::re::Projectile;
6use crate::re::TESObjectREFR::TESObjectREFR;
7
8#[repr(transparent)]
10#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct BSUntypedPointerHandle(u32);
12
13impl BSUntypedPointerHandle {
14 #[inline]
16 pub const fn new() -> Self {
17 Self(0)
18 }
19
20 #[inline]
23 pub const fn from_raw(value: u32) -> Self {
24 Self(value)
25 }
26
27 #[inline]
29 pub const fn has_value(&self) -> bool {
30 self.0 != 0
31 }
32
33 #[inline]
36 pub const fn as_raw(&self) -> u32 {
37 self.0
38 }
39
40 #[inline]
42 pub const fn reset(&mut self) {
43 self.0 = 0;
44 }
45}
46
47#[repr(C)]
51#[derive(Debug)]
52pub struct BSPointerHandle<T> {
53 handle: BSUntypedPointerHandle,
54 _phantom: core::marker::PhantomData<T>,
55}
56const _: () = assert!(core::mem::size_of::<BSPointerHandle<()>>() == 0x4);
57
58impl<T> Clone for BSPointerHandle<T> {
59 #[inline]
60 fn clone(&self) -> Self {
61 Self { handle: self.handle, _phantom: self._phantom }
62 }
63}
64
65impl<T> Default for BSPointerHandle<T> {
66 #[inline]
67 fn default() -> Self {
68 Self::new()
69 }
70}
71
72impl<T> PartialEq<Self> for BSPointerHandle<T> {
73 #[inline]
74 fn eq(&self, other: &Self) -> bool {
75 self.handle == other.handle
76 }
77}
78
79impl<T> Eq for BSPointerHandle<T> {}
80
81impl<T> BSPointerHandle<T> {
82 #[inline]
84 pub const fn new() -> Self {
85 Self { handle: BSUntypedPointerHandle::new(), _phantom: PhantomData }
86 }
87
88 #[inline]
90 pub const fn from_handle(handle: BSUntypedPointerHandle) -> Self {
91 Self { handle, _phantom: PhantomData }
92 }
93
94 #[inline]
96 const fn from_raw(value: u32) -> Self {
97 Self { handle: BSUntypedPointerHandle::from_raw(value), _phantom: PhantomData }
98 }
99
100 pub const fn native_handle(&self) -> u32 {
102 self.handle.as_raw()
103 }
104
105 pub const fn has_value(&self) -> bool {
107 self.handle.has_value()
108 }
109
110 pub const fn reset(&mut self) {
112 self.handle.reset();
113 }
114}
115
116impl<T: RefCountable> BSPointerHandle<T> {
117 #[inline]
119 pub fn get(&self) -> NiPointer<T> {
120 let mut smart_ptr = NiPointer::<T>::new();
121 let _ = BSPointerHandleManagerInterface::<T>::GetSmartPointer(self, &mut smart_ptr);
122 smart_ptr
123 }
124
125 #[inline]
127 pub fn as_ref(&self) -> Option<&T> {
128 self.get().as_ptr().map(|ptr| unsafe { ptr.as_ref() })
129 }
130}
131
132#[repr(C)]
134pub struct BSPointerHandleManagerInterface<T> {
135 _phantom: core::marker::PhantomData<T>,
136}
137
138impl<T> BSPointerHandleManagerInterface<T> {
139 pub fn GetHandle(ptr: *mut T) -> BSPointerHandle<T> {
141 BSPointerHandle::from_raw(unsafe { Self::GetHandleRaw(ptr.cast()) })
142 }
143
144 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 15967, ae_id = 16212)]
149 #[inline]
150 pub unsafe extern "C" fn GetHandleRaw(ptr: *mut ()) -> u32 {}
151}
152
153impl<T: RefCountable> BSPointerHandleManagerInterface<T> {
154 pub fn GetSmartPointer(handle: &BSPointerHandle<T>, smart_ptr: &mut NiPointer<T>) -> bool {
156 let handle = (handle as *const BSPointerHandle<T>).cast();
157 let smart_ptr = (smart_ptr as *mut NiPointer<T>).cast();
158 unsafe { Self::GetSmartPointerRaw(handle, smart_ptr) }
160 }
161
162 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 12204, ae_id = 12332)]
167 #[inline]
168 pub unsafe extern "C" fn GetSmartPointerRaw(handle: *const (), smart_ptr: *mut ()) -> bool {}
169}
170
171macro_rules! impl_handle_wrapper {
175 ($(
176 $(#[$meta:meta])*
177 $vis:vis struct $name:ident : $inner:ty;
178 )*) => {
179 $(
180 $(#[$meta])*
181 #[repr(transparent)]
185 #[derive(Debug, Clone, Default, PartialEq)]
186 $vis struct $name(BSPointerHandle<$inner>);
187
188 unsafe impl std_fork::zeroable::Zeroable for $name {}
190
191 impl $name {
192 #[inline]
194 pub const fn new() -> Self {
195 Self(BSPointerHandle::new())
196 }
197
198 #[inline]
200 pub const fn from_handle(handle: BSUntypedPointerHandle) -> Self {
201 Self(BSPointerHandle::from_handle(handle))
202 }
203
204 #[inline]
206 pub const fn from_raw(value: u32) -> Self {
207 Self(BSPointerHandle::from_raw(value))
208 }
209
210 #[inline]
212 pub const fn as_raw(&self) -> u32 {
213 self.0.native_handle()
214 }
215
216 #[inline]
218 pub const fn has_value(&self) -> bool {
219 self.0.has_value()
220 }
221
222 #[inline]
224 pub const fn reset(&mut self) {
225 self.0.reset()
226 }
227 }
228
229 impl From<BSPointerHandle<$inner>> for $name {
230 #[inline]
231 fn from(inner: BSPointerHandle<$inner>) -> Self {
232 Self(inner)
233 }
234 }
235
236 impl From<$name> for BSPointerHandle<$inner> {
237 #[inline]
238 fn from(wrapper: $name) -> Self {
239 wrapper.0
240 }
241 }
242
243 impl $name {
244 #[inline]
246 pub fn get(&self) -> NiPointer<$inner> {
247 self.0.get()
248 }
249
250 #[inline]
252 pub fn as_ref(&self) -> Option<&$inner> {
253 self.0.as_ref()
254 }
255 }
256 )*
257 };
258}
259
260impl_handle_wrapper! {
261 pub struct ActorHandle : Actor;
262 pub struct ProjectileHandle : Projectile;
263 pub struct ObjectRefHandle : TESObjectREFR;
264}