Skip to content

Commit

Permalink
Add deref_return parameter for export argument
Browse files Browse the repository at this point in the history
  • Loading branch information
KarimHamidou authored and B-head committed Apr 8, 2024
1 parent 9792f2d commit f3ed9c6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
32 changes: 31 additions & 1 deletion gdnative-core/src/export/macros.rs
Expand Up @@ -11,11 +11,23 @@ macro_rules! godot_wrap_method_parameter_count {
}
}

#[doc(hidden)]
#[macro_export]
macro_rules! godot_wrap_method_if_deref {
(true, $ret:expr) => {
std::ops::Deref::deref(&$ret)
};
(false, $ret:expr) => {
$ret
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! godot_wrap_method_inner {
(
$type_name:ty,
$is_deref_return:ident,
$map_method:ident,
fn $method_name:ident(
$self:ident,
Expand Down Expand Up @@ -56,7 +68,9 @@ macro_rules! godot_wrap_method_inner {
$($pname,)*
$($opt_pname,)*
);
gdnative::core_types::OwnedToVariant::owned_to_variant(ret)
gdnative::core_types::OwnedToVariant::owned_to_variant(
$crate::godot_wrap_method_if_deref!($is_deref_return, ret)
)
}
})
.unwrap_or_else(|err| {
Expand All @@ -83,6 +97,7 @@ macro_rules! godot_wrap_method {
// mutable
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
&mut $self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -93,6 +108,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method_inner!(
$type_name,
$is_deref_return,
map_mut,
fn $method_name(
$self,
Expand All @@ -105,6 +121,7 @@ macro_rules! godot_wrap_method {
// immutable
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
& $self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -115,6 +132,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method_inner!(
$type_name,
$is_deref_return,
map,
fn $method_name(
$self,
Expand All @@ -127,6 +145,7 @@ macro_rules! godot_wrap_method {
// owned
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
mut $self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -137,6 +156,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method_inner!(
$type_name,
$is_deref_return,
map_owned,
fn $method_name(
$self,
Expand All @@ -149,6 +169,7 @@ macro_rules! godot_wrap_method {
// owned
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
$self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -159,6 +180,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method_inner!(
$type_name,
$is_deref_return,
map_owned,
fn $method_name(
$self,
Expand All @@ -171,6 +193,7 @@ macro_rules! godot_wrap_method {
// mutable without return type
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
&mut $self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -181,6 +204,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method!(
$type_name,
$is_deref_return,
fn $method_name(
&mut $self,
$owner: $owner_ty
Expand All @@ -192,6 +216,7 @@ macro_rules! godot_wrap_method {
// immutable without return type
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
& $self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -202,6 +227,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method!(
$type_name,
$is_deref_return,
fn $method_name(
& $self,
$owner: $owner_ty
Expand All @@ -213,6 +239,7 @@ macro_rules! godot_wrap_method {
// owned without return type
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
mut $self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -223,6 +250,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method!(
$type_name,
$is_deref_return,
fn $method_name(
$self,
$owner: $owner_ty
Expand All @@ -234,6 +262,7 @@ macro_rules! godot_wrap_method {
// owned without return type
(
$type_name:ty,
$is_deref_return:ident,
fn $method_name:ident(
$self:ident,
$owner:ident : $owner_ty:ty
Expand All @@ -244,6 +273,7 @@ macro_rules! godot_wrap_method {
) => {
$crate::godot_wrap_method!(
$type_name,
$is_deref_return,
fn $method_name(
$self,
$owner: $owner_ty
Expand Down
19 changes: 19 additions & 0 deletions gdnative-derive/src/methods.rs
Expand Up @@ -66,6 +66,7 @@ pub(crate) struct ExportArgs {
pub(crate) optional_args: Option<usize>,
pub(crate) rpc_mode: RpcMode,
pub(crate) name_override: Option<String>,
pub(crate) is_deref_return: bool,
}

pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 {
Expand Down Expand Up @@ -116,6 +117,7 @@ pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 {
};

let rpc = args.rpc_mode;
let is_deref_return = args.is_deref_return;

let args = sig.inputs.iter().enumerate().map(|(n, arg)| {
let span = arg.span();
Expand All @@ -130,6 +132,7 @@ pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 {
{
let method = ::gdnative::export::godot_wrap_method!(
#class_name,
#is_deref_return,
fn #name ( #( #args )* ) -> #ret_ty
);

Expand Down Expand Up @@ -183,6 +186,7 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) {
let mut export_args = None;
let mut rpc = None;
let mut name_override = None;
let mut is_deref_return = false;

let mut errors = vec![];

Expand Down Expand Up @@ -292,6 +296,20 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) {
));
}
}
} else if path.is_ident("deref_return") {
// deref return value
if lit.is_some() {
errors.push(syn::Error::new(
nested_meta.span(),
"value for deref_return parameter is not valid",
));
} else if is_deref_return {
errors.push(syn::Error::new(
nested_meta.span(),
"deref_return was apply more than once",
));
} else {
is_deref_return = true;
}
} else {
let msg = format!(
Expand Down Expand Up @@ -350,6 +368,7 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) {
export_args.optional_args = optional_args;
export_args.rpc_mode = rpc.unwrap_or(RpcMode::Disabled);
export_args.name_override = name_override;
export_args.is_deref_return = is_deref_return;

methods_to_export.push(ExportMethod {
sig: method.sig.clone(),
Expand Down

0 comments on commit f3ed9c6

Please sign in to comment.