Add get_fn_metadata_list.
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
use crate::module::SharedScriptFnDef;
|
||||
use crate::plugin::*;
|
||||
use crate::{def_package, FnPtr};
|
||||
use crate::stdlib::iter::empty;
|
||||
use crate::{calc_script_fn_hash, def_package, FnPtr, ImmutableString, NativeCallContext, INT};
|
||||
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
use crate::{stdlib::collections::HashMap, Array, Map};
|
||||
|
||||
def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, {
|
||||
combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions);
|
||||
@@ -13,10 +20,111 @@ mod fn_ptr_functions {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
pub mod anonymous {
|
||||
pub mod functions {
|
||||
#[rhai_fn(name = "is_anonymous", get = "is_anonymous")]
|
||||
pub fn is_anonymous(f: &mut FnPtr) -> bool {
|
||||
f.is_anonymous()
|
||||
}
|
||||
|
||||
pub fn is_def_fn(ctx: NativeCallContext, fn_name: &str, num_params: INT) -> bool {
|
||||
if num_params < 0 {
|
||||
false
|
||||
} else {
|
||||
let hash_script = calc_script_fn_hash(empty(), fn_name, num_params as usize);
|
||||
ctx.engine()
|
||||
.has_override(ctx.mods, ctx.lib, 0, hash_script, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub mod functions_and_maps {
|
||||
pub fn get_fn_metadata_list(ctx: NativeCallContext) -> Array {
|
||||
collect_fn_metadata(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
fn collect_fn_metadata(ctx: NativeCallContext) -> Array {
|
||||
// Create a metadata record for a function.
|
||||
fn make_metadata(
|
||||
dict: &HashMap<String, ImmutableString>,
|
||||
namespace: Option<ImmutableString>,
|
||||
f: SharedScriptFnDef,
|
||||
) -> Map {
|
||||
let mut map = Map::with_capacity(6);
|
||||
|
||||
if let Some(ns) = namespace {
|
||||
map.insert(dict["namespace"].clone(), ns.into());
|
||||
}
|
||||
map.insert(dict["name"].clone(), f.name.clone().into());
|
||||
map.insert(
|
||||
dict["access"].clone(),
|
||||
match f.access {
|
||||
FnAccess::Public => dict["public"].clone(),
|
||||
FnAccess::Private => dict["private"].clone(),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
map.insert(
|
||||
dict["is_anonymous"].clone(),
|
||||
f.name.starts_with(crate::engine::FN_ANONYMOUS).into(),
|
||||
);
|
||||
map.insert(
|
||||
dict["params"].clone(),
|
||||
f.params
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(Into::<Dynamic>::into)
|
||||
.collect::<Array>()
|
||||
.into(),
|
||||
);
|
||||
|
||||
map.into()
|
||||
}
|
||||
|
||||
// Recursively scan modules for script-defined functions.
|
||||
fn scan_module(
|
||||
list: &mut Array,
|
||||
dict: &HashMap<String, ImmutableString>,
|
||||
namespace: ImmutableString,
|
||||
module: &Module,
|
||||
) {
|
||||
module.iter_script_fn().for_each(|(_, _, _, _, f)| {
|
||||
list.push(make_metadata(dict, Some(namespace.clone()), f).into())
|
||||
});
|
||||
module.iter_sub_modules().for_each(|(ns, m)| {
|
||||
let ns: ImmutableString = format!("{}::{}", namespace, ns).into();
|
||||
scan_module(list, dict, ns, m.as_ref())
|
||||
});
|
||||
}
|
||||
|
||||
// Intern strings
|
||||
let mut dict = HashMap::<String, ImmutableString>::with_capacity(8);
|
||||
dict.insert("namespace".into(), "namespace".into());
|
||||
dict.insert("name".into(), "name".into());
|
||||
dict.insert("access".into(), "access".into());
|
||||
dict.insert("public".into(), "public".into());
|
||||
dict.insert("private".into(), "private".into());
|
||||
dict.insert("is_anonymous".into(), "is_anonymous".into());
|
||||
dict.insert("params".into(), "params".into());
|
||||
|
||||
let mut list: Array = Default::default();
|
||||
|
||||
ctx.lib
|
||||
.iter()
|
||||
.flat_map(|m| m.iter_script_fn())
|
||||
.for_each(|(_, _, _, _, f)| list.push(make_metadata(&dict, None, f).into()));
|
||||
|
||||
if let Some(mods) = ctx.mods {
|
||||
mods.iter()
|
||||
.for_each(|(ns, m)| scan_module(&mut list, &dict, ns, m.as_ref()));
|
||||
}
|
||||
|
||||
list
|
||||
}
|
||||
|
Reference in New Issue
Block a user