Skip to content

delta parameter in process() + physics_process() is now f32 instead of f64 #703

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
4 changes: 2 additions & 2 deletions examples/dodge-the-creeps/rust/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl IArea2D for Player {
self.base_mut().hide();
}

fn process(&mut self, delta: f64) {
fn process(&mut self, delta: f32) {
let mut animated_sprite = self
.base()
.get_node_as::<AnimatedSprite2D>("AnimatedSprite2D");
Expand Down Expand Up @@ -99,7 +99,7 @@ impl IArea2D for Player {
animated_sprite.stop();
}

let change = velocity * real::from_f64(delta);
let change = velocity * delta;
let position = self.base().get_global_position() + change;
let position = Vector2::new(
position.x.clamp(0.0, self.screen_size.x),
Expand Down
2 changes: 1 addition & 1 deletion godot-codegen/src/generator/functions_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub fn make_function_definition(
let has_default_params = default_parameters::function_uses_default_params(sig);
let vis = if has_default_params {
// Public API mapped by separate function.
// Needs to be crate-public because default-arg builder lives outside of the module.
// Needs to be crate-public because default-arg builder lives outside the module.
quote! { pub(crate) }
} else {
make_vis(sig.is_private())
Expand Down
21 changes: 17 additions & 4 deletions godot-codegen/src/models/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,14 @@ pub struct FnParam {
}

impl FnParam {
pub fn new_range(method_args: &Option<Vec<JsonMethodArg>>, ctx: &mut Context) -> Vec<FnParam> {
pub fn new_range(
method_args: &Option<Vec<JsonMethodArg>>,
meta_overrides: &HashMap<String, String>,
ctx: &mut Context,
) -> Vec<FnParam> {
option_as_slice(method_args)
.iter()
.map(|arg| Self::new(arg, ctx))
.map(|arg| Self::new(arg, ctx, meta_overrides))
.collect()
}

Expand All @@ -494,9 +498,18 @@ impl FnParam {
.collect()
}

pub fn new(method_arg: &JsonMethodArg, ctx: &mut Context) -> FnParam {
pub fn new(
method_arg: &JsonMethodArg,
ctx: &mut Context,
meta_overrides: &HashMap<String, String>,
) -> FnParam {
// Some methods like _process(f64) have manual overrides to f32.
let forced_meta = meta_overrides.get(&method_arg.name);
let meta = forced_meta.or(method_arg.meta.as_ref());

let name = safe_ident(&method_arg.name);
let type_ = conv::to_rust_type(&method_arg.type_, method_arg.meta.as_ref(), ctx);

let type_ = conv::to_rust_type(&method_arg.type_, meta, ctx);
let default_value = method_arg
.default_value
.as_ref()
Expand Down
8 changes: 5 additions & 3 deletions godot-codegen/src/models/domain_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ impl ClassMethod {
}

let is_private = special_cases::is_method_private(class_name, &method.name);

let godot_method_name = method.name.clone();

let qualifier = {
Expand All @@ -451,11 +450,14 @@ impl ClassMethod {
FnQualifier::from_const_static(is_actually_const, method.is_static)
};

let param_meta_overrides =
special_cases::get_class_method_meta_overrides(class_name, &method.name);

Some(Self {
common: FunctionCommon {
name: rust_method_name.to_string(),
godot_name: godot_method_name,
parameters: FnParam::new_range(&method.arguments, ctx),
parameters: FnParam::new_range(&method.arguments, &param_meta_overrides, ctx),
return_value: FnReturn::new(&method.return_value, ctx),
is_vararg: method.is_vararg,
is_private,
Expand Down Expand Up @@ -494,7 +496,7 @@ impl UtilityFunction {
common: FunctionCommon {
name: rust_method_name,
godot_name: godot_method_name,
parameters: FnParam::new_range(&function.arguments, ctx),
parameters: FnParam::new_range(&function.arguments, &HashMap::new(), ctx),
return_value: FnReturn::new(&return_value, ctx),
is_vararg: function.is_vararg,
is_private: false,
Expand Down
25 changes: 25 additions & 0 deletions godot-codegen/src/special_cases/special_cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use crate::models::domain::TyName;
use crate::models::json::{JsonBuiltinMethod, JsonClassMethod, JsonUtilityFunction};
use crate::special_cases::codegen_special_cases;
use crate::Context;
use std::collections::HashMap;

// Deliberately private -- all checks must go through `special_cases`.

Expand Down Expand Up @@ -354,3 +355,27 @@ pub fn is_class_level_server(class_name: &str) -> bool {
=> true, _ => false
}
}

/// For certain methods like `_process()`, this can influence a parameter type's meta, e.g. represent `delta: f64` as `f32`.
///
/// Deliberately only operates on meta level and doesn't replace types, at it's very easy to introduce UB otherwise.
#[rustfmt::skip]
pub(crate) fn get_class_method_meta_overrides(
class: &TyName,
method_name: &str,
) -> HashMap<String, String> {
let mut map = HashMap::new();

match (class.godot_ty.as_str(), method_name) {
// Could also be `real`, but currently most docs use the resolved float type, e.g. VectorN x,y,z,w fields.
| ("Node", "_process")
| ("Node", "_physics_process") => {
#[cfg(not(feature = "double-precision"))]
map.insert("delta".to_string(), "float".to_string());
}

_ => {}
}

map
}
8 changes: 4 additions & 4 deletions godot-core/src/obj/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ pub trait WithBaseField: GodotClass + Bounds<Declarer = bounds::DeclUser> {
///
/// #[godot_api]
/// impl INode for MyClass {
/// fn process(&mut self, _delta: f64) {
/// fn process(&mut self, _delta: f32) {
/// let name = self.base().get_name();
/// godot_print!("name is {name}");
/// }
Expand All @@ -268,7 +268,7 @@ pub trait WithBaseField: GodotClass + Bounds<Declarer = bounds::DeclUser> {
///
/// #[godot_api]
/// impl INode for MyClass {
/// fn process(&mut self, _delta: f64) {
/// fn process(&mut self, _delta: f32) {
/// let node = Node::new_alloc();
/// // fails because `add_child` requires a mutable reference.
/// self.base().add_child(node);
Expand Down Expand Up @@ -306,7 +306,7 @@ pub trait WithBaseField: GodotClass + Bounds<Declarer = bounds::DeclUser> {
///
/// #[godot_api]
/// impl INode for MyClass {
/// fn process(&mut self, _delta: f64) {
/// fn process(&mut self, _delta: f32) {
/// let node = Node::new_alloc();
/// self.base_mut().add_child(node);
/// }
Expand All @@ -331,7 +331,7 @@ pub trait WithBaseField: GodotClass + Bounds<Declarer = bounds::DeclUser> {
///
/// #[godot_api]
/// impl INode for MyClass {
/// fn process(&mut self, _delta: f64) {
/// fn process(&mut self, _delta: f32) {
/// self.base_mut().call("other_method".into(), &[]);
/// }
/// }
Expand Down
2 changes: 1 addition & 1 deletion itest/rust/src/engine_tests/codegen_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl IHttpRequest for CodegenTest {
}

// Test unnamed parameter in virtual function
fn process(&mut self, _: f64) {}
fn process(&mut self, _: real) {}
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
Expand Down
8 changes: 4 additions & 4 deletions itest/rust/src/object_tests/onready_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
*/

use crate::framework::{expect_panic, itest};
use godot::builtin::meta::ToGodot;
use godot::builtin::real;
use godot::engine::notify::NodeNotification;
use godot::engine::INode;
use godot::register::{godot_api, GodotClass};

use godot::obj::{Gd, OnReady};
use godot::prelude::ToGodot;
use godot::register::{godot_api, GodotClass};

#[itest]
fn onready_deref() {
Expand Down Expand Up @@ -232,5 +232,5 @@ impl OnReadyWithImplWithoutReady {
#[godot_api]
impl INode for OnReadyWithoutImpl {
// Declare another function to ensure virtual getter must be provided.
fn process(&mut self, _delta: f64) {}
fn process(&mut self, _delta: real) {}
}
Loading