uika_runtime/struct_ref.rs
1// UStructRef<T>: lightweight typed wrapper for struct memory pointers.
2//
3// Unlike UObjectRef<T>, struct memory is not garbage-collected by UE.
4// UStructRef is just a typed raw pointer to a struct instance in memory
5// (e.g., inside a UObject property or a parameter buffer).
6
7use std::marker::PhantomData;
8
9use uika_ffi::UObjectHandle;
10
11use crate::traits::UeStruct;
12
13/// A typed, non-owning reference to a UE struct instance in memory.
14///
15/// This wraps a raw pointer to struct data (e.g., an FVector stored inside
16/// a UObject property). The struct memory is managed by its container —
17/// no validity check is needed (unlike UObjectRef).
18///
19/// PropertyApi methods accept `UObjectHandle` (`*mut c_void`) which works
20/// for both UObject pointers and raw struct memory pointers.
21pub struct UStructRef<T: UeStruct> {
22 ptr: *mut u8,
23 _marker: PhantomData<T>,
24}
25
26impl<T: UeStruct> UStructRef<T> {
27 /// Create from a raw pointer to struct memory.
28 ///
29 /// # Safety
30 /// The caller must ensure `ptr` points to valid memory containing a `T`.
31 #[inline]
32 pub unsafe fn from_raw(ptr: *mut u8) -> Self {
33 UStructRef {
34 ptr,
35 _marker: PhantomData,
36 }
37 }
38
39 /// Get the raw pointer as a `UObjectHandle`.
40 ///
41 /// PropertyApi methods take `UObjectHandle` which is `*mut c_void` —
42 /// this works for both UObject pointers and raw struct memory.
43 #[inline]
44 pub fn as_ptr(&self) -> UObjectHandle {
45 UObjectHandle(self.ptr as *mut std::ffi::c_void)
46 }
47}
48
49impl<T: UeStruct> std::fmt::Debug for UStructRef<T> {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 f.debug_struct("UStructRef")
52 .field("ptr", &self.ptr)
53 .finish()
54 }
55}