diff --git a/CHANGELOG.md b/CHANGELOG.md index 01592c85..ddda6008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ Rhai Release Notes ================== +Version 1.10.0 +============== + +Bug fixes +--------- + +* API for registering property getters/setters and indexers to an `Engine` now works with functions that take a first parameter of `NativeCallContext`. + + Version 1.9.0 ============= diff --git a/src/api/build_type.rs b/src/api/build_type.rs index 23199b0b..7b54fadf 100644 --- a/src/api/build_type.rs +++ b/src/api/build_type.rs @@ -125,10 +125,10 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// Register a custom function. #[inline(always)] - pub fn with_fn(&mut self, name: N, method: F) -> &mut Self + pub fn with_fn(&mut self, name: N, method: F) -> &mut Self where N: AsRef + Into, - F: RegisterNativeFunction, + F: RegisterNativeFunction, { self.engine.register_fn(name, method); self @@ -136,10 +136,10 @@ impl<'a, T: Variant + Clone> TypeBuilder<'a, T> { /// Register a custom fallible function. #[inline(always)] - pub fn with_result_fn(&mut self, name: N, method: F) -> &mut Self + pub fn with_result_fn(&mut self, name: N, method: F) -> &mut Self where N: AsRef + Into, - F: RegisterNativeFunction>, + F: RegisterNativeFunction>, { self.engine.register_result_fn(name, method); self diff --git a/src/api/register.rs b/src/api/register.rs index 3ebb8695..a6ba5284 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -1,5 +1,6 @@ //! Module that defines the public function/module registration API of [`Engine`]. +use crate::func::register::Mut; use crate::func::{FnCallArgs, RegisterNativeFunction, SendSync}; use crate::types::dynamic::Variant; use crate::{ @@ -50,10 +51,10 @@ impl Engine { /// # } /// ``` #[inline] - pub fn register_fn(&mut self, name: N, func: F) -> &mut Self + pub fn register_fn(&mut self, name: N, func: F) -> &mut Self where N: AsRef + Into, - F: RegisterNativeFunction, + F: RegisterNativeFunction, { let param_types = F::param_types(); @@ -112,10 +113,10 @@ impl Engine { /// .expect_err("expecting division by zero error!"); /// ``` #[inline] - pub fn register_result_fn(&mut self, name: N, func: F) -> &mut Self + pub fn register_result_fn(&mut self, name: N, func: F) -> &mut Self where N: AsRef + Into, - F: RegisterNativeFunction>, + F: RegisterNativeFunction>, { let param_types = F::param_types(); @@ -344,10 +345,10 @@ impl Engine { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn register_get( + pub fn register_get( &mut self, name: impl AsRef, - get_fn: impl Fn(&mut T) -> V + SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut,), V, S> + SendSync + 'static, ) -> &mut Self { self.register_fn(crate::engine::make_getter(name.as_ref()).as_str(), get_fn) } @@ -393,10 +394,10 @@ impl Engine { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn register_get_result( + pub fn register_get_result( &mut self, name: impl AsRef, - get_fn: impl Fn(&mut T) -> RhaiResultOf + SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut,), V, RhaiResultOf> + SendSync + 'static, ) -> &mut Self { self.register_result_fn(crate::engine::make_getter(name.as_ref()).as_str(), get_fn) } @@ -443,10 +444,10 @@ impl Engine { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn register_set( + pub fn register_set( &mut self, name: impl AsRef, - set_fn: impl Fn(&mut T, V) + SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, V), (), S> + SendSync + 'static, ) -> &mut Self { self.register_fn(crate::engine::make_setter(name.as_ref()).as_str(), set_fn) } @@ -494,10 +495,10 @@ impl Engine { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn register_set_result( + pub fn register_set_result( &mut self, name: impl AsRef, - set_fn: impl Fn(&mut T, V) -> RhaiResultOf<()> + SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, V), (), RhaiResultOf> + SendSync + 'static, ) -> &mut Self { self.register_result_fn(crate::engine::make_setter(name.as_ref()).as_str(), set_fn) } @@ -548,11 +549,11 @@ impl Engine { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn register_get_set( + pub fn register_get_set( &mut self, name: impl AsRef, - get_fn: impl Fn(&mut T) -> V + SendSync + 'static, - set_fn: impl Fn(&mut T, V) + SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut,), V, S> + SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, V), (), S> + SendSync + 'static, ) -> &mut Self { self.register_get(&name, get_fn).register_set(&name, set_fn) } @@ -607,9 +608,9 @@ impl Engine { /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[inline] - pub fn register_indexer_get( + pub fn register_indexer_get( &mut self, - get_fn: impl Fn(&mut T, X) -> V + SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut, X), V, S> + SendSync + 'static, ) -> &mut Self { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -686,9 +687,10 @@ impl Engine { T: Variant + Clone, X: Variant + Clone, V: Variant + Clone, + S, >( &mut self, - get_fn: impl Fn(&mut T, X) -> RhaiResultOf + SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut, X), V, RhaiResultOf> + SendSync + 'static, ) -> &mut Self { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -761,9 +763,9 @@ impl Engine { /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[inline] - pub fn register_indexer_set( + pub fn register_indexer_set( &mut self, - set_fn: impl Fn(&mut T, X, V) + SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, X, V), (), S> + SendSync + 'static, ) -> &mut Self { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -841,9 +843,10 @@ impl Engine { T: Variant + Clone, X: Variant + Clone, V: Variant + Clone, + S, >( &mut self, - set_fn: impl Fn(&mut T, X, V) -> RhaiResultOf<()> + SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, X, V), (), RhaiResultOf> + SendSync + 'static, ) -> &mut Self { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -917,10 +920,15 @@ impl Engine { /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[inline(always)] - pub fn register_indexer_get_set( + pub fn register_indexer_get_set< + T: Variant + Clone, + X: Variant + Clone, + V: Variant + Clone, + S, + >( &mut self, - get_fn: impl Fn(&mut T, X) -> V + SendSync + 'static, - set_fn: impl Fn(&mut T, X, V) + SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut, X), V, S> + SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, X, V), (), S> + SendSync + 'static, ) -> &mut Self { self.register_indexer_get(get_fn) .register_indexer_set(set_fn) diff --git a/src/func/register.rs b/src/func/register.rs index 41944cf6..d9e45e76 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -60,7 +60,7 @@ pub fn by_value(data: &mut Dynamic) -> T { } /// Trait to register custom Rust functions. -pub trait RegisterNativeFunction { +pub trait RegisterNativeFunction { /// Convert this function into a [`CallableFunction`]. #[must_use] fn into_callable_function(self) -> CallableFunction; @@ -128,7 +128,7 @@ macro_rules! def_register { FN: Fn($($param),*) -> RET + SendSync + 'static, $($par: Variant + Clone,)* RET: Variant + Clone - > RegisterNativeFunction<($($mark,)*), ()> for FN { + > RegisterNativeFunction<($($mark,)*), RET, ()> for FN { #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$param>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::() } @@ -154,7 +154,7 @@ macro_rules! def_register { FN: for<'a> Fn(NativeCallContext<'a>, $($param),*) -> RET + SendSync + 'static, $($par: Variant + Clone,)* RET: Variant + Clone - > RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN { + > RegisterNativeFunction<($($mark,)*), RET, NativeCallContext<'static>> for FN { #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$param>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::() } @@ -180,7 +180,7 @@ macro_rules! def_register { FN: Fn($($param),*) -> RhaiResultOf + SendSync + 'static, $($par: Variant + Clone,)* RET: Variant + Clone - > RegisterNativeFunction<($($mark,)*), RhaiResultOf> for FN { + > RegisterNativeFunction<($($mark,)*), RET, RhaiResultOf<()>> for FN { #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$param>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::>() } @@ -203,7 +203,7 @@ macro_rules! def_register { FN: for<'a> Fn(NativeCallContext<'a>, $($param),*) -> RhaiResultOf + SendSync + 'static, $($par: Variant + Clone,)* RET: Variant + Clone - > RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), RhaiResultOf> for FN { + > RegisterNativeFunction<($($mark,)*), RET, RhaiResultOf>> for FN { #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$param>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::>() } diff --git a/src/module/mod.rs b/src/module/mod.rs index 3afd1d18..743d2e93 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -1,6 +1,7 @@ //! Module defining external-loaded modules for Rhai. use crate::ast::FnAccess; +use crate::func::register::Mut; use crate::func::{ shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, RegisterNativeFunction, SendSync, @@ -1290,11 +1291,11 @@ impl Module { /// assert!(module.contains_fn(hash)); /// ``` #[inline(always)] - pub fn set_native_fn(&mut self, name: N, func: F) -> u64 + pub fn set_native_fn(&mut self, name: N, func: F) -> u64 where N: AsRef + Into, T: Variant + Clone, - F: RegisterNativeFunction>, + F: RegisterNativeFunction>, { self.set_fn( name, @@ -1326,14 +1327,11 @@ impl Module { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn set_getter_fn(&mut self, name: impl AsRef, func: F) -> u64 + pub fn set_getter_fn(&mut self, name: impl AsRef, func: F) -> u64 where A: Variant + Clone, T: Variant + Clone, - F: RegisterNativeFunction> - + Fn(&mut A) -> RhaiResultOf - + SendSync - + 'static, + F: RegisterNativeFunction<(Mut,), T, RhaiResultOf> + SendSync + 'static, { self.set_fn( crate::engine::make_getter(name.as_ref()).as_str(), @@ -1370,14 +1368,11 @@ impl Module { /// ``` #[cfg(not(feature = "no_object"))] #[inline(always)] - pub fn set_setter_fn(&mut self, name: impl AsRef, func: F) -> u64 + pub fn set_setter_fn(&mut self, name: impl AsRef, func: F) -> u64 where A: Variant + Clone, B: Variant + Clone, - F: RegisterNativeFunction> - + Fn(&mut A, B) -> RhaiResultOf<()> - + SendSync - + 'static, + F: RegisterNativeFunction<(Mut, B), (), RhaiResultOf> + SendSync + 'static, { self.set_fn( crate::engine::make_setter(name.as_ref()).as_str(), @@ -1418,15 +1413,12 @@ impl Module { /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[inline] - pub fn set_indexer_get_fn(&mut self, func: F) -> u64 + pub fn set_indexer_get_fn(&mut self, func: F) -> u64 where A: Variant + Clone, B: Variant + Clone, T: Variant + Clone, - F: RegisterNativeFunction> - + Fn(&mut A, B) -> RhaiResultOf - + SendSync - + 'static, + F: RegisterNativeFunction<(Mut, B), T, RhaiResultOf> + SendSync + 'static, { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -1482,15 +1474,12 @@ impl Module { /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[inline] - pub fn set_indexer_set_fn(&mut self, func: F) -> u64 + pub fn set_indexer_set_fn(&mut self, func: F) -> u64 where A: Variant + Clone, B: Variant + Clone, - C: Variant + Clone, - F: RegisterNativeFunction> - + Fn(&mut A, B, C) -> RhaiResultOf<()> - + SendSync - + 'static, + T: Variant + Clone, + F: RegisterNativeFunction<(Mut, B, T), (), RhaiResultOf> + SendSync + 'static, { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -1552,10 +1541,10 @@ impl Module { /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[inline(always)] - pub fn set_indexer_get_set_fn( + pub fn set_indexer_get_set_fn( &mut self, - get_fn: impl Fn(&mut A, B) -> RhaiResultOf + SendSync + 'static, - set_fn: impl Fn(&mut A, B, T) -> RhaiResultOf<()> + SendSync + 'static, + get_fn: impl RegisterNativeFunction<(Mut, B), T, RhaiResultOf> + SendSync + 'static, + set_fn: impl RegisterNativeFunction<(Mut, B, T), (), RhaiResultOf> + SendSync + 'static, ) -> (u64, u64) where A: Variant + Clone, diff --git a/tests/get_set.rs b/tests/get_set.rs index 2879d56b..d9065952 100644 --- a/tests/get_set.rs +++ b/tests/get_set.rs @@ -1,6 +1,6 @@ #![cfg(not(feature = "no_object"))] -use rhai::{Engine, EvalAltResult, Scope, INT}; +use rhai::{Engine, EvalAltResult, NativeCallContext, Scope, INT}; #[test] fn test_get_set() -> Result<(), Box> { @@ -217,12 +217,14 @@ fn test_get_set_chain_without_write_back() -> Result<(), Box> { .register_get_set( "value", |t: &mut Inner| t.value, - |_: &mut Inner, new: INT| panic!("Inner::value setter called with {}", new), + |_: NativeCallContext, _: &mut Inner, new: INT| { + panic!("Inner::value setter called with {}", new) + }, ) .register_type::() .register_get_set( "inner", - |t: &mut Outer| t.inner.clone(), + |_: NativeCallContext, t: &mut Outer| t.inner.clone(), |_: &mut Outer, new: Inner| panic!("Outer::inner setter called with {:?}", new), );