Skip to main content

rusteal_core/
weak_ptr.rs

1// TWeakObjectPtr<T>: typed weak reference to a UObject.
2// Does not prevent garbage collection. Can be resolved to UObjectRef<T>
3// if the object is still alive.
4
5use std::marker::PhantomData;
6
7use rusteal_ffi::FWeakObjectHandle;
8
9use crate::ffi_dispatch;
10use crate::object_ref::UObjectRef;
11use crate::traits::UeClass;
12
13/// A typed weak reference to a UObject.
14///
15/// Unlike `UObjectRef<T>`, a weak pointer uses UE's internal weak reference
16/// system (ObjectIndex + SerialNumber) which can reliably detect when an
17/// object has been garbage collected.
18///
19/// Use `get()` to attempt to resolve to a strong `UObjectRef<T>`.
20#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
21pub struct TWeakObjectPtr<T: UeClass> {
22    handle: FWeakObjectHandle,
23    _marker: PhantomData<*const T>,
24}
25
26unsafe impl<T: UeClass> Send for TWeakObjectPtr<T> {}
27
28impl<T: UeClass> TWeakObjectPtr<T> {
29    /// Create a weak pointer from a strong UObjectRef.
30    pub fn from_ref(obj: &UObjectRef<T>) -> Self {
31        let handle = unsafe { ffi_dispatch::core_make_weak(obj.raw()) };
32        TWeakObjectPtr {
33            handle,
34            _marker: PhantomData,
35        }
36    }
37
38    /// Attempt to resolve to a strong reference. Returns `None` if the
39    /// object has been garbage collected.
40    pub fn get(&self) -> Option<UObjectRef<T>> {
41        let obj = unsafe { ffi_dispatch::core_resolve_weak(self.handle) };
42        if obj.is_null() {
43            None
44        } else {
45            Some(unsafe { UObjectRef::from_raw(obj) })
46        }
47    }
48
49    /// Check if the referenced object is still alive.
50    pub fn is_valid(&self) -> bool {
51        unsafe { ffi_dispatch::core_is_weak_valid(self.handle) }
52    }
53
54    /// Get the underlying FFI handle.
55    #[inline]
56    pub fn handle(&self) -> FWeakObjectHandle {
57        self.handle
58    }
59}
60
61impl<T: UeClass> Default for TWeakObjectPtr<T> {
62    fn default() -> Self {
63        TWeakObjectPtr {
64            handle: FWeakObjectHandle::default(),
65            _marker: PhantomData,
66        }
67    }
68}