Use function pointers for iterators.
This commit is contained in:
parent
55ee4d6a19
commit
80fcc40710
@ -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`.
|
||||||
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>>
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -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>>
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user