@@ -70,12 +70,11 @@ impl_builtin_froms!(Array;
70
70
71
71
impl < T : VariantMetadata > TypedArray < T > {
72
72
fn from_opaque ( opaque : sys:: types:: OpaqueArray ) -> Self {
73
- let array = Self {
73
+ // Note: type is not yet checked at this point, because array has not yet been initialized!
74
+ Self {
74
75
opaque,
75
76
_phantom : PhantomData ,
76
- } ;
77
- array. check_type ( ) ;
78
- array
77
+ }
79
78
}
80
79
81
80
/// Returns the number of elements in the array. Equivalent of `size()` in Godot.
@@ -320,8 +319,9 @@ impl<T: VariantMetadata> TypedArray<T> {
320
319
/// # Panics
321
320
///
322
321
/// If the inner type doesn't match `T` or no type is set at all.
323
- fn check_type ( & self ) {
322
+ fn with_checked_type ( self ) -> Self {
324
323
assert_eq ! ( self . type_info( ) , TypeInfo :: new:: <T >( ) ) ;
324
+ self
325
325
}
326
326
327
327
/// Sets the type of the inner array. Can only be called once, directly after creation.
@@ -567,14 +567,9 @@ impl<T: VariantMetadata + ToVariant> TypedArray<T> {
567
567
// }
568
568
569
569
impl < T : VariantMetadata > GodotFfi for TypedArray < T > {
570
- ffi_methods ! {
571
- type sys:: GDExtensionTypePtr = * mut Opaque ;
572
- fn from_sys;
573
- fn sys;
574
- fn write_sys;
575
- }
570
+ ffi_methods ! { type sys:: GDExtensionTypePtr = * mut Opaque ; .. }
576
571
577
- unsafe fn from_sys_init ( init_fn : impl FnOnce ( sys:: GDExtensionTypePtr ) ) -> Self {
572
+ unsafe fn from_sys_init_default ( init_fn : impl FnOnce ( sys:: GDExtensionTypePtr ) ) -> Self {
578
573
// Can't use uninitialized pointer -- Array CoW implementation in C++ expects that on
579
574
// assignment, the target CoW pointer is either initialized or nullptr
580
575
@@ -598,28 +593,25 @@ impl<T: VariantMetadata> fmt::Debug for TypedArray<T> {
598
593
/// [`Array::duplicate_deep()`].
599
594
impl < T : VariantMetadata > Share for TypedArray < T > {
600
595
fn share ( & self ) -> Self {
601
- unsafe {
596
+ let array = unsafe {
602
597
Self :: from_sys_init ( |self_ptr| {
603
598
let ctor = :: godot_ffi:: builtin_fn!( array_construct_copy) ;
604
599
let args = [ self . sys_const ( ) ] ;
605
600
ctor ( self_ptr, args. as_ptr ( ) ) ;
606
601
} )
607
- }
602
+ } ;
603
+ array. with_checked_type ( )
608
604
}
609
605
}
610
606
611
607
impl < T : VariantMetadata > Default for TypedArray < T > {
612
608
#[ inline]
613
609
fn default ( ) -> Self {
614
- // Note: can't use from_sys_init(), as that calls the default constructor
615
- // (because most assignments expect initialized target type)
616
- let mut uninit = std:: mem:: MaybeUninit :: < TypedArray < T > > :: uninit ( ) ;
617
610
let mut array = unsafe {
618
- let self_ptr = ( * uninit. as_mut_ptr ( ) ) . sys_mut ( ) ;
619
- sys:: builtin_call! {
620
- array_construct_default( self_ptr, std:: ptr:: null_mut( ) )
621
- } ;
622
- uninit. assume_init ( )
611
+ Self :: from_sys_init ( |self_ptr| {
612
+ let ctor = sys:: builtin_fn!( array_construct_default) ;
613
+ ctor ( self_ptr, std:: ptr:: null_mut ( ) )
614
+ } )
623
615
} ;
624
616
array. init_inner_type ( ) ;
625
617
array
@@ -661,14 +653,14 @@ impl<T: VariantMetadata> FromVariant for TypedArray<T> {
661
653
if variant. get_type ( ) != Self :: variant_type ( ) {
662
654
return Err ( VariantConversionError ) ;
663
655
}
664
- let result = unsafe {
665
- Self :: from_sys_init ( |self_ptr| {
656
+ let array = unsafe {
657
+ Self :: from_sys_init_default ( |self_ptr| {
666
658
let array_from_variant = sys:: builtin_fn!( array_from_variant) ;
667
659
array_from_variant ( self_ptr, variant. var_sys ( ) ) ;
668
660
} )
669
661
} ;
670
662
671
- Ok ( result )
663
+ Ok ( array . with_checked_type ( ) )
672
664
}
673
665
}
674
666
@@ -773,7 +765,7 @@ impl<T: VariantMetadata> PartialEq for TypedArray<T> {
773
765
let mut result = false ;
774
766
sys:: builtin_call! {
775
767
array_operator_equal( self . sys( ) , other. sys( ) , result. sys_mut( ) )
776
- } ;
768
+ }
777
769
result
778
770
}
779
771
}
0 commit comments