Skip to content

Commit

Permalink
Fix Ex* builders taking ObjectArg<T> instead of `impl
Browse files Browse the repository at this point in the history
AsObjectArg<T>`
  • Loading branch information
Bromeon committed Aug 2, 2024
1 parent 15bc053 commit ed6ff78
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 15 deletions.
6 changes: 3 additions & 3 deletions godot-codegen/src/conv/type_conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {

RustTy::EngineClass {
tokens: quote! { Gd<#qualified_class> },
arg_view: quote! { ObjectArg<#qualified_class> },
impl_as_arg: quote! { impl AsObjectArg<#qualified_class> },
object_arg: quote! { ObjectArg<#qualified_class> },
impl_as_object_arg: quote! { impl AsObjectArg<#qualified_class> },
inner_class: ty,
}
}
Expand Down Expand Up @@ -266,7 +266,7 @@ fn to_rust_expr_inner(expr: &str, ty: &RustTy, is_inner: bool) -> TokenStream {
return match ty {
RustTy::BuiltinIdent(ident) if ident == "Variant" => quote! { Variant::nil() },
RustTy::EngineClass { .. } => {
quote! { ObjectArg::null() }
quote! { Gd::null_arg() }
}
_ => panic!("null not representable in target type {ty:?}"),
}
Expand Down
23 changes: 17 additions & 6 deletions godot-codegen/src/generator/default_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,30 +247,33 @@ fn make_extender(
default_value,
} = param;

let type_ = type_.param_decl();
let (field_type, needs_conversion) = type_.private_field_decl();

// Initialize with default parameters where available, forward constructor args otherwise
let init = if let Some(value) = default_value {
quote! { #name: #value }
make_field_init(name, value, needs_conversion)
} else {
quote! { #name }
};

result.builder_fields.push(quote! { #name: #type_ });
result.builder_fields.push(quote! { #name: #field_type });
result.builder_args.push(quote! { self.#name });
result.builder_inits.push(init);
}

for param in default_fn_params {
let FnParam { name, type_, .. } = param;
let type_ = type_.param_decl();
let param_type = type_.param_decl();
let (_, field_needs_conversion) = type_.private_field_decl();

let field_init = make_field_init(name, &quote! { value }, field_needs_conversion);

let method = quote! {
#[inline]
pub fn #name(self, value: #type_) -> Self {
pub fn #name(self, value: #param_type) -> Self {
// Currently not testing whether the parameter was already set
Self {
#name: value,
#field_init,
..self
}
}
Expand All @@ -281,3 +284,11 @@ fn make_extender(

result
}

fn make_field_init(name: &Ident, expr: &TokenStream, needs_conversion: bool) -> TokenStream {
if needs_conversion {
quote! { #name: #expr.as_object_arg() }
} else {
quote! { #name: #expr }
}
}
4 changes: 2 additions & 2 deletions godot-codegen/src/generator/functions_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@ pub(crate) fn make_params_exprs<'a>(
// Objects (Gd<T>) use implicit conversions via AsObjectArg. Only use in non-virtual functions.
match &param.type_ {
RustTy::EngineClass {
arg_view,
impl_as_arg,
object_arg: arg_view,
impl_as_object_arg: impl_as_arg,
..
} if !is_virtual => {
// Parameter declarations in signature: impl AsObjectArg<T>
Expand Down
16 changes: 12 additions & 4 deletions godot-codegen/src/models/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,10 @@ pub enum RustTy {
tokens: TokenStream,

/// Tokens with `ObjectArg<T>` (used in `type CallSig` tuple types).
arg_view: TokenStream,
object_arg: TokenStream,

/// Signature declaration with `impl AsObjectArg<T>`.
impl_as_arg: TokenStream,
impl_as_object_arg: TokenStream,

/// only inner `T`
#[allow(dead_code)] // only read in minimal config
Expand All @@ -639,12 +639,20 @@ impl RustTy {
pub fn param_decl(&self) -> TokenStream {
match self {
RustTy::EngineClass {
arg_view: raw_gd, ..
} => raw_gd.clone(),
impl_as_object_arg, ..
} => impl_as_object_arg.clone(),
other => other.to_token_stream(),
}
}

/// Returns `( <field tokens>, <needs .as_object_arg()> )`.
pub fn private_field_decl(&self) -> (TokenStream, bool) {
match self {
RustTy::EngineClass { object_arg, .. } => (object_arg.clone(), true),
other => (other.to_token_stream(), false),
}
}

pub fn return_decl(&self) -> TokenStream {
match self {
Self::EngineClass { tokens, .. } => quote! { -> Option<#tokens> },
Expand Down

0 comments on commit ed6ff78

Please sign in to comment.