Skip to content

Implement owner argument inference #633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions examples/dodge_the_creeps/src/hud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ impl HUD {
});
}

fn new(_owner: &CanvasLayer) -> Self {
fn new(_owner: _) -> Self {
HUD
}

#[export]
pub fn show_message(&self, owner: &CanvasLayer, text: String) {
pub fn show_message(&self, owner: _, text: String) {
let message_label = unsafe { owner.get_typed_node::<Label, _>("message_label") };
message_label.set_text(text);
message_label.show();
Expand All @@ -30,7 +30,7 @@ impl HUD {
timer.start(0.0);
}

pub fn show_game_over(&self, owner: &CanvasLayer) {
pub fn show_game_over(&self, owner: TRef<CanvasLayer>) {
self.show_message(owner, "Game Over".into());

let message_label = unsafe { owner.get_typed_node::<Label, _>("message_label") };
Expand All @@ -42,20 +42,20 @@ impl HUD {
}

#[export]
pub fn update_score(&self, owner: &CanvasLayer, score: i64) {
pub fn update_score(&self, owner: _, score: i64) {
let label = unsafe { owner.get_typed_node::<Label, _>("score_label") };
label.set_text(score.to_string());
}

#[export]
fn on_start_button_pressed(&self, owner: &CanvasLayer) {
fn on_start_button_pressed(&self, owner: _) {
let button = unsafe { owner.get_typed_node::<Button, _>("start_button") };
button.hide();
owner.emit_signal("start_game", &[]);
}

#[export]
fn on_message_timer_timeout(&self, owner: &CanvasLayer) {
fn on_message_timer_timeout(&self, owner: _) {
let message_label = unsafe { owner.get_typed_node::<Label, _>("message_label") };
message_label.hide()
}
Expand Down
22 changes: 11 additions & 11 deletions examples/dodge_the_creeps/src/main_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ pub struct Main {

#[methods]
impl Main {
fn new(_owner: &Node) -> Self {
fn new(_owner: _) -> Self {
Main {
mob: PackedScene::new().into_shared(),
score: 0,
}
}

#[export]
fn game_over(&self, owner: &Node) {
fn game_over(&self, owner: _) {
let score_timer = unsafe { owner.get_typed_node::<Timer, _>("score_timer") };
let mob_timer = unsafe { owner.get_typed_node::<Timer, _>("mob_timer") };

Expand All @@ -36,12 +36,12 @@ impl Main {
let hud_node = unsafe { owner.get_typed_node::<CanvasLayer, _>("hud") };
hud_node
.cast_instance::<hud::HUD>()
.and_then(|hud| hud.map(|x, o| x.show_game_over(&*o)).ok())
.and_then(|hud| hud.map(|x, o| x.show_game_over(o)).ok())
.unwrap_or_else(|| godot_print!("Unable to get hud"));
}

#[export]
fn new_game(&mut self, owner: &Node) {
fn new_game(&mut self, owner: _) {
let start_position = unsafe { owner.get_typed_node::<Position2D, _>("start_position") };
let player = unsafe { owner.get_typed_node::<Area2D, _>("player") };
let start_timer = unsafe { owner.get_typed_node::<Timer, _>("start_timer") };
Expand All @@ -52,7 +52,7 @@ impl Main {
.cast_instance::<player::Player>()
.and_then(|player| {
player
.map(|x, o| x.start(&*o, start_position.position()))
.map(|x, o| x.start(o, start_position.position()))
.ok()
})
.unwrap_or_else(|| godot_print!("Unable to get player"));
Expand All @@ -64,35 +64,35 @@ impl Main {
.cast_instance::<hud::HUD>()
.and_then(|hud| {
hud.map(|x, o| {
x.update_score(&*o, self.score);
x.show_message(&*o, "Get Ready".into());
x.update_score(o, self.score);
x.show_message(o, "Get Ready".into());
})
.ok()
})
.unwrap_or_else(|| godot_print!("Unable to get hud"));
}

#[export]
fn on_start_timer_timeout(&self, owner: &Node) {
fn on_start_timer_timeout(&self, owner: _) {
let mob_timer = unsafe { owner.get_typed_node::<Timer, _>("mob_timer") };
let score_timer = unsafe { owner.get_typed_node::<Timer, _>("score_timer") };
mob_timer.start(0.0);
score_timer.start(0.0);
}

#[export]
fn on_score_timer_timeout(&mut self, owner: &Node) {
fn on_score_timer_timeout(&mut self, owner: _) {
self.score += 1;

let hud_node = unsafe { owner.get_typed_node::<CanvasLayer, _>("hud") };
hud_node
.cast_instance::<hud::HUD>()
.and_then(|hud| hud.map(|x, o| x.update_score(&*o, self.score)).ok())
.and_then(|hud| hud.map(|x, o| x.update_score(o, self.score)).ok())
.unwrap_or_else(|| godot_print!("Unable to get hud"));
}

#[export]
fn on_mob_timer_timeout(&self, owner: &Node) {
fn on_mob_timer_timeout(&self, owner: _) {
let mob_spawn_location =
unsafe { owner.get_typed_node::<PathFollow2D, _>("mob_path/mob_spawn_locations") };

Expand Down
8 changes: 4 additions & 4 deletions examples/dodge_the_creeps/src/mob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,30 @@ const MOB_TYPES: [MobType; 3] = [MobType::Walk, MobType::Swim, MobType::Fly];

#[methods]
impl Mob {
fn new(_owner: &RigidBody2D) -> Self {
fn new(_owner: _) -> Self {
Mob {
min_speed: 150.0,
max_speed: 250.0,
}
}

#[export]
fn _ready(&mut self, owner: &RigidBody2D) {
fn _ready(&mut self, owner: _) {
let mut rng = rand::thread_rng();
let animated_sprite =
unsafe { owner.get_typed_node::<AnimatedSprite, _>("animated_sprite") };
animated_sprite.set_animation(MOB_TYPES.choose(&mut rng).unwrap().to_str())
}

#[export]
fn on_visibility_screen_exited(&self, owner: &RigidBody2D) {
fn on_visibility_screen_exited(&self, owner: _) {
unsafe {
owner.assume_unique().queue_free();
}
}

#[export]
fn on_start_game(&self, owner: &RigidBody2D) {
fn on_start_game(&self, owner: _) {
unsafe {
owner.assume_unique().queue_free();
}
Expand Down
10 changes: 5 additions & 5 deletions examples/dodge_the_creeps/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@ impl Player {
});
}

fn new(_owner: &Area2D) -> Self {
fn new(_owner: _) -> Self {
Player {
speed: 400.0,
screen_size: Vector2::new(0.0, 0.0),
}
}

#[export]
fn _ready(&mut self, owner: &Area2D) {
fn _ready(&mut self, owner: _) {
let viewport = unsafe { owner.get_viewport().unwrap().assume_safe() };
self.screen_size = viewport.size();
owner.hide();
}

#[export]
fn _process(&mut self, owner: &Area2D, delta: f32) {
fn _process(&mut self, owner: _, delta: f32) {
let animated_sprite =
unsafe { owner.get_typed_node::<AnimatedSprite, _>("animated_sprite") };

Expand Down Expand Up @@ -86,7 +86,7 @@ impl Player {
}

#[export]
fn on_player_body_entered(&self, owner: &Area2D, _body: Ref<PhysicsBody2D>) {
fn on_player_body_entered(&self, owner: _, _body: Ref<PhysicsBody2D>) {
owner.hide();
owner.emit_signal("hit", &[]);

Expand All @@ -97,7 +97,7 @@ impl Player {
}

#[export]
pub fn start(&self, owner: &Area2D, pos: Vector2) {
pub fn start(&self, owner: _, pos: Vector2) {
owner.set_global_position(pos);
owner.show();

Expand Down
10 changes: 5 additions & 5 deletions examples/resource/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ struct GreetingResource {

#[gdnative::methods]
impl GreetingResource {
fn new(_owner: &Resource) -> Self {
fn new(_owner: _) -> Self {
Self { name: "".into() }
}

fn say_hello(&self, _owner: &Reference) {
fn say_hello(&self, _owner: _) {
godot_print!("Hello {}!", self.name);
}
}
Expand All @@ -31,17 +31,17 @@ struct Greeter {

#[gdnative::methods]
impl Greeter {
fn new(_owner: &Node) -> Self {
fn new(_owner: _) -> Self {
Greeter {
greeting_resource: None,
}
}

#[export]
fn _ready(&self, _owner: &Node) {
fn _ready(&self, _owner: _) {
if let Some(greeting_resource) = self.greeting_resource.as_ref() {
let greeting_resource = unsafe { greeting_resource.assume_safe() };
greeting_resource.map(|s, o| s.say_hello(&*o)).unwrap();
greeting_resource.map(|s, o| s.say_hello(o)).unwrap();
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions examples/signals/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ impl SignalEmitter {
});
}

fn new(_owner: &Node) -> Self {
fn new(_owner: _) -> Self {
SignalEmitter {
timer: 0.0,
data: 100,
}
}

#[export]
fn _process(&mut self, owner: &Node, delta: f64) {
fn _process(&mut self, owner: _, delta: f64) {
if self.timer < 1.0 {
self.timer += delta;
return;
Expand All @@ -61,12 +61,12 @@ struct SignalSubscriber {

#[methods]
impl SignalSubscriber {
fn new(_owner: &Label) -> Self {
fn new(_owner: _) -> Self {
SignalSubscriber { times_received: 0 }
}

#[export]
fn _ready(&mut self, owner: TRef<Label>) {
fn _ready(&mut self, owner: _) {
let emitter = &mut owner.get_node("../SignalEmitter").unwrap();
let emitter = unsafe { emitter.assume_safe() };

Expand All @@ -85,15 +85,15 @@ impl SignalSubscriber {
}

#[export]
fn notify(&mut self, owner: &Label) {
fn notify(&mut self, owner: _) {
self.times_received += 1;
let msg = format!("Received signal \"tick\" {} times", self.times_received);

owner.set_text(msg);
}

#[export]
fn notify_with_data(&mut self, owner: &Label, data: Variant) {
fn notify_with_data(&mut self, owner: _, data: Variant) {
let msg = format!(
"Received signal \"tick_with_data\" with data {}",
data.try_to_u64().unwrap()
Expand Down
6 changes: 3 additions & 3 deletions examples/spinning_cube/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn register_properties(builder: &ClassBuilder<RustTest>) {

#[gdnative::methods]
impl RustTest {
fn new(_owner: &MeshInstance) -> Self {
fn new(_owner: _) -> Self {
RustTest {
start: Vector3::new(0.0, 0.0, 0.0),
time: 0.0,
Expand All @@ -47,12 +47,12 @@ impl RustTest {
}

#[export]
fn _ready(&mut self, owner: &MeshInstance) {
fn _ready(&mut self, owner: _) {
owner.set_physics_process(true);
}

#[export]
fn _physics_process(&mut self, owner: &MeshInstance, delta: f64) {
fn _physics_process(&mut self, owner: _, delta: f64) {
use gdnative::api::SpatialMaterial;

self.time += delta as f32;
Expand Down
67 changes: 67 additions & 0 deletions gdnative-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,73 @@ mod native_script;
mod profiled;
mod variant;

/// Marks an `impl` block as containing methods exported to Godot. Methods with the
/// `#[export]` attribute will be exported.
///
/// Due to current technical limitations, every `NativeClass` type *must* have one and only
/// one `impl` block with `#[methods]`.
///
/// ## `#[export]`
///
/// The `#[export]` attribute may take optional arguments that modify behavior:
///
/// - `rpc = "rpc_mode_name"`
///
/// Sets the RPC mode for the method. Valid values are `remote`, `remote_sync`, `master`,
/// `puppet`, `disabled`, `master_sync`, and `puppet_sync`.
///
/// ### Optional arguments
///
/// Exported methods can have one or more optional positional arguments at the end of the
/// argument list, if decorated with the `#[opt]` attribute. Arguments with `#[opt]` will
/// hold default values produced by `Default::default`, if not provided by the caller.
///
/// Note that `Option<T>` may be used as the argument type for arbitrary default behavior.
///
/// ## Owner type inference
///
/// The `#[methods]` macro automatically infers the types of arguments named `owner` or
/// `_owner` within the `impl` block it modifies, if they're declared as `_` in the function
/// signature. The inferred type will be `TRef<'_, Self::Base, Shared>`.
///
/// ```ignore
/// #[derive(NativeClass)]
/// #[inherit(Node)]
/// struct Foo;
///
/// #[methods]
/// impl Foo {
/// #[export]
/// fn foo(&self, owner: _) {
/// let owner: TRef<'_, Node, Shared> = owner;
/// do_stuff_with(owner);
/// }
/// }
/// ```
///
/// # Examples
///
/// ```ignore
/// #[methods]
/// impl OptionalArgs {
/// fn new(_owner: _) -> Self {
/// OptionalArgs
/// }
///
/// #[export]
/// fn opt_sum(
/// &self,
/// _owner: _,
/// a: i64,
/// b: i64,
/// #[opt] c: i64,
/// #[opt] d: i64,
/// #[opt] e: i64,
/// ) -> i64 {
/// a + b + c + d + e
/// }
/// }
/// ```
#[proc_macro_attribute]
pub fn methods(meta: TokenStream, input: TokenStream) -> TokenStream {
methods::derive_methods(meta, input)
Expand Down
Loading