@@ -480,27 +480,9 @@ where
480
480
// https://github.com/godotengine/godot-cpp/issues/954
481
481
482
482
fn as_arg_ptr ( & self ) -> sys:: GDExtensionConstTypePtr {
483
- // Do not extract this code. Address of field pointer matters, copying it into a local variable will create use-after-free .
483
+ // Even though ObjectArg exists, this function is still relevant, e.g. in Callable .
484
484
485
- // No need to call self.check_rtti("as_arg_ptr") here, since this is already done in ToGodot impl.
486
-
487
- // We pass an object to a Godot API. If the reference count needs to be incremented, then the callee (Godot C++ function) will do so.
488
- // We do not need to prematurely do so. In Rust terms, if `T` is ref-counted, then we are effectively passing a `&Arc<T>`, and the
489
- // callee would need to invoke `.clone()` if desired.
490
-
491
- // In 4.0, argument pointers are passed to godot as `T*`, except for in virtual method calls. We can't perform virtual method calls
492
- // currently, so they are always `T*`.
493
- //
494
- // In 4.1, argument pointers were standardized to always be `T**`.
495
- #[ cfg( before_api = "4.1" ) ]
496
- {
497
- self . sys ( )
498
- }
499
-
500
- #[ cfg( since_api = "4.1" ) ]
501
- {
502
- ptr:: addr_of!( self . obj) as sys:: GDExtensionConstTypePtr
503
- }
485
+ object_as_arg_ptr ( self , & self . obj )
504
486
}
505
487
506
488
unsafe fn from_arg_ptr ( ptr : sys:: GDExtensionTypePtr , call_type : PtrcallType ) -> Self {
@@ -581,23 +563,7 @@ impl<T: GodotClass> GodotType for RawGd<T> {
581
563
582
564
impl < T : GodotClass > GodotFfiVariant for RawGd < T > {
583
565
fn ffi_to_variant ( & self ) -> Variant {
584
- // The conversion method `object_to_variant` DOES increment the reference-count of the object; so nothing to do here.
585
- // (This behaves differently in the opposite direction `variant_to_object`.)
586
-
587
- unsafe {
588
- Variant :: new_with_var_uninit ( |variant_ptr| {
589
- let converter = sys:: builtin_fn!( object_to_variant) ;
590
-
591
- // Note: this is a special case because of an inconsistency in Godot, where sometimes the equivalency is
592
- // GDExtensionTypePtr == Object** and sometimes GDExtensionTypePtr == Object*. Here, it is the former, thus extra pointer.
593
- // Reported at https://github.com/godotengine/godot/issues/61967
594
- let type_ptr = self . sys ( ) ;
595
- converter (
596
- variant_ptr,
597
- ptr:: addr_of!( type_ptr) as sys:: GDExtensionTypePtr ,
598
- ) ;
599
- } )
600
- }
566
+ object_ffi_to_variant ( self )
601
567
}
602
568
603
569
fn ffi_from_variant ( variant : & Variant ) -> Result < Self , ConvertError > {
@@ -681,6 +647,9 @@ impl<T: GodotClass> fmt::Debug for RawGd<T> {
681
647
}
682
648
}
683
649
650
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
651
+ // Reusable functions, also shared with Gd, Variant, ObjectArg.
652
+
684
653
/// Runs `init_fn` on the address of a pointer (initialized to null), then returns that pointer, possibly still null.
685
654
///
686
655
/// # Safety
@@ -699,3 +668,50 @@ pub unsafe fn raw_object_init(
699
668
// We don't need to know if Object** is null, but if Object* is null; return_ptr has the address of a local (never null).
700
669
object_ptr
701
670
}
671
+
672
+ pub ( super ) fn object_ffi_to_variant < T : GodotFfi > ( self_ : & T ) -> Variant {
673
+ // The conversion method `object_to_variant` DOES increment the reference-count of the object; so nothing to do here.
674
+ // (This behaves differently in the opposite direction `variant_to_object`.)
675
+
676
+ unsafe {
677
+ Variant :: new_with_var_uninit ( |variant_ptr| {
678
+ let converter = sys:: builtin_fn!( object_to_variant) ;
679
+
680
+ // Note: this is a special case because of an inconsistency in Godot, where sometimes the equivalency is
681
+ // GDExtensionTypePtr == Object** and sometimes GDExtensionTypePtr == Object*. Here, it is the former, thus extra pointer.
682
+ // Reported at https://github.com/godotengine/godot/issues/61967
683
+ let type_ptr = self_. sys ( ) ;
684
+ converter (
685
+ variant_ptr,
686
+ ptr:: addr_of!( type_ptr) as sys:: GDExtensionTypePtr ,
687
+ ) ;
688
+ } )
689
+ }
690
+ }
691
+
692
+ pub ( super ) fn object_as_arg_ptr < T : GodotFfi , F > (
693
+ _self : & T ,
694
+ _object_ptr_field : & * mut F ,
695
+ ) -> sys:: GDExtensionConstTypePtr {
696
+ // Be careful when refactoring this code. Address of field pointer matters, copying it into a local variable will create use-after-free.
697
+
698
+ // No need to call self.check_rtti("as_arg_ptr") here, since this is already done in ToGodot impl.
699
+
700
+ // We pass an object to a Godot API. If the reference count needs to be incremented, then the callee (Godot C++ function) will do so.
701
+ // We do not need to prematurely do so. In Rust terms, if `T` is ref-counted, then we are effectively passing a `&Arc<T>`, and the
702
+ // callee would need to invoke `.clone()` if desired.
703
+
704
+ // In 4.0, argument pointers are passed to godot as `T*`, except for in virtual method calls. We can't perform virtual method calls
705
+ // currently, so they are always `T*`.
706
+ //
707
+ // In 4.1, argument pointers were standardized to always be `T**`.
708
+ #[ cfg( before_api = "4.1" ) ]
709
+ {
710
+ _self. sys ( )
711
+ }
712
+
713
+ #[ cfg( since_api = "4.1" ) ]
714
+ {
715
+ ptr:: addr_of!( * _object_ptr_field) as sys:: GDExtensionConstTypePtr
716
+ }
717
+ }
0 commit comments