Skip to content

Commit

Permalink
Option<Gd<T>> does not implement ToVariant godot-rust#240
Browse files Browse the repository at this point in the history
  • Loading branch information
TitanNano committed Apr 27, 2023
1 parent bab1070 commit 7a48845
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
9 changes: 9 additions & 0 deletions godot-core/src/obj/gd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,15 @@ impl<T: GodotClass> ToVariant for Gd<T> {
}
}

impl<T: GodotClass> ToVariant for Option<Gd<T>> {
fn to_variant(&self) -> Variant {
match self {
Some(gd) => gd.to_variant(),
None => Variant::nil(),
}
}
}

impl<T: GodotClass> PartialEq for Gd<T> {
/// ⚠️ Returns whether two `Gd` pointers point to the same object.
///
Expand Down
68 changes: 66 additions & 2 deletions godot-ffi/src/godot_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

use crate as sys;
use std::fmt::Debug;
use crate::{self as sys, interface_fn};
use std::{fmt::Debug, ptr};

/// Adds methods to convert from and to Godot FFI pointers.
/// See [crate::ffi_methods] for ergonomic implementation.
Expand Down Expand Up @@ -487,3 +487,67 @@ mod scalars {
}
}
}

unsafe impl<T> GodotFfi for Option<T>
where
T: GodotFfi,
{
fn sys(&self) -> sys::GDExtensionTypePtr {
match self {
Some(value) => value.sys(),
None => {
let nil_ptr = ptr::null_mut();
let new_nil = interface_fn!(variant_new_nil);

unsafe {
new_nil(nil_ptr);
}

nil_ptr as sys::GDExtensionTypePtr
}
}
}

unsafe fn from_sys(ptr: sys::GDExtensionTypePtr) -> Self {
let nil_ptr = ptr::null_mut();

interface_fn!(variant_new_nil)(nil_ptr);

if ptr as sys::GDExtensionVariantPtr == nil_ptr {
return None;
}

Some(T::from_sys(ptr))
}

unsafe fn from_sys_init(init_fn: impl FnOnce(sys::GDExtensionTypePtr)) -> Self {
let mut raw = std::mem::MaybeUninit::uninit();
init_fn(raw.as_mut_ptr() as sys::GDExtensionTypePtr);

Self::from_sys(raw.assume_init())
}

unsafe fn from_arg_ptr(ptr: sys::GDExtensionTypePtr, call_type: PtrcallType) -> Self {
let nil_ptr = ptr::null_mut();

interface_fn!(variant_new_nil)(nil_ptr);

if ptr as sys::GDExtensionVariantPtr == nil_ptr {
return None;
}

Some(T::from_arg_ptr(ptr, call_type))
}

unsafe fn move_return_ptr(self, ptr: sys::GDExtensionTypePtr, call_type: PtrcallType) {
match self {
Some(gd) => gd.move_return_ptr(ptr, call_type),
None => {
let nil_ptr = ptr::null_mut();

interface_fn!(variant_new_nil)(nil_ptr);
std::ptr::write(ptr as *mut _, nil_ptr as sys::GDExtensionTypePtr)
}
}
}
}

0 comments on commit 7a48845

Please sign in to comment.