@@ -22,16 +22,7 @@ pub trait SignatureTuple {
22
22
args_ptr : * const sys:: GDExtensionConstVariantPtr ,
23
23
ret : sys:: GDExtensionVariantPtr ,
24
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
- instance_ptr : sys:: GDExtensionClassInstancePtr ,
31
- args_ptr : * const sys:: GDExtensionConstVariantPtr ,
32
- ret : sys:: GDExtensionVariantPtr ,
33
- err : * mut sys:: GDExtensionCallError ,
34
- func : fn ( & mut C , Self :: Params ) -> Self :: Ret ,
25
+ func : fn ( sys:: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
35
26
method_name : & str ,
36
27
) ;
37
28
@@ -41,18 +32,7 @@ pub trait SignatureTuple {
41
32
instance_ptr : sys:: GDExtensionClassInstancePtr ,
42
33
args_ptr : * const sys:: GDExtensionConstTypePtr ,
43
34
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
- instance_ptr : sys:: GDExtensionClassInstancePtr ,
53
- args_ptr : * const sys:: GDExtensionConstTypePtr ,
54
- ret : sys:: GDExtensionTypePtr ,
55
- func : fn ( & mut C , Self :: Params ) -> Self :: Ret ,
35
+ func : fn ( sys:: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
56
36
method_name : & str ,
57
37
call_type : sys:: PtrcallType ,
58
38
) ;
@@ -127,133 +107,104 @@ macro_rules! impl_signature_for_tuple {
127
107
128
108
#[ inline]
129
109
unsafe fn varcall<C : GodotClass >(
130
- instance_ptr: sys:: GDExtensionClassInstancePtr ,
131
- args_ptr: * const sys:: GDExtensionConstVariantPtr ,
132
- ret: sys:: GDExtensionVariantPtr ,
133
- err: * mut sys:: GDExtensionCallError ,
134
- func: fn ( & C , Self :: Params ) -> Self :: Ret ,
135
- method_name: & str ,
136
- ) {
137
- $crate:: out!( "varcall: {}" , method_name) ;
138
-
139
- let storage = unsafe { crate :: private:: as_storage:: <C >( instance_ptr) } ;
140
- let instance = storage. get( ) ;
141
-
142
- let args = ( $(
143
- {
144
- let variant = unsafe { & * ( * args_ptr. offset( $n) as * mut Variant ) } ; // TODO from_var_sys
145
- let arg = <$Pn as FromVariant >:: try_from_variant( variant)
146
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, variant) ) ;
147
-
148
- arg
149
- } ,
150
- ) * ) ;
151
-
152
- let ret_val = func( & * instance, args) ;
153
- let ret_variant = <$R as ToVariant >:: to_variant( & ret_val) ; // TODO write_sys
154
- unsafe {
155
- * ( ret as * mut Variant ) = ret_variant;
156
- ( * err) . error = sys:: GDEXTENSION_CALL_OK ;
157
- }
158
- }
159
-
160
- #[ inline]
161
- unsafe fn varcall_mut<C : GodotClass >(
162
- instance_ptr: sys:: GDExtensionClassInstancePtr ,
110
+ instance_ptr: sys:: GDExtensionClassInstancePtr ,
163
111
args_ptr: * const sys:: GDExtensionConstVariantPtr ,
164
112
ret: sys:: GDExtensionVariantPtr ,
165
113
err: * mut sys:: GDExtensionCallError ,
166
- func: fn ( & mut C , Self :: Params ) -> Self :: Ret ,
114
+ func: fn ( sys :: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
167
115
method_name: & str ,
168
116
) {
169
- $crate:: out!( "varcall: {}" , method_name) ;
170
-
171
- let storage = unsafe { crate :: private:: as_storage:: <C >( instance_ptr) } ;
172
- let mut instance = storage. get_mut( ) ;
117
+ $crate:: out!( "varcall: {}" , method_name) ;
173
118
174
- let args = ( $(
175
- {
176
- let variant = unsafe { & * ( * args_ptr. offset( $n) as * mut Variant ) } ; // TODO from_var_sys
177
- let arg = <$Pn as FromVariant >:: try_from_variant( variant)
178
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, variant) ) ;
119
+ let args = ( $(
120
+ unsafe { varcall_arg:: <$Pn, $n>( args_ptr, method_name) } ,
121
+ ) * ) ;
179
122
180
- arg
181
- } ,
182
- ) * ) ;
183
-
184
- let ret_val = func( & mut * instance, args) ;
185
- let ret_variant = <$R as ToVariant >:: to_variant( & ret_val) ; // TODO write_sys
186
- unsafe {
187
- * ( ret as * mut Variant ) = ret_variant;
188
- ( * err) . error = sys:: GDEXTENSION_CALL_OK ;
189
- }
123
+ varcall_return:: <$R>( func( instance_ptr, args) , ret, err)
190
124
}
191
125
192
126
#[ inline]
193
127
unsafe fn ptrcall<C : GodotClass >(
194
- instance_ptr: sys:: GDExtensionClassInstancePtr ,
128
+ instance_ptr: sys:: GDExtensionClassInstancePtr ,
195
129
args_ptr: * const sys:: GDExtensionConstTypePtr ,
196
130
ret: sys:: GDExtensionTypePtr ,
197
- func: fn ( & C , Self :: Params ) -> Self :: Ret ,
131
+ func: fn ( sys :: GDExtensionClassInstancePtr , Self :: Params ) -> Self :: Ret ,
198
132
method_name: & str ,
199
133
call_type: sys:: PtrcallType ,
200
134
) {
201
135
$crate:: out!( "ptrcall: {}" , method_name) ;
202
136
203
- let storage = unsafe { crate :: private:: as_storage:: <C >( instance_ptr) } ;
204
- let instance = storage. get( ) ;
205
-
206
- let args = ( $(
207
- unsafe {
208
- <$Pn as sys:: GodotFuncMarshal >:: try_from_arg(
209
- sys:: force_mut_ptr( * args_ptr. offset( $n) ) ,
210
- call_type
211
- )
212
- }
213
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, & e) ) ,
214
- ) * ) ;
137
+ let args = ( $(
138
+ unsafe { ptrcall_arg:: <$Pn, $n>( args_ptr, method_name, call_type) } ,
139
+ ) * ) ;
215
140
216
- let ret_val = func( & * instance, args) ;
217
141
// SAFETY:
218
142
// `ret` is always a pointer to an initialized value of type $R
219
143
// TODO: double-check the above
220
- <$R as sys:: GodotFuncMarshal >:: try_return( ret_val, ret, call_type)
221
- . 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)
222
145
}
146
+ }
147
+ } ;
148
+ }
223
149
224
- #[ inline]
225
- unsafe fn ptrcall_mut<C : GodotClass >(
226
- instance_ptr: sys:: GDExtensionClassInstancePtr ,
227
- args_ptr: * const sys:: GDExtensionConstTypePtr ,
228
- ret: sys:: GDExtensionTypePtr ,
229
- func: fn ( & mut C , Self :: Params ) -> Self :: Ret ,
230
- method_name: & str ,
231
- call_type: sys:: PtrcallType ,
232
- ) {
233
- $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
+ }
234
162
235
- let storage = unsafe { crate :: private:: as_storage:: <C >( instance_ptr) } ;
236
- let mut instance = storage. get_mut( ) ;
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
+ }
237
178
238
- let args = ( $(
239
- unsafe {
240
- <$Pn as sys:: GodotFuncMarshal >:: try_from_arg(
241
- sys:: force_mut_ptr( * args_ptr. offset( $n) ) ,
242
- call_type
243
- )
244
- }
245
- . unwrap_or_else( |e| param_error:: <$Pn>( method_name, $n, & e) ) ,
246
- ) * ) ;
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
+ }
247
193
248
- let ret_val = func( & mut * instance, args) ;
249
- // SAFETY:
250
- // `ret` is always a pointer to an initialized value of type $R
251
- // TODO: double-check the above
252
- <$R as sys:: GodotFuncMarshal >:: try_return( ret_val, ret, call_type)
253
- . unwrap_or_else( |ret_val| return_error:: <$R>( method_name, & ret_val) ) ;
254
- }
255
- }
256
- } ;
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) )
257
208
}
258
209
259
210
fn param_error < P > ( method_name : & str , index : i32 , arg : & impl Debug ) -> ! {
0 commit comments