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