1use std::fmt;
5use std::marker::PhantomData;
6
7use crate::error::RustealResult;
8use crate::object_ref::UObjectRef;
9use crate::traits::UeClass;
10use crate::world;
11
12pub struct SoftObjectRef<T: UeClass> {
16 path: String,
17 _marker: PhantomData<T>,
18}
19
20impl<T: UeClass> SoftObjectRef<T> {
21 pub fn new(path: impl Into<String>) -> Self {
23 SoftObjectRef {
24 path: path.into(),
25 _marker: PhantomData,
26 }
27 }
28
29 pub fn null() -> Self {
31 Self::new(String::new())
32 }
33
34 pub fn path(&self) -> &str {
36 &self.path
37 }
38
39 pub fn is_null(&self) -> bool {
41 self.path.is_empty()
42 }
43
44 pub fn get(&self) -> UObjectRef<T> {
46 if self.is_null() {
47 return UObjectRef::null();
48 }
49 world::find_object_raw(T::static_class(), &self.path)
50 .map(|h| unsafe { UObjectRef::from_raw(h) })
51 .unwrap_or_else(|_| UObjectRef::null())
52 }
53
54 pub fn load_synchronous(&self) -> RustealResult<UObjectRef<T>> {
57 if self.is_null() {
58 return Ok(UObjectRef::null());
59 }
60 let handle = world::load_object_raw(T::static_class(), &self.path)?;
61 Ok(unsafe { UObjectRef::from_raw(handle) })
62 }
63}
64
65impl<T: UeClass> Default for SoftObjectRef<T> {
66 fn default() -> Self {
67 Self::null()
68 }
69}
70
71impl<T: UeClass> Clone for SoftObjectRef<T> {
72 fn clone(&self) -> Self {
73 Self::new(self.path.clone())
74 }
75}
76
77impl<T: UeClass> PartialEq for SoftObjectRef<T> {
78 fn eq(&self, other: &Self) -> bool {
79 self.path == other.path
80 }
81}
82
83impl<T: UeClass> Eq for SoftObjectRef<T> {}
84
85impl<T: UeClass> fmt::Debug for SoftObjectRef<T> {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 f.debug_tuple("SoftObjectRef").field(&self.path).finish()
88 }
89}