Intern module registration strings.
This commit is contained in:
parent
0d7f2c16cc
commit
6d1700728a
@ -26,6 +26,7 @@ Breaking changes
|
|||||||
* All `Module::set_fn_XXX` methods are removed, in favor of `Module::set_native_fn`.
|
* All `Module::set_fn_XXX` methods are removed, in favor of `Module::set_native_fn`.
|
||||||
* `Array::reduce` and `Array::reduce_rev` now take a `Dynamic` as initial value instead of a function pointer.
|
* `Array::reduce` and `Array::reduce_rev` now take a `Dynamic` as initial value instead of a function pointer.
|
||||||
* `protected`, `super` are now reserved keywords.
|
* `protected`, `super` are now reserved keywords.
|
||||||
|
* The `Module::set_fn_XXX` API now take `&str` as the function name instead of `Into<String>`.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
@ -212,10 +212,9 @@ pub fn export_module(
|
|||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let module_path = parse_macro_input!(module_path as syn::Path);
|
let module_path = parse_macro_input!(module_path as syn::Path);
|
||||||
let tokens = quote::quote! {
|
proc_macro::TokenStream::from(quote::quote! {
|
||||||
#module_path::rhai_module_generate()
|
#module_path::rhai_module_generate()
|
||||||
};
|
})
|
||||||
proc_macro::TokenStream::from(tokens)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro to combine a _plugin module_ into an existing module.
|
/// Macro to combine a _plugin module_ into an existing module.
|
||||||
@ -258,15 +257,12 @@ pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::Toke
|
|||||||
/// ```
|
/// ```
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let (module_expr, _export_name, module_path) = match crate::register::parse_register_macro(args)
|
match crate::register::parse_register_macro(args) {
|
||||||
{
|
Ok((module_expr, _export_name, module_path)) => proc_macro::TokenStream::from(quote! {
|
||||||
Ok(triple) => triple,
|
#module_path::rhai_generate_into_module(#module_expr, true);
|
||||||
Err(e) => return e.to_compile_error().into(),
|
}),
|
||||||
};
|
Err(e) => e.to_compile_error().into(),
|
||||||
let tokens = quote! {
|
}
|
||||||
#module_path::rhai_generate_into_module(#module_expr, true);
|
|
||||||
};
|
|
||||||
proc_macro::TokenStream::from(tokens)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro to register a _plugin function_ (defined via [`#[export_fn]`][export_fn]) into an `Engine`.
|
/// Macro to register a _plugin function_ (defined via [`#[export_fn]`][export_fn]) into an `Engine`.
|
||||||
@ -293,16 +289,15 @@ pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro
|
|||||||
/// ```
|
/// ```
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let (engine_expr, export_name, rust_mod_path) =
|
match crate::register::parse_register_macro(args) {
|
||||||
match crate::register::parse_register_macro(args) {
|
Ok((engine_expr, export_name, rust_mod_path)) => {
|
||||||
Ok(triple) => triple,
|
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
||||||
Err(e) => return e.to_compile_error().into(),
|
proc_macro::TokenStream::from(quote! {
|
||||||
};
|
#engine_expr.register_result_fn(&(#export_name), #gen_mod_path::dynamic_result_fn);
|
||||||
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
})
|
||||||
let tokens = quote! {
|
}
|
||||||
#engine_expr.register_result_fn(&(#export_name), #gen_mod_path::dynamic_result_fn);
|
Err(e) => e.to_compile_error().into(),
|
||||||
};
|
}
|
||||||
proc_macro::TokenStream::from(tokens)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro to register a _plugin function_ into a Rhai `Module`.
|
/// Macro to register a _plugin function_ into a Rhai `Module`.
|
||||||
@ -332,19 +327,18 @@ pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenS
|
|||||||
/// ```
|
/// ```
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let (module_expr, export_name, rust_mod_path) =
|
match crate::register::parse_register_macro(args) {
|
||||||
match crate::register::parse_register_macro(args) {
|
Ok((module_expr, export_name, rust_mod_path)) => {
|
||||||
Ok(triple) => triple,
|
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
||||||
Err(e) => return e.to_compile_error().into(),
|
proc_macro::TokenStream::from(quote! {
|
||||||
};
|
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
||||||
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
Some(#gen_mod_path::token_param_names().as_ref()),
|
||||||
let tokens = quote! {
|
#gen_mod_path::token_input_types().as_ref(),
|
||||||
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
#gen_mod_path::token_callable());
|
||||||
Some(#gen_mod_path::token_param_names().as_ref()),
|
})
|
||||||
#gen_mod_path::token_input_types().as_ref(),
|
}
|
||||||
#gen_mod_path::token_callable());
|
Err(e) => e.to_compile_error().into(),
|
||||||
};
|
}
|
||||||
proc_macro::TokenStream::from(tokens)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro to register a _plugin function_ into a Rhai `Module` and expose it globally.
|
/// Macro to register a _plugin function_ into a Rhai `Module` and expose it globally.
|
||||||
@ -374,17 +368,16 @@ pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream
|
|||||||
/// ```
|
/// ```
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn set_exported_global_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn set_exported_global_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let (module_expr, export_name, rust_mod_path) =
|
match crate::register::parse_register_macro(args) {
|
||||||
match crate::register::parse_register_macro(args) {
|
Ok((module_expr, export_name, rust_mod_path)) => {
|
||||||
Ok(triple) => triple,
|
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
||||||
Err(e) => return e.to_compile_error().into(),
|
proc_macro::TokenStream::from(quote! {
|
||||||
};
|
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
||||||
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
Some(#gen_mod_path::token_param_names().as_ref()),
|
||||||
let tokens = quote! {
|
#gen_mod_path::token_input_types().as_ref(),
|
||||||
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
#gen_mod_path::token_callable());
|
||||||
Some(#gen_mod_path::token_param_names().as_ref()),
|
})
|
||||||
#gen_mod_path::token_input_types().as_ref(),
|
}
|
||||||
#gen_mod_path::token_callable());
|
Err(e) => e.to_compile_error().into(),
|
||||||
};
|
}
|
||||||
proc_macro::TokenStream::from(tokens)
|
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,7 @@ pub fn parse_register_macro(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
let export_name = match &items[1] {
|
let export_name = match &items[1] {
|
||||||
syn::Expr::Lit(lit_str) => quote_spanned!(items[1].span() =>
|
syn::Expr::Lit(lit_str) => quote_spanned!(items[1].span() => #lit_str),
|
||||||
#lit_str.to_string()),
|
|
||||||
expr => quote! { #expr },
|
expr => quote! { #expr },
|
||||||
};
|
};
|
||||||
let rust_mod_path = if let syn::Expr::Path(ref path) = &items[2] {
|
let rust_mod_path = if let syn::Expr::Path(ref path) = &items[2] {
|
||||||
|
@ -7,7 +7,7 @@ use crate::fn_register::RegisterNativeFunction;
|
|||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
collections::BTreeMap,
|
collections::{BTreeMap, BTreeSet},
|
||||||
fmt, format,
|
fmt, format,
|
||||||
iter::empty,
|
iter::empty,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
@ -54,7 +54,7 @@ pub struct FuncInfo {
|
|||||||
/// Function access mode.
|
/// Function access mode.
|
||||||
pub access: FnAccess,
|
pub access: FnAccess,
|
||||||
/// Function name.
|
/// Function name.
|
||||||
pub name: String,
|
pub name: ImmutableString,
|
||||||
/// Number of parameters.
|
/// Number of parameters.
|
||||||
pub params: usize,
|
pub params: usize,
|
||||||
/// Parameter types (if applicable).
|
/// Parameter types (if applicable).
|
||||||
@ -147,6 +147,8 @@ pub struct Module {
|
|||||||
indexed: bool,
|
indexed: bool,
|
||||||
/// Does the [`Module`] contain indexed functions that have been exposed to the global namespace?
|
/// Does the [`Module`] contain indexed functions that have been exposed to the global namespace?
|
||||||
contains_indexed_global_functions: bool,
|
contains_indexed_global_functions: bool,
|
||||||
|
/// Interned strings
|
||||||
|
interned_strings: BTreeSet<ImmutableString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Module {
|
impl Default for Module {
|
||||||
@ -163,6 +165,7 @@ impl Default for Module {
|
|||||||
all_type_iterators: Default::default(),
|
all_type_iterators: Default::default(),
|
||||||
indexed: false,
|
indexed: false,
|
||||||
contains_indexed_global_functions: false,
|
contains_indexed_global_functions: false,
|
||||||
|
interned_strings: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,11 +175,10 @@ impl fmt::Debug for Module {
|
|||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Module({}\n{}{}{})",
|
"Module({}\n{}{}{})",
|
||||||
if let Some(ref id) = self.id {
|
self.id
|
||||||
format!("id: {:?},", id)
|
.as_ref()
|
||||||
} else {
|
.map(|id| format!("id: {:?},", id))
|
||||||
"".to_string()
|
.unwrap_or_default(),
|
||||||
},
|
|
||||||
if !self.modules.is_empty() {
|
if !self.modules.is_empty() {
|
||||||
format!(
|
format!(
|
||||||
" modules: {}\n",
|
" modules: {}\n",
|
||||||
@ -359,6 +361,15 @@ impl Module {
|
|||||||
self.indexed
|
self.indexed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return an interned string.
|
||||||
|
fn get_interned_string(&mut self, s: &str) -> ImmutableString {
|
||||||
|
self.interned_strings.get(s).cloned().unwrap_or_else(|| {
|
||||||
|
let s: ImmutableString = s.into();
|
||||||
|
self.interned_strings.insert(s.clone());
|
||||||
|
s
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate signatures for all the non-private functions in the [`Module`].
|
/// Generate signatures for all the non-private functions in the [`Module`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn gen_fn_signatures(&self) -> impl Iterator<Item = String> + '_ {
|
pub fn gen_fn_signatures(&self) -> impl Iterator<Item = String> + '_ {
|
||||||
@ -466,12 +477,12 @@ impl Module {
|
|||||||
// None + function name + number of arguments.
|
// None + function name + number of arguments.
|
||||||
let num_params = fn_def.params.len();
|
let num_params = fn_def.params.len();
|
||||||
let hash_script = crate::calc_fn_hash(empty(), &fn_def.name, num_params);
|
let hash_script = crate::calc_fn_hash(empty(), &fn_def.name, num_params);
|
||||||
let mut param_names: StaticVec<_> = fn_def.params.iter().cloned().collect();
|
let mut param_names = fn_def.params.clone();
|
||||||
param_names.push("Dynamic".into());
|
param_names.push("Dynamic".into());
|
||||||
self.functions.insert(
|
self.functions.insert(
|
||||||
hash_script,
|
hash_script,
|
||||||
Box::new(FuncInfo {
|
Box::new(FuncInfo {
|
||||||
name: fn_def.name.to_string(),
|
name: fn_def.name.clone(),
|
||||||
namespace: FnNamespace::Internal,
|
namespace: FnNamespace::Internal,
|
||||||
access: fn_def.access,
|
access: fn_def.access,
|
||||||
params: num_params,
|
params: num_params,
|
||||||
@ -612,8 +623,13 @@ impl Module {
|
|||||||
/// In other words, the number of entries should be one larger than the number of parameters.
|
/// In other words, the number of entries should be one larger than the number of parameters.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn update_fn_metadata(&mut self, hash_fn: u64, arg_names: &[&str]) -> &mut Self {
|
pub fn update_fn_metadata(&mut self, hash_fn: u64, arg_names: &[&str]) -> &mut Self {
|
||||||
|
let param_names = arg_names
|
||||||
|
.iter()
|
||||||
|
.map(|&name| self.get_interned_string(name))
|
||||||
|
.collect();
|
||||||
|
|
||||||
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
||||||
f.param_names = arg_names.iter().map(|&n| n.into()).collect();
|
f.param_names = param_names;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -625,9 +641,9 @@ impl Module {
|
|||||||
pub fn update_fn_namespace(&mut self, hash_fn: u64, namespace: FnNamespace) -> &mut Self {
|
pub fn update_fn_namespace(&mut self, hash_fn: u64, namespace: FnNamespace) -> &mut Self {
|
||||||
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
||||||
f.namespace = namespace;
|
f.namespace = namespace;
|
||||||
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
}
|
}
|
||||||
self.indexed = false;
|
|
||||||
self.contains_indexed_global_functions = false;
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,14 +657,13 @@ impl Module {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_fn(
|
pub fn set_fn(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl Into<String>,
|
name: &str,
|
||||||
namespace: FnNamespace,
|
namespace: FnNamespace,
|
||||||
access: FnAccess,
|
access: FnAccess,
|
||||||
arg_names: Option<&[&str]>,
|
arg_names: Option<&[&str]>,
|
||||||
arg_types: &[TypeId],
|
arg_types: &[TypeId],
|
||||||
func: CallableFunction,
|
func: CallableFunction,
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
let name = name.into();
|
|
||||||
let is_method = func.is_method();
|
let is_method = func.is_method();
|
||||||
|
|
||||||
let param_types = arg_types
|
let param_types = arg_types
|
||||||
@ -675,6 +690,13 @@ impl Module {
|
|||||||
|
|
||||||
let hash_fn = calc_native_fn_hash(empty(), &name, ¶m_types);
|
let hash_fn = calc_native_fn_hash(empty(), &name, ¶m_types);
|
||||||
|
|
||||||
|
let name = self.get_interned_string(name);
|
||||||
|
let param_names = arg_names
|
||||||
|
.iter()
|
||||||
|
.flat_map(|p| p.iter())
|
||||||
|
.map(|&name| self.get_interned_string(name))
|
||||||
|
.collect();
|
||||||
|
|
||||||
self.functions.insert(
|
self.functions.insert(
|
||||||
hash_fn,
|
hash_fn,
|
||||||
Box::new(FuncInfo {
|
Box::new(FuncInfo {
|
||||||
@ -683,11 +705,7 @@ impl Module {
|
|||||||
access,
|
access,
|
||||||
params: param_types.len(),
|
params: param_types.len(),
|
||||||
param_types,
|
param_types,
|
||||||
param_names: if let Some(p) = arg_names {
|
param_names,
|
||||||
p.iter().map(|&v| v.into()).collect()
|
|
||||||
} else {
|
|
||||||
Default::default()
|
|
||||||
},
|
|
||||||
func: func.into(),
|
func: func.into(),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -767,7 +785,7 @@ impl Module {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_raw_fn<T: Variant + Clone>(
|
pub fn set_raw_fn<T: Variant + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl Into<String>,
|
name: &str,
|
||||||
namespace: FnNamespace,
|
namespace: FnNamespace,
|
||||||
access: FnAccess,
|
access: FnAccess,
|
||||||
arg_types: &[TypeId],
|
arg_types: &[TypeId],
|
||||||
@ -812,7 +830,7 @@ impl Module {
|
|||||||
/// assert!(module.contains_fn(hash));
|
/// assert!(module.contains_fn(hash));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_native_fn<ARGS, T, F>(&mut self, name: impl Into<String>, func: F) -> u64
|
pub fn set_native_fn<ARGS, T, F>(&mut self, name: &str, func: F) -> u64
|
||||||
where
|
where
|
||||||
T: Variant + Clone,
|
T: Variant + Clone,
|
||||||
F: RegisterNativeFunction<ARGS, Result<T, Box<EvalAltResult>>>,
|
F: RegisterNativeFunction<ARGS, Result<T, Box<EvalAltResult>>>,
|
||||||
@ -847,7 +865,7 @@ impl Module {
|
|||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_getter_fn<ARGS, A, T, F>(&mut self, name: impl Into<String>, func: F) -> u64
|
pub fn set_getter_fn<ARGS, A, T, F>(&mut self, name: &str, func: F) -> u64
|
||||||
where
|
where
|
||||||
A: Variant + Clone,
|
A: Variant + Clone,
|
||||||
T: Variant + Clone,
|
T: Variant + Clone,
|
||||||
@ -855,7 +873,7 @@ impl Module {
|
|||||||
F: Fn(&mut A) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
F: Fn(&mut A) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||||
{
|
{
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
crate::engine::make_getter(&name.into()),
|
&crate::engine::make_getter(name),
|
||||||
FnNamespace::Global,
|
FnNamespace::Global,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
None,
|
None,
|
||||||
@ -888,7 +906,7 @@ impl Module {
|
|||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_setter_fn<ARGS, A, B, F>(&mut self, name: impl Into<String>, func: F) -> u64
|
pub fn set_setter_fn<ARGS, A, B, F>(&mut self, name: &str, func: F) -> u64
|
||||||
where
|
where
|
||||||
A: Variant + Clone,
|
A: Variant + Clone,
|
||||||
B: Variant + Clone,
|
B: Variant + Clone,
|
||||||
@ -896,7 +914,7 @@ impl Module {
|
|||||||
F: Fn(&mut A, B) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
|
F: Fn(&mut A, B) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
|
||||||
{
|
{
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
crate::engine::make_setter(&name.into()),
|
&crate::engine::make_setter(name),
|
||||||
FnNamespace::Global,
|
FnNamespace::Global,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
None,
|
None,
|
||||||
|
@ -34,7 +34,7 @@ macro_rules! register_in_bulk {
|
|||||||
{
|
{
|
||||||
let type_str = stringify!($type_names);
|
let type_str = stringify!($type_names);
|
||||||
set_exported_fn!($mod_name,
|
set_exported_fn!($mod_name,
|
||||||
format!(concat!(stringify!($op_name), "_{}"), type_str),
|
&format!(concat!(stringify!($op_name), "_{}"), type_str),
|
||||||
crate::$op_name::$type_names::op);
|
crate::$op_name::$type_names::op);
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
Loading…
Reference in New Issue
Block a user