Use function pointers for iterators.

This commit is contained in:
Stephen Chung 2020-05-20 19:27:23 +08:00
parent 55ee4d6a19
commit 80fcc40710
6 changed files with 23 additions and 57 deletions

View File

@ -4,9 +4,7 @@ use crate::any::{Dynamic, Variant};
use crate::engine::{make_getter, make_setter, Engine, State, FUNC_INDEXER}; use crate::engine::{make_getter, make_setter, Engine, State, FUNC_INDEXER};
use crate::error::ParseError; use crate::error::ParseError;
use crate::fn_call::FuncArgs; use crate::fn_call::FuncArgs;
use crate::fn_native::{ use crate::fn_native::{IteratorFn, ObjectGetCallback, ObjectIndexerCallback, ObjectSetCallback};
IteratorCallback, ObjectGetCallback, ObjectIndexerCallback, ObjectSetCallback,
};
use crate::fn_register::RegisterFn; use crate::fn_register::RegisterFn;
use crate::optimize::{optimize_into_ast, OptimizationLevel}; use crate::optimize::{optimize_into_ast, OptimizationLevel};
use crate::parser::{parse, parse_global_expr, AST}; use crate::parser::{parse, parse_global_expr, AST};
@ -123,8 +121,8 @@ impl Engine {
/// Register an iterator adapter for a type with the `Engine`. /// Register an iterator adapter for a type with the `Engine`.
/// This is an advanced feature. /// This is an advanced feature.
pub fn register_iterator<T: Variant + Clone, F: IteratorCallback>(&mut self, f: F) { pub fn register_iterator<T: Variant + Clone>(&mut self, f: IteratorFn) {
self.global_module.set_iter(TypeId::of::<T>(), Box::new(f)); self.global_module.set_iter(TypeId::of::<T>(), f);
} }
/// Register a getter function for a member of a registered type with the `Engine`. /// Register a getter function for a member of a registered type with the `Engine`.

View File

@ -11,10 +11,7 @@ pub type FnAny = dyn Fn(&mut FnCallArgs) -> Result<Dynamic, Box<EvalAltResult>>
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub type FnAny = dyn Fn(&mut FnCallArgs) -> Result<Dynamic, Box<EvalAltResult>>; pub type FnAny = dyn Fn(&mut FnCallArgs) -> Result<Dynamic, Box<EvalAltResult>>;
#[cfg(feature = "sync")] pub type IteratorFn = fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;
pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync;
#[cfg(not(feature = "sync"))]
pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub type PrintCallback = dyn Fn(&str) + Send + Sync + 'static; pub type PrintCallback = dyn Fn(&str) + Send + Sync + 'static;
@ -57,32 +54,11 @@ pub trait ObjectIndexerCallback<T, X, U>: Fn(&mut T, X) -> U + 'static {}
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
impl<F: Fn(&mut T, X) -> U + 'static, T, X, U> ObjectIndexerCallback<T, X, U> for F {} impl<F: Fn(&mut T, X) -> U + 'static, T, X, U> ObjectIndexerCallback<T, X, U> for F {}
#[cfg(feature = "sync")]
pub trait IteratorCallback:
Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync + 'static
{
}
#[cfg(feature = "sync")]
impl<F: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync + 'static> IteratorCallback
for F
{
}
#[cfg(not(feature = "sync"))]
pub trait IteratorCallback: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static> IteratorCallback for F {}
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub type SharedNativeFunction = Rc<FnAny>; pub type SharedNativeFunction = Rc<FnAny>;
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub type SharedNativeFunction = Arc<FnAny>; pub type SharedNativeFunction = Arc<FnAny>;
#[cfg(not(feature = "sync"))]
pub type SharedIteratorFn = Rc<IteratorFn>;
#[cfg(feature = "sync")]
pub type SharedIteratorFn = Arc<IteratorFn>;
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub type SharedFnDef = Arc<FnDef>; pub type SharedFnDef = Arc<FnDef>;
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
@ -97,7 +73,7 @@ pub enum CallableFunction {
/// and the rest passed by value. /// and the rest passed by value.
Method(SharedNativeFunction), Method(SharedNativeFunction),
/// An iterator function. /// An iterator function.
Iterator(SharedIteratorFn), Iterator(IteratorFn),
/// A script-defined function. /// A script-defined function.
Script(SharedFnDef), Script(SharedFnDef),
} }
@ -158,9 +134,9 @@ impl CallableFunction {
/// # Panics /// # Panics
/// ///
/// Panics if the `CallableFunction` is not `Iterator`. /// Panics if the `CallableFunction` is not `Iterator`.
pub fn get_iter_fn(&self) -> &IteratorFn { pub fn get_iter_fn(&self) -> IteratorFn {
match self { match self {
Self::Iterator(f) => f.as_ref(), Self::Iterator(f) => *f,
Self::Pure(_) | Self::Method(_) | Self::Script(_) => panic!(), Self::Pure(_) | Self::Method(_) | Self::Script(_) => panic!(),
} }
} }

View File

@ -3,7 +3,7 @@
use crate::any::{Dynamic, Variant}; use crate::any::{Dynamic, Variant};
use crate::calc_fn_hash; use crate::calc_fn_hash;
use crate::engine::{Engine, FunctionsLib}; use crate::engine::{Engine, FunctionsLib};
use crate::fn_native::{CallableFunction as CF, FnCallArgs, IteratorFn, SharedIteratorFn}; use crate::fn_native::{CallableFunction as CF, FnCallArgs, IteratorFn};
use crate::parser::{ use crate::parser::{
FnAccess, FnAccess,
FnAccess::{Private, Public}, FnAccess::{Private, Public},
@ -53,7 +53,7 @@ pub struct Module {
fn_lib: FunctionsLib, fn_lib: FunctionsLib,
/// Iterator functions, keyed by the type producing the iterator. /// Iterator functions, keyed by the type producing the iterator.
type_iterators: HashMap<TypeId, SharedIteratorFn>, type_iterators: HashMap<TypeId, IteratorFn>,
/// Flattened collection of all external Rust functions, native or scripted, /// Flattened collection of all external Rust functions, native or scripted,
/// including those in sub-modules. /// including those in sub-modules.
@ -659,13 +659,13 @@ impl Module {
} }
/// Set a type iterator into the module. /// Set a type iterator into the module.
pub fn set_iter(&mut self, typ: TypeId, func: Box<IteratorFn>) { pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) {
self.type_iterators.insert(typ, func.into()); self.type_iterators.insert(typ, func);
} }
/// Get the specified type iterator. /// Get the specified type iterator.
pub fn get_iter(&self, id: TypeId) -> Option<&IteratorFn> { pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
self.type_iterators.get(&id).map(|v| v.as_ref()) self.type_iterators.get(&id).cloned()
} }
} }

View File

@ -120,8 +120,6 @@ def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
// Register array iterator // Register array iterator
lib.set_iter( lib.set_iter(
TypeId::of::<Array>(), TypeId::of::<Array>(),
Box::new(|arr| Box::new( |arr| Box::new(arr.cast::<Array>().into_iter()) as Box<dyn Iterator<Item = Dynamic>>,
arr.cast::<Array>().into_iter()) as Box<dyn Iterator<Item = Dynamic>>
),
); );
}); });

View File

@ -14,13 +14,10 @@ fn reg_range<T: Variant + Clone>(lib: &mut Module)
where where
Range<T>: Iterator<Item = T>, Range<T>: Iterator<Item = T>,
{ {
lib.set_iter( lib.set_iter(TypeId::of::<Range<T>>(), |source| {
TypeId::of::<Range<T>>(),
Box::new(|source| {
Box::new(source.cast::<Range<T>>().map(|x| x.into_dynamic())) Box::new(source.cast::<Range<T>>().map(|x| x.into_dynamic()))
as Box<dyn Iterator<Item = Dynamic>> as Box<dyn Iterator<Item = Dynamic>>
}), });
);
} }
fn get_range<T: Variant + Clone>(from: T, to: T) -> FuncReturn<Range<T>> { fn get_range<T: Variant + Clone>(from: T, to: T) -> FuncReturn<Range<T>> {
@ -58,13 +55,10 @@ where
T: Variant + Clone + PartialOrd, T: Variant + Clone + PartialOrd,
StepRange<T>: Iterator<Item = T>, StepRange<T>: Iterator<Item = T>,
{ {
lib.set_iter( lib.set_iter(TypeId::of::<StepRange<T>>(), |source| {
TypeId::of::<StepRange<T>>(),
Box::new(|source| {
Box::new(source.cast::<StepRange<T>>().map(|x| x.into_dynamic())) Box::new(source.cast::<StepRange<T>>().map(|x| x.into_dynamic()))
as Box<dyn Iterator<Item = Dynamic>> as Box<dyn Iterator<Item = Dynamic>>
}), });
);
} }
fn get_step_range<T>(from: T, to: T, step: T) -> FuncReturn<StepRange<T>> fn get_step_range<T>(from: T, to: T, step: T) -> FuncReturn<StepRange<T>>

View File

@ -83,7 +83,7 @@ impl PackagesCollection {
self.packages.iter().any(|p| p.contains_iter(id)) self.packages.iter().any(|p| p.contains_iter(id))
} }
/// Get the specified TypeId iterator. /// Get the specified TypeId iterator.
pub fn get_iter(&self, id: TypeId) -> Option<&IteratorFn> { pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
self.packages self.packages
.iter() .iter()
.map(|p| p.get_iter(id)) .map(|p| p.get_iter(id))