diff --git a/CHANGELOG.md b/CHANGELOG.md index dca0c2d4..f3aea521 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ New features * [`Engine::register_custom_syntax_with_state_raw`] is added. The custom syntax parser and implementation functions take on an additional parameter that holds a user-defined custom _state_ which should substantially simplify writing some custom parsers. * [`Engine::register_custom_syntax_raw`] is deprecated. +### Initial capacity for packages + +* For packages that register a large number of functions, a syntax extension for `def_package!` allows the specification of the initial _capacity_ of the package to reduce reallocation costs. +* A `capacity` method is added to the `Package` trait. + Version 1.10.0 ============== diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index 2347f451..d1181889 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -190,7 +190,7 @@ macro_rules! reg_functions { def_package! { /// Basic arithmetic package. - pub ArithmeticPackage(lib) { + pub ArithmeticPackage(lib @ 128) { lib.standard = true; combine_with_exported_module!(lib, "int", int_functions); diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 21abbde9..d4cea6b6 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -13,7 +13,7 @@ use std::{any::TypeId, cmp::Ordering, mem}; def_package! { /// Package of basic array utilities. - pub BasicArrayPackage(lib) { + pub BasicArrayPackage(lib @ 64) { lib.standard = true; combine_with_exported_module!(lib, "array", array_functions); diff --git a/src/packages/bit_field.rs b/src/packages/bit_field.rs index 5deb09ce..ea5127b5 100644 --- a/src/packages/bit_field.rs +++ b/src/packages/bit_field.rs @@ -9,7 +9,7 @@ use std::prelude::v1::*; def_package! { /// Package of basic bit-field utilities. - pub BitFieldPackage(lib) { + pub BitFieldPackage(lib @ 16) { lib.standard = true; combine_with_exported_module!(lib, "bit_field", bit_field_functions); diff --git a/src/packages/blob_basic.rs b/src/packages/blob_basic.rs index a3bbd532..8e6a1ba1 100644 --- a/src/packages/blob_basic.rs +++ b/src/packages/blob_basic.rs @@ -15,7 +15,7 @@ use crate::{FLOAT, FLOAT_BYTES}; def_package! { /// Package of basic BLOB utilities. - pub BasicBlobPackage(lib) { + pub BasicBlobPackage(lib @ 64) { lib.standard = true; combine_with_exported_module!(lib, "blob", blob_functions); diff --git a/src/packages/iter_basic.rs b/src/packages/iter_basic.rs index 6ec293cc..97a1c016 100644 --- a/src/packages/iter_basic.rs +++ b/src/packages/iter_basic.rs @@ -326,7 +326,7 @@ macro_rules! reg_range { def_package! { /// Package of basic range iterators - pub BasicIteratorPackage(lib) { + pub BasicIteratorPackage(lib @ 64) { lib.standard = true; reg_range!(lib | "range" => INT); diff --git a/src/packages/logic.rs b/src/packages/logic.rs index af494f00..da08b0d5 100644 --- a/src/packages/logic.rs +++ b/src/packages/logic.rs @@ -37,7 +37,7 @@ macro_rules! reg_functions { def_package! { /// Package of basic logic operators. - pub LogicPackage(lib) { + pub LogicPackage(lib @ 128) { lib.standard = true; #[cfg(not(feature = "only_i32"))] diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index f7c3c40f..595e6464 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -53,7 +53,7 @@ macro_rules! reg_functions { def_package! { /// Basic mathematical package. - pub BasicMathPackage(lib) { + pub BasicMathPackage(lib @ 128) { lib.standard = true; // Integer functions diff --git a/src/packages/mod.rs b/src/packages/mod.rs index ab4df033..5aa2d646 100644 --- a/src/packages/mod.rs +++ b/src/packages/mod.rs @@ -53,6 +53,14 @@ pub trait Package { #[allow(unused_variables)] fn init_engine(engine: &mut Engine) {} + /// Number of functions expected by the package. + /// + /// This capacity only acts as a hint. It may not be precise. + #[allow(unused_variables)] + fn capacity() -> usize { + 16 + } + /// Register the package with an [`Engine`]. /// /// # Example @@ -112,15 +120,17 @@ pub trait Package { /// /// def_package! { /// /// My super-duper package. -/// pub MyPackage(module) { +/// pub MyPackage(module @ 10) { /// // Load a native Rust function. /// module.set_native_fn("my_add", add); +/// } |> |engine| { +/// engine.set_custom_operator("@", 160); /// } /// } /// ``` #[macro_export] macro_rules! def_package { - ($($(#[$outer:meta])* $mod:vis $package:ident($lib:ident) + ($($(#[$outer:meta])* $mod:vis $package:ident($lib:ident $(@ $capacity:expr)?) $( : $($(#[$base_meta:meta])* $base_pkg:ty),+ )? $block:block $( |> | $engine:ident | $init_engine:block )? @@ -136,7 +146,7 @@ macro_rules! def_package { #[inline] fn init($lib: &mut $crate::Module) { $($( - $(#[$base_meta])* { <$base_pkg>::init($lib); } + $(#[$base_meta])* <$base_pkg>::init($lib); )*)* $block @@ -144,7 +154,7 @@ macro_rules! def_package { #[inline] fn init_engine(_engine: &mut $crate::Engine) { $($( - $(#[$base_meta])* { <$base_pkg>::init_engine(_engine); } + $(#[$base_meta])* <$base_pkg>::init_engine(_engine); )*)* $( @@ -152,6 +162,15 @@ macro_rules! def_package { $init_engine )* } + #[inline(always)] + fn capacity() -> usize { + let mut _capacity = 16; + $(_capacity = $capacity;)? + $($( + $(#[$base_meta])* { _capacity += <$base_pkg>::capacity(); } + )*)* + _capacity + } } impl Default for $package { @@ -166,7 +185,7 @@ macro_rules! def_package { #[inline] #[must_use] pub fn new() -> Self { - let mut module = $crate::Module::new(); + let mut module = $crate::Module::with_capacity(::capacity()); ::init(&mut module); module.build_index(); Self(module.into()) diff --git a/src/packages/pkg_core.rs b/src/packages/pkg_core.rs index 547274cd..815c2a56 100644 --- a/src/packages/pkg_core.rs +++ b/src/packages/pkg_core.rs @@ -15,7 +15,7 @@ def_package! { /// * [`BasicIteratorPackage`][super::BasicIteratorPackage] /// * [`BasicFnPackage`][super::BasicFnPackage] /// * [`DebuggingPackage`][super::DebuggingPackage] - pub CorePackage(lib) : + pub CorePackage(lib @ 0) : LanguageCorePackage, ArithmeticPackage, BasicStringPackage, diff --git a/src/packages/pkg_std.rs b/src/packages/pkg_std.rs index e7d4f1ff..e7878bfd 100644 --- a/src/packages/pkg_std.rs +++ b/src/packages/pkg_std.rs @@ -18,7 +18,7 @@ def_package! { /// * [`BasicMapPackage`][super::BasicMapPackage] /// * [`BasicTimePackage`][super::BasicTimePackage] /// * [`MoreStringPackage`][super::MoreStringPackage] - pub StandardPackage(lib) : + pub StandardPackage(lib @ 0) : CorePackage, BitFieldPackage, LogicPackage, diff --git a/src/packages/string_basic.rs b/src/packages/string_basic.rs index d8c3845a..41a00893 100644 --- a/src/packages/string_basic.rs +++ b/src/packages/string_basic.rs @@ -16,7 +16,7 @@ pub const FUNC_TO_DEBUG: &str = "to_debug"; def_package! { /// Package of basic string utilities (e.g. printing) - pub BasicStringPackage(lib) { + pub BasicStringPackage(lib @ 128) { lib.standard = true; combine_with_exported_module!(lib, "print_debug", print_debug_functions); diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index da53a127..b40dc214 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -11,7 +11,7 @@ use super::string_basic::{print_with_func, FUNC_TO_STRING}; def_package! { /// Package of additional string utilities over [`BasicStringPackage`][super::BasicStringPackage] - pub MoreStringPackage(lib) { + pub MoreStringPackage(lib @ 64) { lib.standard = true; combine_with_exported_module!(lib, "string", string_functions); diff --git a/tests/packages.rs b/tests/packages.rs index 49e9f27a..d728b4f9 100644 --- a/tests/packages.rs +++ b/tests/packages.rs @@ -7,7 +7,7 @@ use rhai::{def_package, Engine, EvalAltResult, Module, Scope, INT}; fn test_packages() -> Result<(), Box> { def_package! { /// My custom package. - MyPackage(m) : SSS { + MyPackage(m @ 32) : SSS { m.set_native_fn("hello", |x: INT| Ok(x + 1)); m.set_native_fn("@", |x: INT, y: INT| Ok(x * x + y * y)); } |> |engine| {