@@ -18,15 +18,6 @@ pub trait SignatureTuple {
18
18
fn param_metadata ( index : i32 ) -> sys:: GDExtensionClassMethodArgumentMetadata ;
19
19
20
20
unsafe fn varcall < C : GodotClass > (
21
- instance_ptr : sys:: GDExtensionClassInstancePtr ,
22
- args_ptr : * const sys:: GDExtensionConstVariantPtr ,
23
- ret : sys:: GDExtensionVariantPtr ,
24
- err : * mut sys:: GDExtensionCallError ,
25
- func : fn ( & C , Self :: Params ) -> Self :: Ret ,
26
- method_name : & str ,
27
- ) ;
28
-
29
- unsafe fn varcall_mut < C : GodotClass > (
30
21
instance_ptr : sys:: GDExtensionClassInstancePtr ,
31
22
args_ptr : * const sys:: GDExtensionConstVariantPtr ,
32
23
ret : sys:: GDExtensionVariantPtr ,
@@ -38,21 +29,11 @@ pub trait SignatureTuple {
38
29
// Note: this method imposes extra bounds on GodotFfi, which may not be implemented for user types.
39
30
// We could fall back to varcalls in such cases, and not require GodotFfi categorically.
40
31
unsafe fn ptrcall < C : GodotClass > (
41
- instance_ptr : sys:: GDExtensionClassInstancePtr ,
42
- args_ptr : * const sys:: GDExtensionConstTypePtr ,
43
- ret : sys:: GDExtensionTypePtr ,
44
- func : fn ( & C , Self :: Params ) -> Self :: Ret ,
45
- method_name : & str ,
46
- call_type : sys:: PtrcallType ,
47
- ) ;
48
-
49
- // Note: this method imposes extra bounds on GodotFfi, which may not be implemented for user types.
50
- // We could fall back to varcalls in such cases, and not require GodotFfi categorically.
51
- unsafe fn ptrcall_mut < C : GodotClass > (
52
32
instance_ptr : sys:: GDExtensionClassInstancePtr ,
53
33
args_ptr : * const sys:: GDExtensionConstTypePtr ,
54
34
ret : sys:: GDExtensionTypePtr ,
55
35
func : fn ( sys:: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
36
+ method_name : & str ,
56
37
call_type : sys:: PtrcallType ,
57
38
) ;
58
39
}
@@ -130,122 +111,100 @@ macro_rules! impl_signature_for_tuple {
130
111
args_ptr: * const sys:: GDExtensionConstVariantPtr ,
131
112
ret: sys:: GDExtensionVariantPtr ,
132
113
err: * mut sys:: GDExtensionCallError ,
133
- func: fn ( & C , Self :: Params ) -> Self :: Ret ,
134
- method_name: & str ,
135
- ) {
136
- $crate:: out!( "varcall: {}" , method_name) ;
137
-
138
- let storage = unsafe { crate :: private:: as_storage:: <C >( instance_ptr) } ;
139
- let instance = storage. get( ) ;
140
-
141
- let args = ( $(
142
- {
143
- let variant = unsafe { & * ( * args_ptr. offset( $n) as * mut Variant ) } ; // TODO from_var_sys
144
- let arg = <$Pn as FromVariant >:: try_from_variant( variant)
145
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, variant) ) ;
146
-
147
- arg
148
- } ,
149
- ) * ) ;
150
-
151
- let ret_val = func( & * instance, args) ;
152
- let ret_variant = <$R as ToVariant >:: to_variant( & ret_val) ; // TODO write_sys
153
- unsafe {
154
- * ( ret as * mut Variant ) = ret_variant;
155
- ( * err) . error = sys:: GDEXTENSION_CALL_OK ;
156
- }
157
- }
158
-
159
- #[ inline]
160
- unsafe fn varcall_mut<C : GodotClass >(
161
- instance_ptr: sys:: GDExtensionClassInstancePtr ,
162
- args_ptr: * const sys:: GDExtensionConstVariantPtr ,
163
- ret: sys:: GDExtensionVariantPtr ,
164
- err: * mut sys:: GDExtensionCallError ,
165
114
func: fn ( sys:: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
166
115
method_name: & str ,
167
116
) {
168
117
$crate:: out!( "varcall: {}" , method_name) ;
169
118
170
- let args = ( $(
171
- {
172
- let variant = unsafe { & * ( * args_ptr. offset( $n) as * mut Variant ) } ; // TODO from_var_sys
173
- let arg = <$Pn as FromVariant >:: try_from_variant( variant)
174
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, variant) ) ;
175
-
176
- arg
177
- } ,
178
- ) * ) ;
119
+ let args = ( $(
120
+ unsafe { varcall_arg:: <$Pn, $n>( args_ptr, method_name) } ,
121
+ ) * ) ;
179
122
180
- let ret_val = func( instance_ptr, args) ;
181
- let ret_variant = <$R as ToVariant >:: to_variant( & ret_val) ; // TODO write_sys
182
- unsafe {
183
- * ( ret as * mut Variant ) = ret_variant;
184
- ( * err) . error = sys:: GDEXTENSION_CALL_OK ;
185
- }
123
+ varcall_return:: <$R>( func( instance_ptr, args) , ret, err)
186
124
}
187
125
188
126
#[ inline]
189
127
unsafe fn ptrcall<C : GodotClass >(
190
128
instance_ptr: sys:: GDExtensionClassInstancePtr ,
191
129
args_ptr: * const sys:: GDExtensionConstTypePtr ,
192
130
ret: sys:: GDExtensionTypePtr ,
193
- func: fn ( & C , Self :: Params ) -> Self :: Ret ,
131
+ func: fn ( sys :: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
194
132
method_name: & str ,
195
133
call_type: sys:: PtrcallType ,
196
134
) {
197
135
$crate:: out!( "ptrcall: {}" , method_name) ;
198
136
199
- let storage = unsafe { crate :: private:: as_storage:: <C >( instance_ptr) } ;
200
- let instance = storage. get( ) ;
201
-
202
- let args = ( $(
203
- unsafe {
204
- <$Pn as sys:: GodotFuncMarshal >:: try_from_arg(
205
- sys:: force_mut_ptr( * args_ptr. offset( $n) ) ,
206
- call_type
207
- )
208
- }
209
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, & e) ) ,
210
- ) * ) ;
137
+ let args = ( $(
138
+ unsafe { ptrcall_arg:: <$Pn, $n>( args_ptr, method_name, call_type) } ,
139
+ ) * ) ;
211
140
212
- let ret_val = func( & * instance, args) ;
213
141
// SAFETY:
214
142
// `ret` is always a pointer to an initialized value of type $R
215
143
// TODO: double-check the above
216
- <$R as sys:: GodotFuncMarshal >:: try_return( ret_val, ret, call_type)
217
- . unwrap_or_else( |ret_val| return_error:: <$R>( method_name, & ret_val) ) ;
144
+ ptrcall_return:: <$R>( func( instance_ptr, args) , ret, method_name, call_type)
218
145
}
146
+ }
147
+ } ;
148
+ }
219
149
220
- #[ inline]
221
- unsafe fn ptrcall_mut<C : GodotClass >(
222
- instance_ptr: sys:: GDExtensionClassInstancePtr ,
223
- args_ptr: * const sys:: GDExtensionConstTypePtr ,
224
- ret: sys:: GDExtensionTypePtr ,
225
- func: fn ( sys:: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
226
- call_type: sys:: PtrcallType ,
227
- ) {
228
- $crate:: out!( "ptrcall: {}" , method_name) ;
150
+ /// Convert the `N`th argument of `args_ptr` into a value of type `P`.
151
+ ///
152
+ /// # Safety
153
+ /// - It must be safe to dereference the pointer at `args_ptr.offset(N)` .
154
+ unsafe fn varcall_arg < P : FromVariant , const N : isize > (
155
+ args_ptr : * const sys:: GDExtensionConstVariantPtr ,
156
+ method_name : & str ,
157
+ ) -> P {
158
+ let variant = & * ( * args_ptr. offset ( N ) as * mut Variant ) ; // TODO from_var_sys
159
+ P :: try_from_variant ( variant)
160
+ . unwrap_or_else ( |_| param_error :: < P > ( method_name, N as i32 , variant) )
161
+ }
229
162
230
- let args = ( $(
231
- unsafe {
232
- <$Pn as sys:: GodotFuncMarshal >:: try_from_arg(
233
- sys:: force_mut_ptr( * args_ptr. offset( $n) ) ,
234
- call_type
235
- )
236
- }
237
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, & e) ) ,
238
- ) * ) ;
163
+ /// Moves `ret_val` into `ret`.
164
+ ///
165
+ /// # Safety
166
+ /// - `ret` must be a pointer to an initialized `Variant`.
167
+ /// - It must be safe to write a `Variant` once to `ret`.
168
+ /// - It must be safe to write a `sys::GDExtensionCallError` once to `err`.
169
+ unsafe fn varcall_return < R : ToVariant > (
170
+ ret_val : R ,
171
+ ret : sys:: GDExtensionConstVariantPtr ,
172
+ err : * mut sys:: GDExtensionCallError ,
173
+ ) {
174
+ let ret_variant = ret_val. to_variant ( ) ; // TODO write_sys
175
+ * ( ret as * mut Variant ) = ret_variant;
176
+ ( * err) . error = sys:: GDEXTENSION_CALL_OK ;
177
+ }
239
178
240
- let ret_val = func( instance_ptr, args) ;
241
- // SAFETY:
242
- // `ret` is always a pointer to an initialized value of type $R
243
- // TODO: double-check the above
244
- <$R as sys:: GodotFuncMarshal >:: try_return( ret_val, ret, call_type)
245
- . unwrap_or_else( |ret_val| return_error:: <$R>( method_name, & ret_val) ) ;
246
- }
247
- }
248
- } ;
179
+ /// Convert the `N`th argument of `args_ptr` into a value of type `P`.
180
+ ///
181
+ /// # Safety
182
+ /// - It must be safe to dereference the address at `args_ptr.offset(N)` .
183
+ /// - The pointer at `args_ptr.offset(N)` must follow the safety requirements as laid out in
184
+ /// [`GodotFuncMarshal::try_from_arg`][sys::GodotFuncMarshal::try_from_arg].
185
+ unsafe fn ptrcall_arg < P : sys:: GodotFuncMarshal , const N : isize > (
186
+ args_ptr : * const sys:: GDExtensionConstTypePtr ,
187
+ method_name : & str ,
188
+ call_type : sys:: PtrcallType ,
189
+ ) -> P {
190
+ P :: try_from_arg ( sys:: force_mut_ptr ( * args_ptr. offset ( N ) ) , call_type)
191
+ . unwrap_or_else ( |e| param_error :: < P > ( method_name, N as i32 , & e) )
192
+ }
193
+
194
+ /// Moves `ret_val` into `ret`.
195
+ ///
196
+ /// # Safety
197
+ /// `ret_val`, `ret`, and `call_type` must follow the safety requirements as laid out in
198
+ /// [`GodotFuncMarshal::try_return`](sys::GodotFuncMarshal::try_return).
199
+ unsafe fn ptrcall_return < R : sys:: GodotFuncMarshal + std:: fmt:: Debug > (
200
+ ret_val : R ,
201
+ ret : sys:: GDExtensionTypePtr ,
202
+ method_name : & str ,
203
+ call_type : sys:: PtrcallType ,
204
+ ) {
205
+ ret_val
206
+ . try_return ( ret, call_type)
207
+ . unwrap_or_else ( |ret_val| return_error :: < R > ( method_name, & ret_val) )
249
208
}
250
209
251
210
fn param_error < P > ( method_name : & str , index : i32 , arg : & impl Debug ) -> ! {
0 commit comments