Skip to content

Commit e86388f

Browse files
authored
Merge pull request #940 from godot-rust/feature/string-args
String argument conversion + `AsArg` trait
2 parents 19147e8 + 12778bd commit e86388f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1708
-847
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl Hud {
1515
#[func]
1616
pub fn show_message(&self, text: GString) {
1717
let mut message_label = self.base().get_node_as::<Label>("MessageLabel");
18-
message_label.set_text(text);
18+
message_label.set_text(&text);
1919
message_label.show();
2020

2121
let mut timer = self.base().get_node_as::<Timer>("MessageTimer");
@@ -26,13 +26,13 @@ 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".into(), self.base().callable("show_start_button"));
29+
timer.connect("timeout", self.base().callable("show_start_button"));
3030
}
3131

3232
#[func]
3333
fn show_start_button(&mut self) {
3434
let mut message_label = self.base().get_node_as::<Label>("MessageLabel");
35-
message_label.set_text("Dodge the\nCreeps!".into());
35+
message_label.set_text("Dodge the\nCreeps!");
3636
message_label.show();
3737

3838
let mut button = self.base().get_node_as::<Button>("StartButton");
@@ -43,7 +43,7 @@ impl Hud {
4343
pub fn update_score(&self, score: i64) {
4444
let mut label = self.base().get_node_as::<Label>("ScoreLabel");
4545

46-
label.set_text(score.to_string().into());
46+
label.set_text(&score.to_string());
4747
}
4848

4949
#[func]
@@ -55,7 +55,7 @@ impl Hud {
5555
// This method keeps a &mut Hud, and start_game calls Main::new_game(), which itself accesses this Hud
5656
// instance through Gd<Hud>::bind_mut(). It will try creating a 2nd &mut reference, and thus panic.
5757
// Deferring the signal is one option to work around it.
58-
self.base_mut().emit_signal("start_game".into(), &[]);
58+
self.base_mut().emit_signal("start_game", &[]);
5959
}
6060

6161
#[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".into(), mob.callable("on_start_game"));
105+
hud.connect("start_game", mob.callable("on_start_game"));
106106
}
107107

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ impl IRigidBody2D for Mob {
4747
let mut rng = rand::thread_rng();
4848
let animation_name = anim_names.choose(&mut rng).unwrap();
4949

50-
sprite.set_animation(animation_name.into());
50+
sprite.set_animation(animation_name.arg());
5151
}
5252
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ impl Player {
1818
#[func]
1919
fn on_player_body_entered(&mut self, _body: Gd<PhysicsBody2D>) {
2020
self.base_mut().hide();
21-
self.base_mut().emit_signal("hit".into(), &[]);
21+
self.base_mut().emit_signal("hit", &[]);
2222

2323
let mut collision_shape = self
2424
.base()
2525
.get_node_as::<CollisionShape2D>("CollisionShape2D");
2626

27-
collision_shape.set_deferred("disabled".into(), &true.to_variant());
27+
collision_shape.set_deferred("disabled", &true.to_variant());
2828
}
2929

3030
#[func]
@@ -65,16 +65,16 @@ impl IArea2D for Player {
6565

6666
// Note: exact=false by default, in Rust we have to provide it explicitly
6767
let input = Input::singleton();
68-
if input.is_action_pressed("move_right".into()) {
68+
if input.is_action_pressed("move_right") {
6969
velocity += Vector2::RIGHT;
7070
}
71-
if input.is_action_pressed("move_left".into()) {
71+
if input.is_action_pressed("move_left") {
7272
velocity += Vector2::LEFT;
7373
}
74-
if input.is_action_pressed("move_down".into()) {
74+
if input.is_action_pressed("move_down") {
7575
velocity += Vector2::DOWN;
7676
}
77-
if input.is_action_pressed("move_up".into()) {
77+
if input.is_action_pressed("move_up") {
7878
velocity += Vector2::UP;
7979
}
8080

@@ -94,7 +94,7 @@ impl IArea2D for Player {
9494
animated_sprite.set_flip_v(velocity.y > 0.0)
9595
}
9696

97-
animated_sprite.play_ex().name(animation.into()).done();
97+
animated_sprite.play_ex().name(animation).done();
9898
} else {
9999
animated_sprite.stop();
100100
}

godot-bindings/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ mod depend_on_prebuilt {
115115
.get(2)
116116
.and_then(|patch| patch.parse().ok())
117117
.unwrap_or(0),
118-
status: "stable".into(),
118+
status: "stable".to_string(),
119119
custom_rev: None,
120120
}
121121
}

godot-codegen/src/context.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use crate::generator::method_tables::MethodTableKey;
99
use crate::generator::notifications;
10-
use crate::models::domain::{GodotTy, RustTy, TyName};
10+
use crate::models::domain::{ArgPassing, GodotTy, RustTy, TyName};
1111
use crate::models::json::{
1212
JsonBuiltinClass, JsonBuiltinMethod, JsonClass, JsonClassConstant, JsonClassMethod,
1313
};
@@ -243,10 +243,16 @@ impl<'a> Context<'a> {
243243
self.builtin_types.contains(ty_name)
244244
}
245245

246-
pub fn is_builtin_copy(&self, ty_name: &str) -> bool {
247-
debug_assert!(!ty_name.starts_with("Packed")); // Already handled separately.
246+
pub fn get_builtin_arg_passing(&self, ty_name: &str) -> ArgPassing {
247+
// Already handled separately.
248+
debug_assert!(!ty_name.starts_with("Packed"));
248249

249-
!matches!(ty_name, "Variant" | "VariantArray" | "Dictionary")
250+
// Arrays are also handled separately, and use ByRef.
251+
match ty_name {
252+
"Variant" | "VariantArray" | "Dictionary" => ArgPassing::ByRef,
253+
"GString" | "NodePath" | "StringName" => ArgPassing::ImplAsArg,
254+
_ => ArgPassing::ByValue,
255+
}
250256
}
251257

252258
pub fn is_native_structure(&self, ty_name: &str) -> bool {

godot-codegen/src/conv/type_conversions.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::fmt;
1313

1414
use crate::context::Context;
1515
use crate::conv;
16-
use crate::models::domain::{GodotTy, ModName, RustTy, TyName};
16+
use crate::models::domain::{ArgPassing, GodotTy, ModName, RustTy, TyName};
1717
use crate::special_cases::is_builtin_type_scalar;
1818
use crate::util::ident;
1919

@@ -98,22 +98,22 @@ pub(crate) fn to_rust_type_abi(ty: &str, ctx: &mut Context) -> (RustTy, bool) {
9898
RustTy::RawPointer {
9999
inner: Box::new(RustTy::BuiltinIdent {
100100
ty: ident("c_void"),
101-
is_copy: true,
101+
arg_passing: ArgPassing::ByValue,
102102
}),
103103
is_const: false,
104104
}
105105
}
106106
"int" => RustTy::BuiltinIdent {
107107
ty: ident("i32"),
108-
is_copy: true,
108+
arg_passing: ArgPassing::ByValue,
109109
},
110110
"float" => RustTy::BuiltinIdent {
111111
ty: ident("f32"),
112-
is_copy: true,
112+
arg_passing: ArgPassing::ByValue,
113113
},
114114
"double" => RustTy::BuiltinIdent {
115115
ty: ident("f64"),
116-
is_copy: true,
116+
arg_passing: ArgPassing::ByValue,
117117
},
118118
_ => to_rust_type(ty, None, ctx),
119119
};
@@ -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-
is_copy: ctx.is_builtin_copy(hardcoded),
182+
arg_passing: ctx.get_builtin_arg_passing(hardcoded),
183183
};
184184
}
185185
}
@@ -201,7 +201,7 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {
201201
if packed_arr_ty.ends_with("Array") {
202202
return RustTy::BuiltinIdent {
203203
ty: rustify_ty(ty),
204-
is_copy: false, // Packed arrays are not Copy.
204+
arg_passing: ArgPassing::ByRef, // Packed arrays are passed by-ref.
205205
};
206206
}
207207
} else if let Some(elem_ty) = ty.strip_prefix("typedarray::") {
@@ -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-
is_copy: ctx.is_builtin_copy(ty),
227+
arg_passing: ctx.get_builtin_arg_passing(ty),
228228
}
229229
} else {
230230
let ty = rustify_ty(ty);
@@ -461,25 +461,25 @@ fn gdscript_to_rust_expr() {
461461

462462
let ty_int = RustTy::BuiltinIdent {
463463
ty: ident("i64"),
464-
is_copy: true,
464+
arg_passing: ArgPassing::ByValue,
465465
};
466466
let ty_int = Some(&ty_int);
467467

468468
let ty_int_u16 = RustTy::BuiltinIdent {
469469
ty: ident("u16"),
470-
is_copy: true,
470+
arg_passing: ArgPassing::ByValue,
471471
};
472472
let ty_int_u16 = Some(&ty_int_u16);
473473

474474
let ty_float = RustTy::BuiltinIdent {
475475
ty: ident("f64"),
476-
is_copy: true,
476+
arg_passing: ArgPassing::ByValue,
477477
};
478478
let ty_float = Some(&ty_float);
479479

480480
let ty_float_f32 = RustTy::BuiltinIdent {
481481
ty: ident("f32"),
482-
is_copy: true,
482+
arg_passing: ArgPassing::ByValue,
483483
};
484484
let ty_float_f32 = Some(&ty_float_f32);
485485

@@ -499,7 +499,7 @@ fn gdscript_to_rust_expr() {
499499

500500
let ty_variant = RustTy::BuiltinIdent {
501501
ty: ident("Variant"),
502-
is_copy: false,
502+
arg_passing: ArgPassing::ByRef,
503503
};
504504
let ty_variant = Some(&ty_variant);
505505

@@ -511,19 +511,19 @@ fn gdscript_to_rust_expr() {
511511

512512
let ty_string = RustTy::BuiltinIdent {
513513
ty: ident("GString"),
514-
is_copy: true,
514+
arg_passing: ArgPassing::ImplAsArg,
515515
};
516516
let ty_string = Some(&ty_string);
517517

518518
let ty_stringname = RustTy::BuiltinIdent {
519519
ty: ident("StringName"),
520-
is_copy: true,
520+
arg_passing: ArgPassing::ImplAsArg,
521521
};
522522
let ty_stringname = Some(&ty_stringname);
523523

524524
let ty_nodepath = RustTy::BuiltinIdent {
525525
ty: ident("NodePath"),
526-
is_copy: true,
526+
arg_passing: ArgPassing::ImplAsArg,
527527
};
528528
let ty_nodepath = Some(&ty_nodepath);
529529

0 commit comments

Comments
 (0)