@@ -10,7 +10,7 @@ use std::ptr;
10
10
11
11
use godot_ffi as sys;
12
12
use godot_ffi:: VariantType ;
13
- use sys:: { interface_fn , static_assert_eq_size, GodotNullableFfi } ;
13
+ use sys:: static_assert_eq_size;
14
14
15
15
use crate :: builtin:: meta:: { FromGodot , GodotCompatible , GodotType , ToGodot } ;
16
16
use crate :: builtin:: { Callable , StringName } ;
@@ -149,28 +149,6 @@ where
149
149
pub fn bind_mut ( & mut self ) -> GdMut < T > {
150
150
self . raw . bind_mut ( )
151
151
}
152
-
153
- /// Storage object associated with the extension instance.
154
- // pub(crate) fn storage_mut(&mut self) -> &mut InstanceStorage<T> {
155
- // // SAFETY:
156
- // unsafe {
157
- // let binding = self.resolve_instance_ptr();
158
- // crate::private::as_storage_mut::<T>(binding)
159
- // }
160
- // }
161
-
162
- unsafe fn resolve_instance_ptr ( & self ) -> sys:: GDExtensionClassInstancePtr {
163
- let callbacks = crate :: storage:: nop_instance_callbacks ( ) ;
164
- let token = sys:: get_library ( ) as * mut std:: ffi:: c_void ;
165
- let binding = interface_fn ! ( object_get_instance_binding) ( self . obj_sys ( ) , token, & callbacks) ;
166
-
167
- debug_assert ! (
168
- !binding. is_null( ) ,
169
- "Class {} -- null instance; does the class have a Godot creator function?" ,
170
- std:: any:: type_name:: <T >( )
171
- ) ;
172
- binding as sys:: GDExtensionClassInstancePtr
173
- }
174
152
}
175
153
176
154
/// _The methods in this impl block are available for any `T`._ <br><br>
@@ -182,13 +160,9 @@ impl<T: GodotClass> Gd<T> {
182
160
pub fn try_from_instance_id ( instance_id : InstanceId ) -> Option < Self > {
183
161
let ptr = engine:: object_ptr_from_id ( instance_id) ;
184
162
185
- if ptr. is_null ( ) {
186
- None
187
- } else {
188
- // SAFETY: assumes that the returned GDExtensionObjectPtr is convertible to Object* (i.e. C++ upcast doesn't modify the pointer)
189
- let untyped = unsafe { Gd :: < engine:: Object > :: from_obj_sys ( ptr) } ;
190
- untyped. owned_cast :: < T > ( ) . ok ( )
191
- }
163
+ // SAFETY: assumes that the returned GDExtensionObjectPtr is convertible to Object* (i.e. C++ upcast doesn't modify the pointer)
164
+ let untyped = unsafe { Gd :: < engine:: Object > :: from_obj_sys_or_none ( ptr) ? } ;
165
+ untyped. owned_cast :: < T > ( ) . ok ( )
192
166
}
193
167
194
168
/// ⚠️ Looks up the given instance ID and returns the associated object.
@@ -227,9 +201,13 @@ impl<T: GodotClass> Gd<T> {
227
201
/// ⚠️ Returns the last known, possibly invalid instance ID of this object.
228
202
///
229
203
/// This function does not check that the returned instance ID points to a valid instance!
230
- /// Unless performance is a problem, use [`instance_id()`][Self::instance_id] or [`instance_id_or_none()`][Self::instance_id_or_none] instead.
204
+ /// Unless performance is a problem, use [`instance_id()`][Self::instance_id] or
205
+ /// [`instance_id_or_none()`][Self::instance_id_or_none] instead.
231
206
pub fn instance_id_unchecked ( & self ) -> InstanceId {
232
- self . raw . cached_instance_id . get ( ) . unwrap ( )
207
+ // SAFETY:
208
+ // A `Gd` can only be created from a non-null `RawGd`. Meaning `raw.instance_id_unchecked()` will
209
+ // always return `Some`.
210
+ unsafe { self . raw . instance_id_unchecked ( ) . unwrap_unchecked ( ) }
233
211
}
234
212
235
213
/// Checks if this smart pointer points to a live object (read description!).
@@ -308,23 +286,33 @@ impl<T: GodotClass> Gd<T> {
308
286
. map_err ( Self :: from_ffi)
309
287
}
310
288
289
+ #[ doc( hidden) ]
290
+ pub ( crate ) unsafe fn from_obj_sys_or_none ( ptr : sys:: GDExtensionObjectPtr ) -> Option < Self > {
291
+ Self :: try_from_ffi ( RawGd :: from_obj_sys ( ptr) )
292
+ }
293
+
311
294
/// Initializes this `Gd<T>` from the object pointer as a **strong ref**, meaning
312
295
/// it initializes/increments the reference counter and keeps the object alive.
313
296
///
314
297
/// This is the default for most initializations from FFI. In cases where reference counter
315
298
/// should explicitly **not** be updated, [`Self::from_obj_sys_weak`] is available.
316
299
#[ doc( hidden) ]
317
- pub unsafe fn from_obj_sys ( ptr : sys:: GDExtensionObjectPtr ) -> Self {
318
- Self :: from_ffi ( RawGd :: from_obj_sys ( ptr) )
300
+ pub ( crate ) unsafe fn from_obj_sys ( ptr : sys:: GDExtensionObjectPtr ) -> Self {
301
+ Self :: from_obj_sys_or_none ( ptr) . unwrap ( )
319
302
}
320
303
321
304
#[ doc( hidden) ]
322
- pub unsafe fn from_obj_sys_weak ( ptr : sys:: GDExtensionObjectPtr ) -> Self {
323
- Self :: from_ffi ( RawGd :: from_obj_sys_weak ( ptr) )
305
+ pub ( crate ) unsafe fn from_obj_sys_weak_or_none ( ptr : sys:: GDExtensionObjectPtr ) -> Option < Self > {
306
+ Self :: try_from_ffi ( RawGd :: from_obj_sys_weak ( ptr) )
324
307
}
325
308
326
309
#[ doc( hidden) ]
327
- pub fn obj_sys ( & self ) -> sys:: GDExtensionObjectPtr {
310
+ pub ( crate ) unsafe fn from_obj_sys_weak ( ptr : sys:: GDExtensionObjectPtr ) -> Self {
311
+ Self :: from_obj_sys_weak_or_none ( ptr) . unwrap ( )
312
+ }
313
+
314
+ #[ doc( hidden) ]
315
+ pub ( crate ) fn obj_sys ( & self ) -> sys:: GDExtensionObjectPtr {
328
316
self . raw . obj_sys ( )
329
317
}
330
318
@@ -341,34 +329,13 @@ impl<T: GodotClass> Deref for Gd<T> {
341
329
type Target = <<T as GodotClass >:: Declarer as dom:: Domain >:: DerefTarget < T > ;
342
330
343
331
fn deref ( & self ) -> & Self :: Target {
344
- // SAFETY:
345
- //
346
- // This relies on `Gd<Node3D>` having the layout as `Node3D` (as an example),
347
- // which also needs #[repr(transparent)]:
348
- //
349
- // struct Gd<T: GodotClass> {
350
- // opaque: OpaqueObject, // <- size of GDExtensionObjectPtr
351
- // cached_instance_id, // <- Cell is #[repr(transparent)] to its inner T
352
- // _marker: PhantomData, // <- ZST
353
- // }
354
- // struct Node3D {
355
- // object_ptr: sys::GDExtensionObjectPtr,
356
- // }
357
- self . raw . as_target ( )
332
+ self . raw . as_target ( ) . expect ( "`Gd` is never null" )
358
333
}
359
334
}
360
335
361
336
impl < T : GodotClass > DerefMut for Gd < T > {
362
337
fn deref_mut ( & mut self ) -> & mut Self :: Target {
363
- // SAFETY: see also Deref
364
- //
365
- // The resulting `&mut T` is transmuted from `&mut OpaqueObject`, i.e. a *pointer* to the `opaque` field.
366
- // `opaque` itself has a different *address* for each Gd instance, meaning that two simultaneous
367
- // DerefMut borrows on two Gd instances will not alias, *even if* the underlying Godot object is the
368
- // same (i.e. `opaque` has the same value, but not address).
369
- //
370
- // The `&mut self` guarantees that no other base access can take place for *the same Gd instance* (access to other Gds is OK).
371
- self . raw . as_target_mut ( )
338
+ self . raw . as_target_mut ( ) . expect ( "`Gd` is never null" )
372
339
}
373
340
}
374
341
0 commit comments