Skip to content

Commit 7a48845

Browse files
committed
Option<Gd<T>> does not implement ToVariant #240
1 parent bab1070 commit 7a48845

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

godot-core/src/obj/gd.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,15 @@ impl<T: GodotClass> ToVariant for Gd<T> {
706706
}
707707
}
708708

709+
impl<T: GodotClass> ToVariant for Option<Gd<T>> {
710+
fn to_variant(&self) -> Variant {
711+
match self {
712+
Some(gd) => gd.to_variant(),
713+
None => Variant::nil(),
714+
}
715+
}
716+
}
717+
709718
impl<T: GodotClass> PartialEq for Gd<T> {
710719
/// ⚠️ Returns whether two `Gd` pointers point to the same object.
711720
///

godot-ffi/src/godot_ffi.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*/
66

7-
use crate as sys;
8-
use std::fmt::Debug;
7+
use crate::{self as sys, interface_fn};
8+
use std::{fmt::Debug, ptr};
99

1010
/// Adds methods to convert from and to Godot FFI pointers.
1111
/// See [crate::ffi_methods] for ergonomic implementation.
@@ -487,3 +487,67 @@ mod scalars {
487487
}
488488
}
489489
}
490+
491+
unsafe impl<T> GodotFfi for Option<T>
492+
where
493+
T: GodotFfi,
494+
{
495+
fn sys(&self) -> sys::GDExtensionTypePtr {
496+
match self {
497+
Some(value) => value.sys(),
498+
None => {
499+
let nil_ptr = ptr::null_mut();
500+
let new_nil = interface_fn!(variant_new_nil);
501+
502+
unsafe {
503+
new_nil(nil_ptr);
504+
}
505+
506+
nil_ptr as sys::GDExtensionTypePtr
507+
}
508+
}
509+
}
510+
511+
unsafe fn from_sys(ptr: sys::GDExtensionTypePtr) -> Self {
512+
let nil_ptr = ptr::null_mut();
513+
514+
interface_fn!(variant_new_nil)(nil_ptr);
515+
516+
if ptr as sys::GDExtensionVariantPtr == nil_ptr {
517+
return None;
518+
}
519+
520+
Some(T::from_sys(ptr))
521+
}
522+
523+
unsafe fn from_sys_init(init_fn: impl FnOnce(sys::GDExtensionTypePtr)) -> Self {
524+
let mut raw = std::mem::MaybeUninit::uninit();
525+
init_fn(raw.as_mut_ptr() as sys::GDExtensionTypePtr);
526+
527+
Self::from_sys(raw.assume_init())
528+
}
529+
530+
unsafe fn from_arg_ptr(ptr: sys::GDExtensionTypePtr, call_type: PtrcallType) -> Self {
531+
let nil_ptr = ptr::null_mut();
532+
533+
interface_fn!(variant_new_nil)(nil_ptr);
534+
535+
if ptr as sys::GDExtensionVariantPtr == nil_ptr {
536+
return None;
537+
}
538+
539+
Some(T::from_arg_ptr(ptr, call_type))
540+
}
541+
542+
unsafe fn move_return_ptr(self, ptr: sys::GDExtensionTypePtr, call_type: PtrcallType) {
543+
match self {
544+
Some(gd) => gd.move_return_ptr(ptr, call_type),
545+
None => {
546+
let nil_ptr = ptr::null_mut();
547+
548+
interface_fn!(variant_new_nil)(nil_ptr);
549+
std::ptr::write(ptr as *mut _, nil_ptr as sys::GDExtensionTypePtr)
550+
}
551+
}
552+
}
553+
}

0 commit comments

Comments
 (0)