Skip to content

Commit 1da68dd

Browse files
committed
Implement DynGd::null_arg()
1 parent 6274bd8 commit 1da68dd

File tree

5 files changed

+52
-18
lines changed

5 files changed

+52
-18
lines changed

godot-core/src/meta/args/as_arg.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,42 @@ where
224224
}
225225
}
226226

227+
// ----------------------------------------------------------------------------------------------------------------------------------------------
228+
// Null arguments
229+
230+
/// Private struct for passing null arguments to optional object parameters.
231+
///
232+
/// This struct implements `AsArg` for both `Option<Gd<T>>` and `Option<DynGd<T, D>>`, allowing [`Gd::null_arg()`] and [`DynGd::null_arg()`]
233+
/// to share implementation.
234+
///
235+
/// Not public, as `impl AsArg<...>` is used by `null_arg()` methods.
236+
pub(crate) struct NullArg<T>(pub std::marker::PhantomData<*mut T>);
237+
238+
impl<T> AsArg<Option<Gd<T>>> for NullArg<T>
239+
where
240+
T: GodotClass,
241+
{
242+
fn into_arg<'arg>(self) -> CowArg<'arg, Option<Gd<T>>>
243+
where
244+
Self: 'arg,
245+
{
246+
CowArg::Owned(None)
247+
}
248+
}
249+
250+
impl<T, D> AsArg<Option<DynGd<T, D>>> for NullArg<T>
251+
where
252+
T: GodotClass,
253+
D: ?Sized + 'static,
254+
{
255+
fn into_arg<'arg>(self) -> CowArg<'arg, Option<DynGd<T, D>>>
256+
where
257+
Self: 'arg,
258+
{
259+
CowArg::Owned(None)
260+
}
261+
}
262+
227263
// ----------------------------------------------------------------------------------------------------------------------------------------------
228264
// Optional object (Gd + DynGd) impls
229265

godot-core/src/meta/args/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod ref_arg;
1616
pub use as_arg::{
1717
owned_into_arg, ref_to_arg, ArgPassing, AsArg, ByObject, ByOption, ByRef, ByValue, ToArg,
1818
};
19+
1920
// ----------------------------------------------------------------------------------------------------------------------------------------------
2021
// Internal APIs
2122

@@ -29,6 +30,8 @@ pub(crate) use cow_arg::{CowArg, FfiArg};
2930
pub use object_arg::ObjectArg;
3031
pub use ref_arg::RefArg;
3132

33+
pub(crate) use as_arg::NullArg;
34+
3235
// #[doc(hidden)]
3336
// pub use cow_arg::*;
3437
//

godot-core/src/obj/dyn_gd.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,13 @@ where
403403
pub fn into_gd(self) -> Gd<T> {
404404
self.obj
405405
}
406+
407+
/// Represents `null` when passing a dynamic object argument to Godot.
408+
///
409+
/// See [`Gd::null_arg()`]
410+
pub fn null_arg() -> impl meta::AsArg<Option<DynGd<T, D>>> {
411+
meta::NullArg(std::marker::PhantomData)
412+
}
406413
}
407414

408415
impl<T, D> DynGd<T, D>

godot-core/src/obj/gd.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -816,22 +816,7 @@ where
816816
/// let mut shape: Gd<Node> = some_node();
817817
/// shape.set_owner(Gd::null_arg());
818818
pub fn null_arg() -> impl AsArg<Option<Gd<T>>> {
819-
// Anonymous struct that creates None for optional object arguments.
820-
struct NullGdArg<T>(std::marker::PhantomData<*mut T>);
821-
822-
impl<T> AsArg<Option<Gd<T>>> for NullGdArg<T>
823-
where
824-
T: GodotClass,
825-
{
826-
fn into_arg<'arg>(self) -> CowArg<'arg, Option<Gd<T>>>
827-
where
828-
Self: 'arg,
829-
{
830-
CowArg::Owned(None)
831-
}
832-
}
833-
834-
NullGdArg(std::marker::PhantomData)
819+
meta::NullArg(std::marker::PhantomData)
835820
}
836821
}
837822

itest/rust/src/object_tests/dyn_gd_test.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,9 @@ fn dyn_gd_as_arg() {
451451
Some(&refc_health),
452452
Some(&node_health),
453453
typed_none,
454-
// Gd::null_arg(),
454+
DynGd::null_arg(),
455455
];
456-
assert_eq!(opt_array.len(), 3);
456+
assert_eq!(opt_array.len(), 4);
457457

458458
let first = opt_array.at(0).expect("element 0 is Some");
459459
assert_eq!(first.dyn_bind().get_hitpoints(), 42);
@@ -464,6 +464,9 @@ fn dyn_gd_as_arg() {
464464
let third = opt_array.at(2);
465465
assert!(third.is_none(), "element 2 is None");
466466

467+
let fourth = opt_array.at(3);
468+
assert!(fourth.is_none(), "element 3 is None (null_arg)");
469+
467470
// Clean up manually managed objects.
468471
opt_array.at(1).unwrap().free();
469472
}

0 commit comments

Comments
 (0)