Skip to content

Commit 26adfa9

Browse files
ecobiubiuB-head
authored andcommitted
Add deref_return parameter for export argument
godot-rust/gdnative#870
1 parent 67966e8 commit 26adfa9

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

gdnative-core/src/export/macros.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,23 @@ macro_rules! godot_wrap_method_parameter_count {
1111
}
1212
}
1313

14+
#[doc(hidden)]
15+
#[macro_export]
16+
macro_rules! godot_wrap_method_if_deref {
17+
(true, $ret:expr) => {
18+
std::ops::Deref::deref(&$ret)
19+
};
20+
(false, $ret:expr) => {
21+
$ret
22+
};
23+
}
24+
1425
#[doc(hidden)]
1526
#[macro_export]
1627
macro_rules! godot_wrap_method_inner {
1728
(
1829
$type_name:ty,
30+
$is_deref_return:ident,
1931
$map_method:ident,
2032
fn $method_name:ident(
2133
$self:ident,
@@ -56,7 +68,9 @@ macro_rules! godot_wrap_method_inner {
5668
$($pname,)*
5769
$($opt_pname,)*
5870
);
59-
gdnative::core_types::OwnedToVariant::owned_to_variant(ret)
71+
gdnative::core_types::OwnedToVariant::owned_to_variant(
72+
$crate::godot_wrap_method_if_deref!($is_deref_return, ret)
73+
)
6074
}
6175
})
6276
.unwrap_or_else(|err| {
@@ -83,6 +97,7 @@ macro_rules! godot_wrap_method {
8397
// mutable
8498
(
8599
$type_name:ty,
100+
$is_deref_return:ident,
86101
fn $method_name:ident(
87102
&mut $self:ident,
88103
$owner:ident : $owner_ty:ty
@@ -93,6 +108,7 @@ macro_rules! godot_wrap_method {
93108
) => {
94109
$crate::godot_wrap_method_inner!(
95110
$type_name,
111+
$is_deref_return,
96112
map_mut,
97113
fn $method_name(
98114
$self,
@@ -105,6 +121,7 @@ macro_rules! godot_wrap_method {
105121
// immutable
106122
(
107123
$type_name:ty,
124+
$is_deref_return:ident,
108125
fn $method_name:ident(
109126
& $self:ident,
110127
$owner:ident : $owner_ty:ty
@@ -115,6 +132,7 @@ macro_rules! godot_wrap_method {
115132
) => {
116133
$crate::godot_wrap_method_inner!(
117134
$type_name,
135+
$is_deref_return,
118136
map,
119137
fn $method_name(
120138
$self,
@@ -127,6 +145,7 @@ macro_rules! godot_wrap_method {
127145
// owned
128146
(
129147
$type_name:ty,
148+
$is_deref_return:ident,
130149
fn $method_name:ident(
131150
mut $self:ident,
132151
$owner:ident : $owner_ty:ty
@@ -137,6 +156,7 @@ macro_rules! godot_wrap_method {
137156
) => {
138157
$crate::godot_wrap_method_inner!(
139158
$type_name,
159+
$is_deref_return,
140160
map_owned,
141161
fn $method_name(
142162
$self,
@@ -149,6 +169,7 @@ macro_rules! godot_wrap_method {
149169
// owned
150170
(
151171
$type_name:ty,
172+
$is_deref_return:ident,
152173
fn $method_name:ident(
153174
$self:ident,
154175
$owner:ident : $owner_ty:ty
@@ -159,6 +180,7 @@ macro_rules! godot_wrap_method {
159180
) => {
160181
$crate::godot_wrap_method_inner!(
161182
$type_name,
183+
$is_deref_return,
162184
map_owned,
163185
fn $method_name(
164186
$self,
@@ -171,6 +193,7 @@ macro_rules! godot_wrap_method {
171193
// mutable without return type
172194
(
173195
$type_name:ty,
196+
$is_deref_return:ident,
174197
fn $method_name:ident(
175198
&mut $self:ident,
176199
$owner:ident : $owner_ty:ty
@@ -181,6 +204,7 @@ macro_rules! godot_wrap_method {
181204
) => {
182205
$crate::godot_wrap_method!(
183206
$type_name,
207+
$is_deref_return,
184208
fn $method_name(
185209
&mut $self,
186210
$owner: $owner_ty
@@ -192,6 +216,7 @@ macro_rules! godot_wrap_method {
192216
// immutable without return type
193217
(
194218
$type_name:ty,
219+
$is_deref_return:ident,
195220
fn $method_name:ident(
196221
& $self:ident,
197222
$owner:ident : $owner_ty:ty
@@ -202,6 +227,7 @@ macro_rules! godot_wrap_method {
202227
) => {
203228
$crate::godot_wrap_method!(
204229
$type_name,
230+
$is_deref_return,
205231
fn $method_name(
206232
& $self,
207233
$owner: $owner_ty
@@ -213,6 +239,7 @@ macro_rules! godot_wrap_method {
213239
// owned without return type
214240
(
215241
$type_name:ty,
242+
$is_deref_return:ident,
216243
fn $method_name:ident(
217244
mut $self:ident,
218245
$owner:ident : $owner_ty:ty
@@ -223,6 +250,7 @@ macro_rules! godot_wrap_method {
223250
) => {
224251
$crate::godot_wrap_method!(
225252
$type_name,
253+
$is_deref_return,
226254
fn $method_name(
227255
$self,
228256
$owner: $owner_ty
@@ -234,6 +262,7 @@ macro_rules! godot_wrap_method {
234262
// owned without return type
235263
(
236264
$type_name:ty,
265+
$is_deref_return:ident,
237266
fn $method_name:ident(
238267
$self:ident,
239268
$owner:ident : $owner_ty:ty
@@ -244,6 +273,7 @@ macro_rules! godot_wrap_method {
244273
) => {
245274
$crate::godot_wrap_method!(
246275
$type_name,
276+
$is_deref_return,
247277
fn $method_name(
248278
$self,
249279
$owner: $owner_ty

gdnative-derive/src/methods.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub(crate) struct ExportArgs {
6666
pub(crate) optional_args: Option<usize>,
6767
pub(crate) rpc_mode: RpcMode,
6868
pub(crate) name_override: Option<String>,
69+
pub(crate) is_deref_return: bool,
6970
}
7071

7172
pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 {
@@ -116,6 +117,7 @@ pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 {
116117
};
117118

118119
let rpc = args.rpc_mode;
120+
let is_deref_return = args.is_deref_return;
119121

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

@@ -183,6 +186,7 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) {
183186
let mut export_args = None;
184187
let mut rpc = None;
185188
let mut name_override = None;
189+
let mut is_deref_return = false;
186190

187191
let mut errors = vec![];
188192

@@ -292,6 +296,20 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) {
292296
));
293297
}
294298
}
299+
} else if path.is_ident("deref_return") {
300+
// deref return value
301+
if lit.is_some() {
302+
errors.push(syn::Error::new(
303+
nested_meta.span(),
304+
"value for deref_return parameter is not valid",
305+
));
306+
} else if is_deref_return {
307+
errors.push(syn::Error::new(
308+
nested_meta.span(),
309+
"deref_return was apply more than once",
310+
));
311+
} else {
312+
is_deref_return = true;
295313
}
296314
} else {
297315
let msg = format!(
@@ -350,6 +368,7 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) {
350368
export_args.optional_args = optional_args;
351369
export_args.rpc_mode = rpc.unwrap_or(RpcMode::Disabled);
352370
export_args.name_override = name_override;
371+
export_args.is_deref_return = is_deref_return;
353372

354373
methods_to_export.push(ExportMethod {
355374
sig: method.sig.clone(),

0 commit comments

Comments
 (0)