|
4 | 4 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
5 | 5 | */
|
6 | 6 |
|
7 |
| -use crate as sys; |
8 |
| -use std::fmt::Debug; |
| 7 | +use crate::{self as sys, interface_fn}; |
| 8 | +use std::{fmt::Debug, ptr}; |
9 | 9 |
|
10 | 10 | /// Adds methods to convert from and to Godot FFI pointers.
|
11 | 11 | /// See [crate::ffi_methods] for ergonomic implementation.
|
@@ -487,3 +487,67 @@ mod scalars {
|
487 | 487 | }
|
488 | 488 | }
|
489 | 489 | }
|
| 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