commonlibsse_ng\re\n/
NiRefObject.rs

1use crate::re::offsets_rtti::RTTI_NiRefObject;
2use crate::re::offsets_vtable::VTABLE_NiRefObject;
3use crate::rel::id::VariantID;
4use core::sync::atomic::{AtomicU32, Ordering};
5
6#[repr(C)]
7#[derive(Debug)]
8pub struct NiRefObject {
9    pub vtbl: *const NiRefObjectVtbl,
10    pub _ref_count: AtomicU32,
11    _pad: u32,
12}
13const _: () = assert!(core::mem::size_of::<NiRefObject>() == 0x10);
14
15#[repr(C)]
16pub struct NiRefObjectVtbl {
17    /// C++ virtual class Destructor equivalent
18    /// - override: `NiRefObject`
19    pub CxxDrop: unsafe extern "C" fn(this: *mut NiRefObject), // 0x00
20    /// `NiRefObject` virtual member function
21    pub DeleteThis: unsafe extern "C" fn(this: *mut NiRefObject), // 0x01
22}
23const _: () = assert!(core::mem::size_of::<NiRefObjectVtbl>() == 0x10);
24
25impl NiRefObject {
26    pub const RTTI: VariantID = RTTI_NiRefObject;
27    pub const VTABLE: [VariantID; 1] = VTABLE_NiRefObject;
28
29    /// Manual Destructor
30    ///
31    /// # Safety
32    /// As long as not double free.
33    pub unsafe fn delete_this(&mut self) {
34        unsafe { ((*self.vtbl).DeleteThis)(self) };
35    }
36
37    // Get ref count
38    pub fn get_ref_count(&self) -> u32 {
39        self._ref_count.load(Ordering::SeqCst)
40    }
41
42    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 523912, ae_id = 410493)]
43    pub unsafe fn get_total_object_count(&mut self) -> *const AtomicU32 {}
44}
45
46impl crate::re::NiSmartPointer::RefCountable for NiRefObject {
47    #[inline]
48    fn inc_ref_count(&self) {
49        self._ref_count.fetch_add(1, Ordering::SeqCst);
50    }
51
52    #[inline]
53    fn dec_ref_count(&mut self) {
54        if self._ref_count.fetch_sub(1, Ordering::SeqCst) == 1 {
55            unsafe { self.delete_this() }; // FIXME: Maybe unsafe
56        }
57    }
58}
59
60impl Drop for NiRefObject {
61    fn drop(&mut self) {
62        if let Some(count) = unsafe { self.get_total_object_count().as_ref() } {
63            count.fetch_sub(1, Ordering::AcqRel);
64        }
65    }
66}