@@ -14,6 +14,9 @@ use std::mem::ManuallyDrop;
14
14
///
15
15
/// Behaves similarly to [`Gd`][crate::obj::Gd], but is more constrained. Cannot be constructed by the user.
16
16
pub struct Base < T : GodotClass > {
17
+ // Like `Gd`, it's theoretically possible that Base is destroyed while there are still other Gd pointers to the underlying object. This is
18
+ // safe, may however lead to unintended behavior. The base_test.rs file checks some of these scenarios.
19
+
17
20
// Internal smart pointer is never dropped. It thus acts like a weak pointer and is needed to break reference cycles between Gd<T>
18
21
// and the user instance owned by InstanceStorage.
19
22
//
@@ -34,19 +37,37 @@ pub struct Base<T: GodotClass> {
34
37
}
35
38
36
39
impl < T : GodotClass > Base < T > {
40
+ /// "Copy constructor": allows to share a `Base<T>` weak pointer.
41
+ ///
42
+ /// The return value is a weak pointer, so it will not keep the instance alive.
43
+ ///
37
44
/// # Safety
38
- /// The returned Base is a weak pointer, so holding it will not keep the object alive. It must not be accessed after the object is destroyed.
45
+ /// `base` must be alive at the time of invocation, i.e. user `init()` (which could technically destroy it) must not have run yet.
46
+ /// If `base` is destroyed while the returned `Base<T>` is in use, that constitutes a logic error, not a safety issue.
39
47
pub ( crate ) unsafe fn from_base ( base : & Base < T > ) -> Base < T > {
40
- Base :: from_obj ( Gd :: from_obj_sys_weak ( base. as_gd ( ) . obj_sys ( ) ) )
48
+ debug_assert ! ( base. obj. is_instance_valid( ) ) ;
49
+ Base :: from_obj ( Gd :: from_obj_sys_weak ( base. obj . obj_sys ( ) ) )
41
50
}
42
51
52
+ /// Create base from existing object (used in script instances).
53
+ ///
54
+ /// The return value is a weak pointer, so it will not keep the instance alive.
55
+ ///
43
56
/// # Safety
44
- /// The returned Base is a weak pointer, so holding it will not keep the object alive. It must not be accessed after the object is destroyed.
57
+ /// `gd` must be alive at the time of invocation. If it is destroyed while the returned `Base<T>` is in use, that constitutes a logic
58
+ /// error, not a safety issue.
45
59
pub ( crate ) unsafe fn from_gd ( gd : & Gd < T > ) -> Self {
60
+ debug_assert ! ( gd. is_instance_valid( ) ) ;
46
61
Base :: from_obj ( Gd :: from_obj_sys_weak ( gd. obj_sys ( ) ) )
47
62
}
48
63
49
- // Note: not &mut self, to only borrow one field and not the entire struct
64
+ /// Create new base from raw Godot object.
65
+ ///
66
+ /// The return value is a weak pointer, so it will not keep the instance alive.
67
+ ///
68
+ /// # Safety
69
+ /// `base_ptr` must point to a valid, live object at the time of invocation. If it is destroyed while the returned `Base<T>` is in use,
70
+ /// that constitutes a logic error, not a safety issue.
50
71
pub ( crate ) unsafe fn from_sys ( base_ptr : sys:: GDExtensionObjectPtr ) -> Self {
51
72
assert ! ( !base_ptr. is_null( ) , "instance base is null pointer" ) ;
52
73
@@ -76,16 +97,7 @@ impl<T: GodotClass> Base<T> {
76
97
( * self . obj ) . clone ( )
77
98
}
78
99
79
- /// Returns a [`Gd`] referencing the same object as this reference.
80
- ///
81
- /// Using this method to call methods on the base field of a Rust object is discouraged, instead use the
82
- /// methods from [`WithBaseField`](super::WithBaseField) when possible.
83
- #[ doc( hidden) ]
84
- pub fn as_gd ( & self ) -> & Gd < T > {
85
- & self . obj
86
- }
87
-
88
- // Currently only used in outbound virtual calls (for scripts).
100
+ // Currently only used in outbound virtual calls (for scripts); search for: base_field(self).obj_sys().
89
101
#[ doc( hidden) ]
90
102
pub fn obj_sys ( & self ) -> sys:: GDExtensionObjectPtr {
91
103
self . obj . obj_sys ( )
0 commit comments