Skip to content

Commit 0d1f4d1

Browse files
authored
Merge pull request #944 from godot-rust/feature/callable-by-ref
`Callable` is now passed by-ref
2 parents 9e4f380 + 856842c commit 0d1f4d1

File tree

13 files changed

+33
-53
lines changed

13 files changed

+33
-53
lines changed

examples/dodge-the-creeps/rust/src/hud.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl Hud {
2626
self.show_message("Game Over".into());
2727

2828
let mut timer = self.base().get_tree().unwrap().create_timer(2.0).unwrap();
29-
timer.connect("timeout", self.base().callable("show_start_button"));
29+
timer.connect("timeout", &self.base().callable("show_start_button"));
3030
}
3131

3232
#[func]

examples/dodge-the-creeps/rust/src/main_scene.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl Main {
102102
mob.set_linear_velocity(Vector2::new(range, 0.0).rotated(real::from_f32(direction)));
103103

104104
let mut hud = self.base().get_node_as::<Hud>("Hud");
105-
hud.connect("start_game", mob.callable("on_start_game"));
105+
hud.connect("start_game", &mob.callable("on_start_game"));
106106
}
107107

108108
fn music(&mut self) -> &mut AudioStreamPlayer {

godot-codegen/src/context.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,17 @@ impl<'a> Context<'a> {
243243
self.builtin_types.contains(ty_name)
244244
}
245245

246-
pub fn get_builtin_arg_passing(&self, ty_name: &str) -> ArgPassing {
246+
pub fn get_builtin_arg_passing(&self, godot_ty: &GodotTy) -> ArgPassing {
247247
// Already handled separately.
248-
debug_assert!(!ty_name.starts_with("Packed"));
248+
debug_assert!(!godot_ty.ty.starts_with("Packed"));
249+
250+
// IMPORTANT: Keep this in sync with impl_ffi_variant!() macros taking `ref` or not.
249251

250252
// Arrays are also handled separately, and use ByRef.
251-
match ty_name {
252-
"Variant" | "VariantArray" | "Dictionary" => ArgPassing::ByRef,
253-
"GString" | "NodePath" | "StringName" => ArgPassing::ImplAsArg,
253+
match godot_ty.ty.as_str() {
254+
// Note: Signal is currently not used in any parameter, but this may change.
255+
"Variant" | "Array" | "Dictionary" | "Callable" | "Signal" => ArgPassing::ByRef,
256+
"String" | "StringName" | "NodePath" => ArgPassing::ImplAsArg,
254257
_ => ArgPassing::ByValue,
255258
}
256259
}

godot-codegen/src/conv/type_conversions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {
179179
if let Some(hardcoded) = to_hardcoded_rust_ident(full_ty) {
180180
return RustTy::BuiltinIdent {
181181
ty: ident(hardcoded),
182-
arg_passing: ctx.get_builtin_arg_passing(hardcoded),
182+
arg_passing: ctx.get_builtin_arg_passing(full_ty),
183183
};
184184
}
185185
}
@@ -224,7 +224,7 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {
224224
// Native structures might not all be Copy, but they should have value semantics.
225225
RustTy::BuiltinIdent {
226226
ty: rustify_ty(ty),
227-
arg_passing: ctx.get_builtin_arg_passing(ty),
227+
arg_passing: ctx.get_builtin_arg_passing(full_ty),
228228
}
229229
} else {
230230
let ty = rustify_ty(ty);

godot-codegen/src/models/domain.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -663,28 +663,6 @@ impl RustTy {
663663
other => quote! { -> #other },
664664
}
665665
}
666-
667-
pub fn is_pass_by_ref(&self) -> bool {
668-
matches!(
669-
self,
670-
RustTy::BuiltinIdent {
671-
arg_passing: ArgPassing::ByRef,
672-
..
673-
} | RustTy::BuiltinArray { .. }
674-
| RustTy::EngineArray { .. }
675-
)
676-
}
677-
678-
pub fn needs_lifetime(&self) -> bool {
679-
matches!(
680-
self,
681-
RustTy::BuiltinIdent {
682-
arg_passing: ArgPassing::ByRef | ArgPassing::ImplAsArg,
683-
..
684-
} | RustTy::BuiltinArray { .. }
685-
| RustTy::EngineArray { .. }
686-
)
687-
}
688666
}
689667

690668
impl ToTokens for RustTy {

godot-core/src/builtin/collections/array.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ impl<T: ArrayElement> Array<T> {
614614
///
615615
/// Consider using `sort_custom()` to ensure the sorting order is compatible with
616616
/// your callable's ordering
617-
pub fn bsearch_custom(&self, value: impl AsArg<T>, func: Callable) -> usize {
617+
pub fn bsearch_custom(&self, value: impl AsArg<T>, func: &Callable) -> usize {
618618
meta::arg_into_ref!(value: T);
619619

620620
to_usize(
@@ -646,7 +646,7 @@ impl<T: ArrayElement> Array<T> {
646646
/// Note: The sorting algorithm used is not [stable](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability).
647647
/// This means that values considered equal may have their order changed when using `sort_unstable_custom`.
648648
#[doc(alias = "sort_custom")]
649-
pub fn sort_unstable_custom(&mut self, func: Callable) {
649+
pub fn sort_unstable_custom(&mut self, func: &Callable) {
650650
// SAFETY: We do not write any values that don't already exist in the array, so all values have the correct type.
651651
unsafe { self.as_inner_mut() }.sort_custom(func);
652652
}

godot-core/src/builtin/signal.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl Signal {
7474
/// returns [`Error::ERR_INVALID_PARAMETER`] and
7575
/// pushes an error message, unless the signal is connected with [`ConnectFlags::REFERENCE_COUNTED`](crate::classes::object::ConnectFlags::REFERENCE_COUNTED).
7676
/// To prevent this, use [`Self::is_connected`] first to check for existing connections.
77-
pub fn connect(&self, callable: Callable, flags: i64) -> Error {
77+
pub fn connect(&self, callable: &Callable, flags: i64) -> Error {
7878
let error = self.as_inner().connect(callable, flags);
7979

8080
Error::from_godot(error as i32)
@@ -83,7 +83,7 @@ impl Signal {
8383
/// Disconnects this signal from the specified [`Callable`].
8484
///
8585
/// If the connection does not exist, generates an error. Use [`Self::is_connected`] to make sure that the connection exists.
86-
pub fn disconnect(&self, callable: Callable) {
86+
pub fn disconnect(&self, callable: &Callable) {
8787
self.as_inner().disconnect(callable);
8888
}
8989

@@ -142,7 +142,7 @@ impl Signal {
142142
}
143143

144144
/// Returns `true` if the specified [`Callable`] is connected to this signal.
145-
pub fn is_connected(&self, callable: Callable) -> bool {
145+
pub fn is_connected(&self, callable: &Callable) -> bool {
146146
self.as_inner().is_connected(callable)
147147
}
148148

godot-core/src/builtin/variant/impls.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,10 @@ macro_rules! impl_ffi_variant {
130130
#[allow(clippy::module_inception)]
131131
mod impls {
132132
use super::*;
133+
134+
// IMPORTANT: the presence/absence of `ref` here should be aligned with the ArgPassing variant
135+
// used in codegen get_builtin_arg_passing().
133136

134-
// Also implements ArrayType.
135137
impl_ffi_variant!(bool, bool_to_variant, bool_from_variant);
136138
impl_ffi_variant!(i64, int_to_variant, int_from_variant; int);
137139
impl_ffi_variant!(f64, float_to_variant, float_from_variant; float);

godot-core/src/meta/rpc_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::classes::Node;
1212
use crate::meta::{AsArg, ToGodot};
1313
use crate::{arg_into_ref, dict};
1414

15-
/// Configuration for a remote procedure call, typically used with `#[rpc(config = ...)]`.
15+
/// Configuration for a remote procedure call, used with `#[rpc(config = ...)]`.
1616
///
1717
/// See [Godot documentation](https://docs.godotengine.org/en/stable/tutorials/networking/high_level_multiplayer.html#remote-procedure-calls).
1818
#[derive(Copy, Clone, Debug)]

itest/rust/src/builtin_tests/containers/array_test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ fn array_should_format_with_display() {
479479
fn array_sort_custom() {
480480
let mut a = array![1, 2, 3, 4];
481481
let func = backwards_sort_callable();
482-
a.sort_unstable_custom(func);
482+
a.sort_unstable_custom(&func);
483483
assert_eq!(a, array![4, 3, 2, 1]);
484484
}
485485

@@ -488,8 +488,8 @@ fn array_sort_custom() {
488488
fn array_binary_search_custom() {
489489
let a = array![5, 4, 2, 1];
490490
let func = backwards_sort_callable();
491-
assert_eq!(a.bsearch_custom(1, func.clone()), 3);
492-
assert_eq!(a.bsearch_custom(3, func), 2);
491+
assert_eq!(a.bsearch_custom(1, &func), 3);
492+
assert_eq!(a.bsearch_custom(3, &func), 2);
493493
}
494494

495495
#[cfg(since_api = "4.2")]

0 commit comments

Comments
 (0)