5
5
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
6
*/
7
7
8
- use std:: ptr;
8
+ use std:: { fmt , ptr} ;
9
9
10
10
use godot_ffi as sys;
11
11
use sys:: { interface_fn, GodotFfi , GodotNullableFfi , PtrcallType } ;
@@ -477,6 +477,28 @@ where
477
477
// For more context around `ref_get_object` and `ref_set_object`, see:
478
478
// https://github.com/godotengine/godot-cpp/issues/954
479
479
480
+ fn as_arg_ptr ( & self ) -> sys:: GDExtensionConstTypePtr {
481
+ // No need to call self.check_rtti("as_arg_ptr") here, since this is already done in ToGodot impl.
482
+
483
+ // 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.
484
+ // 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
485
+ // callee would need to invoke `.clone()` if desired.
486
+
487
+ // In 4.0, argument pointers are passed to godot as `T*`, except for in virtual method calls. We can't perform virtual method calls
488
+ // currently, so they are always `T*`.
489
+ //
490
+ // In 4.1, argument pointers were standardized to always be `T**`.
491
+ #[ cfg( before_api = "4.1" ) ]
492
+ {
493
+ self . sys ( )
494
+ }
495
+
496
+ #[ cfg( since_api = "4.1" ) ]
497
+ {
498
+ ptr:: addr_of!( self . obj) as sys:: GDExtensionConstTypePtr
499
+ }
500
+ }
501
+
480
502
unsafe fn from_arg_ptr ( ptr : sys:: GDExtensionTypePtr , call_type : PtrcallType ) -> Self {
481
503
if ptr. is_null ( ) {
482
504
return Self :: null ( ) ;
@@ -507,28 +529,6 @@ where
507
529
// We've passed ownership to caller.
508
530
std:: mem:: forget ( self ) ;
509
531
}
510
-
511
- fn as_arg_ptr ( & self ) -> sys:: GDExtensionConstTypePtr {
512
- // No need to call self.check_rtti("as_arg_ptr") here, since this is already done in ToGodot impl.
513
-
514
- // 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.
515
- // 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
516
- // callee would need to invoke `.clone()` if desired.
517
-
518
- // In 4.0, argument pointers are passed to godot as `T*`, except for in virtual method calls. We can't perform virtual method calls
519
- // currently, so they are always `T*`.
520
- //
521
- // In 4.1, argument pointers were standardized to always be `T**`.
522
- #[ cfg( before_api = "4.1" ) ]
523
- {
524
- self . sys ( )
525
- }
526
-
527
- #[ cfg( since_api = "4.1" ) ]
528
- {
529
- ptr:: addr_of!( self . obj) as sys:: GDExtensionConstTypePtr
530
- }
531
- }
532
532
}
533
533
534
534
impl < T : GodotClass > GodotConvert for RawGd < T > {
@@ -551,88 +551,6 @@ impl<T: GodotClass> FromGodot for RawGd<T> {
551
551
}
552
552
}
553
553
554
- impl < T : GodotClass > GodotNullableFfi for RawGd < T > {
555
- fn flatten_option ( opt : Option < Self > ) -> Self {
556
- opt. unwrap_or_else ( || Self :: null ( ) )
557
- }
558
-
559
- fn is_null ( & self ) -> bool {
560
- Self :: is_null ( self )
561
- }
562
- }
563
-
564
- /// Runs `init_fn` on the address of a pointer (initialized to null), then returns that pointer, possibly still null.
565
- ///
566
- /// # Safety
567
- /// `init_fn` must be a function that correctly handles a _type pointer_ pointing to an _object pointer_.
568
- #[ doc( hidden) ]
569
- pub unsafe fn raw_object_init (
570
- init_fn : impl FnOnce ( sys:: GDExtensionUninitializedTypePtr ) ,
571
- ) -> sys:: GDExtensionObjectPtr {
572
- // return_ptr has type GDExtensionTypePtr = GDExtensionObjectPtr* = OpaqueObject* = Object**
573
- // (in other words, the type-ptr contains the _address_ of an object-ptr).
574
- let mut object_ptr: sys:: GDExtensionObjectPtr = ptr:: null_mut ( ) ;
575
- let return_ptr: * mut sys:: GDExtensionObjectPtr = ptr:: addr_of_mut!( object_ptr) ;
576
-
577
- init_fn ( return_ptr as sys:: GDExtensionUninitializedTypePtr ) ;
578
-
579
- // 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).
580
- object_ptr
581
- }
582
-
583
- /// Destructor with semantics depending on memory strategy.
584
- ///
585
- /// * If this `RawGd` smart pointer holds a reference-counted type, this will decrement the reference counter.
586
- /// If this was the last remaining reference, dropping it will invoke `T`'s destructor.
587
- ///
588
- /// * If the held object is manually-managed, **nothing happens**.
589
- /// To destroy manually-managed `RawGd` pointers, you need to call [`crate::obj::Gd::free()`].
590
- impl < T : GodotClass > Drop for RawGd < T > {
591
- fn drop ( & mut self ) {
592
- // No-op for manually managed objects
593
-
594
- // out!("RawGd::drop <{}>", std::any::type_name::<T>());
595
-
596
- // SAFETY: This `Gd` won't be dropped again after this.
597
- let is_last = unsafe { T :: DynMemory :: maybe_dec_ref ( self ) } ; // may drop
598
- if is_last {
599
- unsafe {
600
- interface_fn ! ( object_destroy) ( self . obj_sys ( ) ) ;
601
- }
602
- }
603
-
604
- /*let st = self.storage();
605
- out!(" objd; self={:?}, val={:?}", st as *mut _, st.lifecycle);
606
- //out!(" objd2; self={:?}, val={:?}", st as *mut _, st.lifecycle);
607
-
608
- // If destruction is triggered by Godot, Storage already knows about it, no need to notify it
609
- if !self.storage().destroyed_by_godot() {
610
- let is_last = T::DynMemory::maybe_dec_ref(&self); // may drop
611
- if is_last {
612
- //T::Declarer::destroy(self);
613
- unsafe {
614
- interface_fn!(object_destroy)(self.obj_sys());
615
- }
616
- }
617
- }*/
618
- }
619
- }
620
-
621
- impl < T : GodotClass > Clone for RawGd < T > {
622
- fn clone ( & self ) -> Self {
623
- out ! ( "RawGd::clone" ) ;
624
- if !self . is_null ( ) {
625
- self . check_rtti ( "clone" ) ;
626
- }
627
-
628
- if !self . is_null ( ) {
629
- unsafe { Self :: from_obj_sys ( self . obj as sys:: GDExtensionObjectPtr ) }
630
- } else {
631
- Self :: null ( )
632
- }
633
- }
634
- }
635
-
636
554
impl < T : GodotClass > GodotType for RawGd < T > {
637
555
type Ffi = Self ;
638
556
@@ -701,8 +619,55 @@ impl<T: GodotClass> GodotFfiVariant for RawGd<T> {
701
619
}
702
620
}
703
621
704
- impl < T : GodotClass > std:: fmt:: Debug for RawGd < T > {
705
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
622
+ impl < T : GodotClass > GodotNullableFfi for RawGd < T > {
623
+ fn flatten_option ( opt : Option < Self > ) -> Self {
624
+ opt. unwrap_or_else ( Self :: null)
625
+ }
626
+
627
+ fn is_null ( & self ) -> bool {
628
+ Self :: is_null ( self )
629
+ }
630
+ }
631
+
632
+ /// Destructor with semantics depending on memory strategy.
633
+ ///
634
+ /// * If this `RawGd` smart pointer holds a reference-counted type, this will decrement the reference counter.
635
+ /// If this was the last remaining reference, dropping it will invoke `T`'s destructor.
636
+ ///
637
+ /// * If the held object is manually-managed, **nothing happens**.
638
+ /// To destroy manually-managed `RawGd` pointers, you need to call [`crate::obj::Gd::free()`].
639
+ impl < T : GodotClass > Drop for RawGd < T > {
640
+ fn drop ( & mut self ) {
641
+ // No-op for manually managed objects
642
+
643
+ out ! ( "RawGd::drop <{}>" , std:: any:: type_name:: <T >( ) ) ;
644
+
645
+ // SAFETY: This `Gd` won't be dropped again after this.
646
+ // If destruction is triggered by Godot, Storage already knows about it, no need to notify it
647
+ let is_last = unsafe { T :: DynMemory :: maybe_dec_ref ( self ) } ; // may drop
648
+ if is_last {
649
+ unsafe {
650
+ interface_fn ! ( object_destroy) ( self . obj_sys ( ) ) ;
651
+ }
652
+ }
653
+ }
654
+ }
655
+
656
+ impl < T : GodotClass > Clone for RawGd < T > {
657
+ fn clone ( & self ) -> Self {
658
+ out ! ( "RawGd::clone" ) ;
659
+
660
+ if self . is_null ( ) {
661
+ Self :: null ( )
662
+ } else {
663
+ self . check_rtti ( "clone" ) ;
664
+ unsafe { Self :: from_obj_sys ( self . obj as sys:: GDExtensionObjectPtr ) }
665
+ }
666
+ }
667
+ }
668
+
669
+ impl < T : GodotClass > fmt:: Debug for RawGd < T > {
670
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
706
671
if self . is_null ( ) {
707
672
return write ! ( f, "{} {{ null obj }}" , std:: any:: type_name:: <T >( ) ) ;
708
673
}
@@ -711,3 +676,22 @@ impl<T: GodotClass> std::fmt::Debug for RawGd<T> {
711
676
write ! ( f, "{gd:?}" )
712
677
}
713
678
}
679
+
680
+ /// Runs `init_fn` on the address of a pointer (initialized to null), then returns that pointer, possibly still null.
681
+ ///
682
+ /// # Safety
683
+ /// `init_fn` must be a function that correctly handles a _type pointer_ pointing to an _object pointer_.
684
+ #[ doc( hidden) ]
685
+ pub unsafe fn raw_object_init (
686
+ init_fn : impl FnOnce ( sys:: GDExtensionUninitializedTypePtr ) ,
687
+ ) -> sys:: GDExtensionObjectPtr {
688
+ // return_ptr has type GDExtensionTypePtr = GDExtensionObjectPtr* = OpaqueObject* = Object**
689
+ // (in other words, the type-ptr contains the _address_ of an object-ptr).
690
+ let mut object_ptr: sys:: GDExtensionObjectPtr = ptr:: null_mut ( ) ;
691
+ let return_ptr: * mut sys:: GDExtensionObjectPtr = ptr:: addr_of_mut!( object_ptr) ;
692
+
693
+ init_fn ( return_ptr as sys:: GDExtensionUninitializedTypePtr ) ;
694
+
695
+ // 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).
696
+ object_ptr
697
+ }
0 commit comments