Skip to content

Commit

Permalink
Try #279:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored May 24, 2023
2 parents 81f81c6 + 424c879 commit b16deb7
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 30 deletions.
3 changes: 2 additions & 1 deletion godot-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ pub mod private {
pub use crate::registry::{callbacks, ClassPlugin, ErasedRegisterFn, PluginComponent};
pub use crate::storage::as_storage;
pub use crate::{
gdext_register_method, gdext_register_method_inner, gdext_virtual_method_callback,
gdext_get_arguments_info, gdext_register_method, gdext_register_method_inner,
gdext_virtual_method_callback,
};

use crate::{log, sys};
Expand Down
39 changes: 24 additions & 15 deletions godot-core/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,20 +229,7 @@ macro_rules! gdext_register_method_inner {

// Arguments meta-information
let argument_count = NUM_ARGS as u32;
let mut arguments_info: [PropertyInfo; NUM_ARGS] = {
let mut i = -1i32;
[$(
{
i += 1;
let prop = Sig::property_info(i, stringify!($param));
//OnceArg::new(prop)
prop
},
)*]
};
let mut arguments_info_sys: [sys::GDExtensionPropertyInfo; NUM_ARGS]
= std::array::from_fn(|i| arguments_info[i].property_sys());
// = std::array::from_fn(|i| arguments_info[i].once_sys());
let mut arguments_info: [sys::GDExtensionPropertyInfo; NUM_ARGS] = $crate::gdext_get_arguments_info!(($($RetTy)+, $($ParamTy),*), $( $param, )*);
let mut arguments_metadata: [sys::GDExtensionClassMethodArgumentMetadata; NUM_ARGS]
= std::array::from_fn(|i| Sig::param_metadata(i as i32));

Expand All @@ -262,7 +249,7 @@ macro_rules! gdext_register_method_inner {
return_value_info: std::ptr::addr_of_mut!(return_value_info_sys),
return_value_metadata,
argument_count,
arguments_info: arguments_info_sys.as_mut_ptr(),
arguments_info: arguments_info.as_mut_ptr(),
arguments_metadata: arguments_metadata.as_mut_ptr(),
default_argument_count: 0,
default_arguments: std::ptr::null_mut(),
Expand Down Expand Up @@ -546,3 +533,25 @@ macro_rules! gdext_ptrcall {
);
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! gdext_get_arguments_info {
(
$Signature:ty,
$($param:ident,)*
) => {
{
use $crate::builtin::meta::*;

let mut i = -1i32;
[$(
{
i += 1;
let prop = <$Signature as SignatureTuple>::property_info(i, stringify!($param)).property_sys();
prop
},
)*]
}
};
}
54 changes: 40 additions & 14 deletions godot-macros/src/godot_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::util;
use crate::util::bail;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use venial::{AttributeValue, Declaration, Error, Function, Impl, ImplMember};
use venial::{AttributeValue, Declaration, Error, FnParam, Function, Impl, ImplMember, TyExpr};

pub fn transform(input_decl: Declaration) -> Result<TokenStream, Error> {
let decl = match input_decl {
Expand Down Expand Up @@ -62,19 +62,41 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
let class_name = util::validate_impl(&decl, None, "godot_api")?;
let class_name_str = class_name.to_string();

//let register_fn = format_ident!("__godot_rust_register_{}", class_name_str);
//#[allow(non_snake_case)]

let (funcs, signals) = process_godot_fns(&mut decl)?;
let signal_name_strs = signals.into_iter().map(|ident| ident.to_string());

let mut signal_name_strs: Vec<String> = Vec::new();
let mut signal_parameters_count: Vec<i64> = Vec::new();
let mut signal_parameters: Vec<TokenStream> = Vec::new();

for signature in signals {
let mut param_types: Vec<TyExpr> = Vec::new();
let mut param_names: Vec<Ident> = Vec::new();

for param in signature.params.inner {
match &param.0 {
FnParam::Typed(param) => {
param_types.push(param.ty.clone());
param_names.push(param.name.clone());
}
FnParam::Receiver(_) => {}
};
}

signal_name_strs.push(signature.name.to_string());
signal_parameters_count.push(param_names.len() as i64);
signal_parameters.push(
quote! {
::godot::private::gdext_get_arguments_info!(((), #(#param_types ),*), #(#param_names, )*).as_ptr()
},
);
}

let prv = quote! { ::godot::private };

let result = quote! {
#decl

impl ::godot::obj::cap::ImplementsGodotApi for #class_name {
//fn __register_methods(_builder: &mut ::godot::builder::ClassBuilder<Self>) {
fn __register_methods() {
#(
::godot::private::gdext_register_method!(#class_name, #funcs);
Expand All @@ -83,14 +105,17 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
unsafe {
let class_name = ::godot::builtin::StringName::from(#class_name_str);
use ::godot::sys;

#(
let parameters = #signal_parameters;
let signal_name = ::godot::builtin::StringName::from(#signal_name_strs);

sys::interface_fn!(classdb_register_extension_class_signal)(
sys::get_library(),
class_name.string_sys(),
signal_name.string_sys(),
std::ptr::null(), // NULL only valid for zero parameters, in current impl; maybe better empty slice
0,
parameters,
sys::GDExtensionInt::from(#signal_parameters_count),
);
)*
}
Expand All @@ -110,9 +135,9 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
Ok(result)
}

fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Ident>), Error> {
fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Function>), Error> {
let mut func_signatures = vec![];
let mut signal_idents = vec![]; // TODO consider signature
let mut signal_signatures = vec![];

let mut removed_indexes = vec![];
for (index, item) in decl.body_items.iter_mut().enumerate() {
Expand Down Expand Up @@ -147,11 +172,12 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Ident>), Err
func_signatures.push(sig);
}
BoundAttrType::Signal(ref _attr_val) => {
if !method.params.is_empty() || method.return_ty.is_some() {
return attr.bail("parameters and return types not yet supported", method);
if method.return_ty.is_some() {
return attr.bail("return types are not supported", method);
}
let sig = util::reduce_to_signature(method);

signal_idents.push(method.name.clone());
signal_signatures.push(sig.clone());
removed_indexes.push(index);
}
}
Expand All @@ -164,7 +190,7 @@ fn process_godot_fns(decl: &mut Impl) -> Result<(Vec<Function>, Vec<Ident>), Err
decl.body_items.remove(index);
}

Ok((func_signatures, signal_idents))
Ok((func_signatures, signal_signatures))
}

fn extract_attributes(method: &Function) -> Result<Option<BoundAttr>, Error> {
Expand Down

0 comments on commit b16deb7

Please sign in to comment.