@@ -360,8 +360,8 @@ impl ScriptFunctionRegistryArc {
360
360
361
361
#[ derive( Debug , PartialEq , Eq , Hash ) ]
362
362
pub struct FunctionKey {
363
- name : Cow < ' static , str > ,
364
- namespace : Namespace ,
363
+ pub name : Cow < ' static , str > ,
364
+ pub namespace : Namespace ,
365
365
}
366
366
367
367
#[ derive( Debug , Default ) ]
@@ -372,6 +372,8 @@ pub struct ScriptFunctionRegistry {
372
372
impl ScriptFunctionRegistry {
373
373
/// Register a script function with the given name. If the name already exists,
374
374
/// the new function will be registered as an overload of the function.
375
+ ///
376
+ /// If you want to overwrite an existing function, use [`ScriptFunctionRegistry::overwrite`]
375
377
pub fn register < F , M > (
376
378
& mut self ,
377
379
namespace : Namespace ,
@@ -380,21 +382,44 @@ impl ScriptFunctionRegistry {
380
382
) where
381
383
F : ScriptFunction < ' static , M > ,
382
384
{
383
- self . register_overload ( namespace, name, func) ;
385
+ self . register_overload ( namespace, name, func, false ) ;
386
+ }
387
+
388
+ /// Overwrite a function with the given name. If the function does not exist, it will be registered as a new function.
389
+ pub fn overwrite < F , M > (
390
+ & mut self ,
391
+ namespace : Namespace ,
392
+ name : impl Into < Cow < ' static , str > > ,
393
+ func : F ,
394
+ ) where
395
+ F : ScriptFunction < ' static , M > ,
396
+ {
397
+ self . register_overload ( namespace, name, func, true ) ;
398
+ }
399
+
400
+ /// Remove a function from the registry if it exists. Returns the removed function if it was found.
401
+ pub fn remove (
402
+ & mut self ,
403
+ namespace : Namespace ,
404
+ name : impl Into < Cow < ' static , str > > ,
405
+ ) -> Option < DynamicScriptFunction > {
406
+ let name = name. into ( ) ;
407
+ self . functions . remove ( & FunctionKey { name, namespace } )
384
408
}
385
409
386
410
fn register_overload < F , M > (
387
411
& mut self ,
388
412
namespace : Namespace ,
389
413
name : impl Into < Cow < ' static , str > > ,
390
414
func : F ,
415
+ overwrite : bool ,
391
416
) where
392
417
F : ScriptFunction < ' static , M > ,
393
418
{
394
419
// always start with non-suffixed registration
395
420
// TODO: we do alot of string work, can we make this all more efficient?
396
421
let name: Cow < ' static , str > = name. into ( ) ;
397
- if !self . contains ( namespace, name. clone ( ) ) {
422
+ if overwrite || !self . contains ( namespace, name. clone ( ) ) {
398
423
let func = func
399
424
. into_dynamic_script_function ( )
400
425
. with_name ( name. clone ( ) )
@@ -636,4 +661,34 @@ mod test {
636
661
assert_eq ! ( all_functions[ 0 ] . info. name( ) , "test" ) ;
637
662
assert_eq ! ( all_functions[ 1 ] . info. name( ) , "test-1" ) ;
638
663
}
664
+
665
+ #[ test]
666
+ fn test_overwrite_script_function ( ) {
667
+ let mut registry = ScriptFunctionRegistry :: default ( ) ;
668
+ let fn_ = |a : usize , b : usize | a + b;
669
+ let namespace = Namespace :: Global ;
670
+ registry. register ( namespace, "test" , fn_) ;
671
+ let fn_2 = |a : usize , b : i32 | a + ( b as usize ) ;
672
+ registry. overwrite ( namespace, "test" , fn_2) ;
673
+
674
+ let all_functions = registry
675
+ . iter_overloads ( namespace, "test" )
676
+ . expect ( "Failed to get overloads" )
677
+ . collect :: < Vec < _ > > ( ) ;
678
+
679
+ assert_eq ! ( all_functions. len( ) , 1 ) ;
680
+ assert_eq ! ( all_functions[ 0 ] . info. name( ) , "test" ) ;
681
+ }
682
+
683
+ #[ test]
684
+ fn test_remove_script_function ( ) {
685
+ let mut registry = ScriptFunctionRegistry :: default ( ) ;
686
+ let fn_ = |a : usize , b : usize | a + b;
687
+ let namespace = Namespace :: Global ;
688
+ registry. register ( namespace, "test" , fn_) ;
689
+ let removed = registry. remove ( namespace, "test" ) ;
690
+ assert ! ( removed. is_some( ) ) ;
691
+ let removed = registry. remove ( namespace, "test" ) ;
692
+ assert ! ( removed. is_none( ) ) ;
693
+ }
639
694
}
0 commit comments