Skip to content

Commit

Permalink
Merge pull request #940 from godot-rust/feature/string-args
Browse files Browse the repository at this point in the history
String argument conversion + `AsArg` trait
  • Loading branch information
Bromeon authored Nov 5, 2024
2 parents 19147e8 + 12778bd commit e86388f
Show file tree
Hide file tree
Showing 73 changed files with 1,708 additions and 847 deletions.
10 changes: 5 additions & 5 deletions examples/dodge-the-creeps/rust/src/hud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Hud {
#[func]
pub fn show_message(&self, text: GString) {
let mut message_label = self.base().get_node_as::<Label>("MessageLabel");
message_label.set_text(text);
message_label.set_text(&text);
message_label.show();

let mut timer = self.base().get_node_as::<Timer>("MessageTimer");
Expand All @@ -26,13 +26,13 @@ impl Hud {
self.show_message("Game Over".into());

let mut timer = self.base().get_tree().unwrap().create_timer(2.0).unwrap();
timer.connect("timeout".into(), self.base().callable("show_start_button"));
timer.connect("timeout", self.base().callable("show_start_button"));
}

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

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

label.set_text(score.to_string().into());
label.set_text(&score.to_string());
}

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

#[func]
Expand Down
2 changes: 1 addition & 1 deletion examples/dodge-the-creeps/rust/src/main_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl Main {
mob.set_linear_velocity(Vector2::new(range, 0.0).rotated(real::from_f32(direction)));

let mut hud = self.base().get_node_as::<Hud>("Hud");
hud.connect("start_game".into(), mob.callable("on_start_game"));
hud.connect("start_game", mob.callable("on_start_game"));
}

fn music(&mut self) -> &mut AudioStreamPlayer {
Expand Down
2 changes: 1 addition & 1 deletion examples/dodge-the-creeps/rust/src/mob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ impl IRigidBody2D for Mob {
let mut rng = rand::thread_rng();
let animation_name = anim_names.choose(&mut rng).unwrap();

sprite.set_animation(animation_name.into());
sprite.set_animation(animation_name.arg());
}
}
14 changes: 7 additions & 7 deletions examples/dodge-the-creeps/rust/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ impl Player {
#[func]
fn on_player_body_entered(&mut self, _body: Gd<PhysicsBody2D>) {
self.base_mut().hide();
self.base_mut().emit_signal("hit".into(), &[]);
self.base_mut().emit_signal("hit", &[]);

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

collision_shape.set_deferred("disabled".into(), &true.to_variant());
collision_shape.set_deferred("disabled", &true.to_variant());
}

#[func]
Expand Down Expand Up @@ -65,16 +65,16 @@ impl IArea2D for Player {

// Note: exact=false by default, in Rust we have to provide it explicitly
let input = Input::singleton();
if input.is_action_pressed("move_right".into()) {
if input.is_action_pressed("move_right") {
velocity += Vector2::RIGHT;
}
if input.is_action_pressed("move_left".into()) {
if input.is_action_pressed("move_left") {
velocity += Vector2::LEFT;
}
if input.is_action_pressed("move_down".into()) {
if input.is_action_pressed("move_down") {
velocity += Vector2::DOWN;
}
if input.is_action_pressed("move_up".into()) {
if input.is_action_pressed("move_up") {
velocity += Vector2::UP;
}

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

animated_sprite.play_ex().name(animation.into()).done();
animated_sprite.play_ex().name(animation).done();
} else {
animated_sprite.stop();
}
Expand Down
2 changes: 1 addition & 1 deletion godot-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ mod depend_on_prebuilt {
.get(2)
.and_then(|patch| patch.parse().ok())
.unwrap_or(0),
status: "stable".into(),
status: "stable".to_string(),
custom_rev: None,
}
}
Expand Down
14 changes: 10 additions & 4 deletions godot-codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

use crate::generator::method_tables::MethodTableKey;
use crate::generator::notifications;
use crate::models::domain::{GodotTy, RustTy, TyName};
use crate::models::domain::{ArgPassing, GodotTy, RustTy, TyName};
use crate::models::json::{
JsonBuiltinClass, JsonBuiltinMethod, JsonClass, JsonClassConstant, JsonClassMethod,
};
Expand Down Expand Up @@ -243,10 +243,16 @@ impl<'a> Context<'a> {
self.builtin_types.contains(ty_name)
}

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

!matches!(ty_name, "Variant" | "VariantArray" | "Dictionary")
// Arrays are also handled separately, and use ByRef.
match ty_name {
"Variant" | "VariantArray" | "Dictionary" => ArgPassing::ByRef,
"GString" | "NodePath" | "StringName" => ArgPassing::ImplAsArg,
_ => ArgPassing::ByValue,
}
}

pub fn is_native_structure(&self, ty_name: &str) -> bool {
Expand Down
32 changes: 16 additions & 16 deletions godot-codegen/src/conv/type_conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::fmt;

use crate::context::Context;
use crate::conv;
use crate::models::domain::{GodotTy, ModName, RustTy, TyName};
use crate::models::domain::{ArgPassing, GodotTy, ModName, RustTy, TyName};
use crate::special_cases::is_builtin_type_scalar;
use crate::util::ident;

Expand Down Expand Up @@ -98,22 +98,22 @@ pub(crate) fn to_rust_type_abi(ty: &str, ctx: &mut Context) -> (RustTy, bool) {
RustTy::RawPointer {
inner: Box::new(RustTy::BuiltinIdent {
ty: ident("c_void"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
}),
is_const: false,
}
}
"int" => RustTy::BuiltinIdent {
ty: ident("i32"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
},
"float" => RustTy::BuiltinIdent {
ty: ident("f32"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
},
"double" => RustTy::BuiltinIdent {
ty: ident("f64"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
},
_ => to_rust_type(ty, None, ctx),
};
Expand Down Expand Up @@ -179,7 +179,7 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {
if let Some(hardcoded) = to_hardcoded_rust_ident(full_ty) {
return RustTy::BuiltinIdent {
ty: ident(hardcoded),
is_copy: ctx.is_builtin_copy(hardcoded),
arg_passing: ctx.get_builtin_arg_passing(hardcoded),
};
}
}
Expand All @@ -201,7 +201,7 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {
if packed_arr_ty.ends_with("Array") {
return RustTy::BuiltinIdent {
ty: rustify_ty(ty),
is_copy: false, // Packed arrays are not Copy.
arg_passing: ArgPassing::ByRef, // Packed arrays are passed by-ref.
};
}
} else if let Some(elem_ty) = ty.strip_prefix("typedarray::") {
Expand All @@ -224,7 +224,7 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {
// Native structures might not all be Copy, but they should have value semantics.
RustTy::BuiltinIdent {
ty: rustify_ty(ty),
is_copy: ctx.is_builtin_copy(ty),
arg_passing: ctx.get_builtin_arg_passing(ty),
}
} else {
let ty = rustify_ty(ty);
Expand Down Expand Up @@ -461,25 +461,25 @@ fn gdscript_to_rust_expr() {

let ty_int = RustTy::BuiltinIdent {
ty: ident("i64"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
};
let ty_int = Some(&ty_int);

let ty_int_u16 = RustTy::BuiltinIdent {
ty: ident("u16"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
};
let ty_int_u16 = Some(&ty_int_u16);

let ty_float = RustTy::BuiltinIdent {
ty: ident("f64"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
};
let ty_float = Some(&ty_float);

let ty_float_f32 = RustTy::BuiltinIdent {
ty: ident("f32"),
is_copy: true,
arg_passing: ArgPassing::ByValue,
};
let ty_float_f32 = Some(&ty_float_f32);

Expand All @@ -499,7 +499,7 @@ fn gdscript_to_rust_expr() {

let ty_variant = RustTy::BuiltinIdent {
ty: ident("Variant"),
is_copy: false,
arg_passing: ArgPassing::ByRef,
};
let ty_variant = Some(&ty_variant);

Expand All @@ -511,19 +511,19 @@ fn gdscript_to_rust_expr() {

let ty_string = RustTy::BuiltinIdent {
ty: ident("GString"),
is_copy: true,
arg_passing: ArgPassing::ImplAsArg,
};
let ty_string = Some(&ty_string);

let ty_stringname = RustTy::BuiltinIdent {
ty: ident("StringName"),
is_copy: true,
arg_passing: ArgPassing::ImplAsArg,
};
let ty_stringname = Some(&ty_stringname);

let ty_nodepath = RustTy::BuiltinIdent {
ty: ident("NodePath"),
is_copy: true,
arg_passing: ArgPassing::ImplAsArg,
};
let ty_nodepath = Some(&ty_nodepath);

Expand Down
Loading

0 comments on commit e86388f

Please sign in to comment.