@@ -11,7 +11,7 @@ use std::{fmt, ptr};
1111use godot_ffi as sys;
1212use sys:: { ffi_methods, ExtVariantType , GodotFfi } ;
1313
14- use crate :: builtin:: { inner, AnyArray , GString , StringName , Variant } ;
14+ use crate :: builtin:: { inner, AnyArray , CowStr , StringName , Variant } ;
1515use crate :: meta:: { GodotType , ToGodot } ;
1616use crate :: obj:: bounds:: DynMemory ;
1717use crate :: obj:: { Bounds , Gd , GodotClass , InstanceId , Singleton } ;
@@ -114,10 +114,10 @@ impl Callable {
114114 } ;
115115
116116 #[ cfg( feature = "experimental-threads" ) ]
117- let callable = Self :: from_sync_fn ( & callable_name, function) ;
117+ let callable = Self :: from_sync_fn ( callable_name, function) ;
118118
119119 #[ cfg( not( feature = "experimental-threads" ) ) ]
120- let callable = Self :: from_fn ( & callable_name, function) ;
120+ let callable = Self :: from_fn ( callable_name, function) ;
121121
122122 callable
123123 }
@@ -161,9 +161,14 @@ impl Callable {
161161 where
162162 R : ToGodot ,
163163 F : ' static + FnMut ( & [ & Variant ] ) -> R ,
164- S : meta :: AsArg < GString > ,
164+ S : Into < CowStr > ,
165165 {
166- Self :: from_fn_wrapper ( name, rust_function, Some ( std:: thread:: current ( ) . id ( ) ) , None )
166+ Self :: from_fn_wrapper (
167+ name. into ( ) ,
168+ rust_function,
169+ Some ( std:: thread:: current ( ) . id ( ) ) ,
170+ None ,
171+ )
167172 }
168173
169174 /// Creates a new callable linked to the given object from **single-threaded** Rust function or closure.
@@ -179,10 +184,10 @@ impl Callable {
179184 R : ToGodot ,
180185 T : GodotClass ,
181186 F : ' static + FnMut ( & [ & Variant ] ) -> R ,
182- S : meta :: AsArg < GString > ,
187+ S : Into < CowStr > ,
183188 {
184189 Self :: from_fn_wrapper (
185- name,
190+ name. into ( ) ,
186191 rust_function,
187192 Some ( std:: thread:: current ( ) . id ( ) ) ,
188193 Some ( linked_object. instance_id ( ) ) ,
@@ -196,14 +201,19 @@ impl Callable {
196201 pub fn from_local_fn < F , S > ( name : S , mut rust_function : F ) -> Self
197202 where
198203 F : ' static + FnMut ( & [ & Variant ] ) -> Result < Variant , ( ) > ,
199- S : meta :: AsArg < GString > ,
204+ S : Into < CowStr > ,
200205 {
201- meta :: arg_into_owned! ( name) ;
206+ let name_cow = name. into ( ) ;
202207
203- Self :: from_fn ( & name, move |args| {
204- // Ignore errors.
205- rust_function ( args) . unwrap_or_else ( |( ) | Variant :: nil ( ) )
206- } )
208+ Self :: from_fn_wrapper (
209+ name_cow,
210+ move |args| {
211+ // Ignore errors.
212+ rust_function ( args) . unwrap_or_else ( |( ) | Variant :: nil ( ) )
213+ } ,
214+ Some ( std:: thread:: current ( ) . id ( ) ) ,
215+ None ,
216+ )
207217 }
208218
209219 /// Create callable from **single-threaded** Rust function or closure that can only be called once.
@@ -216,38 +226,47 @@ impl Callable {
216226 where
217227 R : ToGodot ,
218228 F : ' static + FnOnce ( & [ & Variant ] ) -> R ,
219- S : meta :: AsArg < GString > ,
229+ S : Into < CowStr > ,
220230 {
221- meta :: arg_into_owned! ( name) ;
231+ let name_cow = name. into ( ) ;
222232
223233 let mut rust_fn_once = Some ( rust_function) ;
224- Self :: from_fn ( & name, move |args| {
225- let rust_fn_once = rust_fn_once
226- . take ( )
227- . expect ( "callable created with from_once_fn() has already been consumed" ) ;
228-
229- rust_fn_once ( args)
230- } )
234+ Self :: from_fn_wrapper (
235+ name_cow,
236+ move |args| {
237+ let rust_fn_once = rust_fn_once
238+ . take ( )
239+ . expect ( "callable created with from_once_fn() has already been consumed" ) ;
240+
241+ rust_fn_once ( args)
242+ } ,
243+ Some ( std:: thread:: current ( ) . id ( ) ) ,
244+ None ,
245+ )
231246 }
232247
233248 #[ cfg( feature = "trace" ) ] // Test only.
234249 #[ doc( hidden) ]
235250 pub fn __once_fn < F , S > ( name : S , rust_function : F ) -> Self
236251 where
237252 F : ' static + FnOnce ( & [ & Variant ] ) -> Variant ,
238- S : meta :: AsArg < GString > ,
253+ S : Into < CowStr > ,
239254 {
240255 Self :: from_once_fn ( name, rust_function)
241256 }
242257
243258 pub ( crate ) fn with_scoped_fn < S , F , Fc , R > ( name : S , rust_function : F , callable_usage : Fc ) -> R
244259 where
245- S : meta :: AsArg < GString > ,
260+ S : Into < CowStr > ,
246261 F : FnMut ( & [ & Variant ] ) -> Variant ,
247262 Fc : FnOnce ( & Callable ) -> R ,
248263 {
249- let callable =
250- Self :: from_fn_wrapper ( name, rust_function, Some ( std:: thread:: current ( ) . id ( ) ) , None ) ;
264+ let callable = Self :: from_fn_wrapper (
265+ name. into ( ) ,
266+ rust_function,
267+ Some ( std:: thread:: current ( ) . id ( ) ) ,
268+ None ,
269+ ) ;
251270
252271 callable_usage ( & callable)
253272 }
@@ -276,9 +295,9 @@ impl Callable {
276295 where
277296 R : ToGodot ,
278297 F : ' static + Send + Sync + FnMut ( & [ & Variant ] ) -> R ,
279- S : meta :: AsArg < GString > ,
298+ S : Into < CowStr > ,
280299 {
281- Self :: from_fn_wrapper ( name, rust_function, None , None )
300+ Self :: from_fn_wrapper ( name. into ( ) , rust_function, None , None )
282301 }
283302
284303 /// Create a highly configurable callable from Rust.
@@ -305,21 +324,19 @@ impl Callable {
305324 Self :: from_custom_info ( info)
306325 }
307326
308- fn from_fn_wrapper < F , R , S > (
309- _name : S ,
327+ fn from_fn_wrapper < F , R > (
328+ name : CowStr ,
310329 rust_function : F ,
311330 thread_id : Option < ThreadId > ,
312331 linked_object_id : Option < InstanceId > ,
313332 ) -> Self
314333 where
315334 F : FnMut ( & [ & Variant ] ) -> R ,
316335 R : ToGodot ,
317- S : meta:: AsArg < GString > ,
318336 {
319337 let wrapper = FnWrapper {
320338 rust_function,
321- #[ cfg( safeguards_balanced) ]
322- name : { _name. into_arg ( ) . cow_into_owned ( ) } ,
339+ name,
323340 thread_id,
324341 linked_object_id,
325342 } ;
@@ -332,7 +349,6 @@ impl Callable {
332349 callable_userdata : Box :: into_raw ( Box :: new ( userdata) ) as * mut std:: ffi:: c_void ,
333350 call_func : Some ( rust_callable_call_fn :: < F , R > ) ,
334351 free_func : Some ( rust_callable_destroy :: < FnWrapper < F > > ) ,
335- #[ cfg( safeguards_balanced) ]
336352 to_string_func : Some ( rust_callable_to_string_named :: < F > ) ,
337353 is_valid_func : Some ( rust_callable_is_valid) ,
338354 ..Self :: default_callable_custom_info ( )
@@ -601,8 +617,7 @@ mod custom_callable {
601617
602618 pub ( crate ) struct FnWrapper < F > {
603619 pub ( super ) rust_function : F ,
604- #[ cfg( safeguards_balanced) ]
605- pub ( super ) name : GString ,
620+ pub ( super ) name : CowStr ,
606621
607622 /// `None` if the callable is multi-threaded ([`Callable::from_sync_fn`]).
608623 pub ( super ) thread_id : Option < ThreadId > ,
@@ -692,24 +707,20 @@ mod custom_callable {
692707 {
693708 let arg_refs: & [ & Variant ] = Variant :: borrow_ref_slice ( p_args, p_argument_count as usize ) ;
694709
695- let name = name_or_optimized ! {
696- let w: & FnWrapper <F > = CallableUserdata :: inner_from_raw( callable_userdata) ;
697- w. name. to_string( )
698- } ;
699- let ctx = meta:: CallContext :: custom_callable ( & name) ;
710+ let w: & FnWrapper < F > = CallableUserdata :: inner_from_raw ( callable_userdata) ;
711+ let ctx = meta:: CallContext :: custom_callable ( & w. name ) ;
700712
701713 crate :: private:: handle_fallible_varcall ( & ctx, & mut * r_error, move || {
702714 // Get the FnWrapper again inside closure so the FnMut doesn't have to be UnwindSafe.
703715 let w: & mut FnWrapper < F > = CallableUserdata :: inner_from_raw ( callable_userdata) ;
704716
705- let name = name_or_optimized ! ( w. name. to_string( ) ) ;
706-
707717 // NOTE: this panic is currently not propagated to the caller, but results in an error message and Nil return.
708718 // See comments in itest callable_call() for details.
709719 sys:: balanced_assert!(
710720 w. thread_id. is_none( ) || w. thread_id == Some ( std:: thread:: current( ) . id( ) ) ,
711- "Callable '{name}' created with from_fn() must be called from the same thread it was created in.\n \
712- If you need to call it from any thread, use from_sync_fn() instead (requires `experimental-threads` feature)."
721+ "Callable '{}' created with from_fn() must be called from the same thread it was created in.\n \
722+ If you need to call it from any thread, use from_sync_fn() instead (requires `experimental-threads` feature).",
723+ w. name
713724 ) ;
714725
715726 let result = ( w. rust_function ) ( arg_refs) . to_variant ( ) ;
@@ -754,15 +765,15 @@ mod custom_callable {
754765 * r_is_valid = sys:: conv:: SYS_TRUE ;
755766 }
756767
757- #[ cfg( safeguards_balanced) ]
758768 pub unsafe extern "C" fn rust_callable_to_string_named < F > (
759769 callable_userdata : * mut std:: ffi:: c_void ,
760770 r_is_valid : * mut sys:: GDExtensionBool ,
761771 r_out : sys:: GDExtensionStringPtr ,
762772 ) {
763773 let w: & mut FnWrapper < F > = CallableUserdata :: inner_from_raw ( callable_userdata) ;
774+ let gstring = GString :: from ( w. name . as_ref ( ) ) ;
764775
765- w . name . clone ( ) . move_into_string_ptr ( r_out) ;
776+ gstring . move_into_string_ptr ( r_out) ;
766777 * r_is_valid = sys:: conv:: SYS_TRUE ;
767778 }
768779
0 commit comments