@@ -18,6 +18,15 @@ pub trait SignatureTuple {
1818 fn param_metadata ( index : i32 ) -> sys:: GDExtensionClassMethodArgumentMetadata ;
1919
2020 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 > (
2130 instance_ptr : sys:: GDExtensionClassInstancePtr ,
2231 args_ptr : * const sys:: GDExtensionConstVariantPtr ,
2332 ret : sys:: GDExtensionVariantPtr ,
@@ -29,6 +38,17 @@ pub trait SignatureTuple {
2938 // Note: this method imposes extra bounds on GodotFfi, which may not be implemented for user types.
3039 // We could fall back to varcalls in such cases, and not require GodotFfi categorically.
3140 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 > (
3252 instance_ptr : sys:: GDExtensionClassInstancePtr ,
3353 args_ptr : * const sys:: GDExtensionConstTypePtr ,
3454 ret : sys:: GDExtensionTypePtr ,
@@ -111,6 +131,38 @@ macro_rules! impl_signature_for_tuple {
111131 args_ptr: * const sys:: GDExtensionConstVariantPtr ,
112132 ret: sys:: GDExtensionVariantPtr ,
113133 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 ,
163+ args_ptr: * const sys:: GDExtensionConstVariantPtr ,
164+ ret: sys:: GDExtensionVariantPtr ,
165+ err: * mut sys:: GDExtensionCallError ,
114166 func: fn ( & mut C , Self :: Params ) -> Self :: Ret ,
115167 method_name: & str ,
116168 ) {
@@ -142,6 +194,38 @@ macro_rules! impl_signature_for_tuple {
142194 instance_ptr: sys:: GDExtensionClassInstancePtr ,
143195 args_ptr: * const sys:: GDExtensionConstTypePtr ,
144196 ret: sys:: GDExtensionTypePtr ,
197+ func: fn ( & C , Self :: Params ) -> Self :: Ret ,
198+ method_name: & str ,
199+ call_type: sys:: PtrcallType ,
200+ ) {
201+ $crate:: out!( "ptrcall: {}" , method_name) ;
202+
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+ ) * ) ;
215+
216+ let ret_val = func( & * instance, args) ;
217+ // SAFETY:
218+ // `ret` is always a pointer to an initialized value of type $R
219+ // 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) ) ;
222+ }
223+
224+ #[ inline]
225+ unsafe fn ptrcall_mut<C : GodotClass >(
226+ instance_ptr: sys:: GDExtensionClassInstancePtr ,
227+ args_ptr: * const sys:: GDExtensionConstTypePtr ,
228+ ret: sys:: GDExtensionTypePtr ,
145229 func: fn ( & mut C , Self :: Params ) -> Self :: Ret ,
146230 method_name: & str ,
147231 call_type: sys:: PtrcallType ,
0 commit comments