@@ -11,10 +11,10 @@ use godot_ffi as sys;
1111use sys:: { ffi_methods, ExtVariantType , GodotFfi } ;
1212
1313use crate :: builtin:: { inner, GString , StringName , Variant , VariantArray } ;
14- use crate :: classes;
1514use crate :: meta:: { GodotType , ToGodot } ;
1615use crate :: obj:: bounds:: DynMemory ;
1716use crate :: obj:: { Bounds , Gd , GodotClass , InstanceId } ;
17+ use crate :: { classes, meta} ;
1818
1919#[ cfg( all( since_api = "4.2" , before_api = "4.3" ) ) ]
2020type CallableCustomInfo = sys:: GDExtensionCallableCustomInfo ;
@@ -181,6 +181,40 @@ impl Callable {
181181 } )
182182 }
183183
184+ /// Create callable from **single-threaded** Rust function or closure that can only be called once.
185+ ///
186+ /// `name` is used for the string representation of the closure, which helps debugging.
187+ ///
188+ /// After the first invocation, subsequent calls will panic with a message indicating the callable has already been consumed. This is
189+ /// useful for deferred operations that should only execute once. For repeated execution, use [`from_local_fn()][Self::from_local_fn].
190+ #[ cfg( since_api = "4.2" ) ]
191+ pub ( crate ) fn from_once_fn < F , S > ( name : S , rust_function : F ) -> Self
192+ where
193+ F : ' static + FnOnce ( & [ & Variant ] ) -> Result < Variant , ( ) > ,
194+ S : meta:: AsArg < GString > ,
195+ {
196+ meta:: arg_into_owned!( name) ;
197+
198+ let mut rust_fn_once = Some ( rust_function) ;
199+ Self :: from_local_fn ( & name, move |args| {
200+ let rust_fn_once = rust_fn_once
201+ . take ( )
202+ . expect ( "callable created with from_once_fn() has already been consumed" ) ;
203+ rust_fn_once ( args)
204+ } )
205+ }
206+
207+ #[ cfg( feature = "trace" ) ] // Test only.
208+ #[ cfg( since_api = "4.2" ) ]
209+ #[ doc( hidden) ]
210+ pub fn __once_fn < F , S > ( name : S , rust_function : F ) -> Self
211+ where
212+ F : ' static + FnOnce ( & [ & Variant ] ) -> Result < Variant , ( ) > ,
213+ S : meta:: AsArg < GString > ,
214+ {
215+ Self :: from_once_fn ( name, rust_function)
216+ }
217+
184218 #[ cfg( since_api = "4.2" ) ]
185219 pub ( crate ) fn with_scoped_fn < S , F , Fc , R > ( name : S , rust_function : F , callable_usage : Fc ) -> R
186220 where
@@ -518,8 +552,6 @@ pub use custom_callable::RustCallable;
518552#[ cfg( since_api = "4.2" ) ]
519553use custom_callable:: * ;
520554
521- use crate :: meta;
522-
523555#[ cfg( since_api = "4.2" ) ]
524556mod custom_callable {
525557 use std:: hash:: Hash ;
0 commit comments