Simplify macro system and update doc comments.
This commit is contained in:
@@ -221,7 +221,7 @@ pub enum CallableFunction {
|
||||
Method(Shared<FnAny>),
|
||||
/// An iterator function.
|
||||
Iterator(IteratorFn),
|
||||
/// A plugin-defined function,
|
||||
/// A plugin function,
|
||||
Plugin(Shared<FnPlugin>),
|
||||
/// A script-defined function.
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
@@ -300,7 +300,7 @@ impl CallableFunction {
|
||||
Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => false,
|
||||
}
|
||||
}
|
||||
/// Is this a plugin-defined function?
|
||||
/// Is this a plugin function?
|
||||
pub fn is_plugin_fn(&self) -> bool {
|
||||
match self {
|
||||
Self::Plugin(_) => true,
|
||||
|
@@ -7,118 +7,12 @@ use crate::engine::Engine;
|
||||
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
|
||||
use crate::module::Module;
|
||||
use crate::parser::FnAccess;
|
||||
use crate::plugin::Plugin;
|
||||
use crate::r#unsafe::unsafe_cast_box;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::utils::ImmutableString;
|
||||
|
||||
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String};
|
||||
|
||||
/// A trait to register custom plugins with the `Engine`.
|
||||
///
|
||||
/// A plugin consists of a number of functions. All functions will be registered with the engine.
|
||||
pub trait RegisterPlugin<PL: crate::plugin::Plugin> {
|
||||
/// Allow extensions of the engine's behavior.
|
||||
///
|
||||
/// This can include importing modules, registering functions to the global name space, and
|
||||
/// more.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # #[cfg(not(feature = "no_float"))]
|
||||
/// use rhai::FLOAT as NUMBER;
|
||||
/// # #[cfg(feature = "no_float")]
|
||||
/// use rhai::INT as NUMBER;
|
||||
/// # #[cfg(not(feature = "no_module"))]
|
||||
/// use rhai::{Module, ModuleResolver, RegisterFn, RegisterPlugin};
|
||||
/// # #[cfg(not(feature = "no_module"))]
|
||||
/// use rhai::plugin::*;
|
||||
/// # #[cfg(not(feature = "no_module"))]
|
||||
/// use rhai::module_resolvers::*;
|
||||
///
|
||||
/// // A function we want to expose to Rhai.
|
||||
/// #[derive(Copy, Clone)]
|
||||
/// struct DistanceFunction();
|
||||
///
|
||||
/// # #[cfg(not(feature = "no_module"))]
|
||||
/// impl PluginFunction for DistanceFunction {
|
||||
/// fn is_method_call(&self) -> bool { false }
|
||||
/// fn is_varadic(&self) -> bool { false }
|
||||
///
|
||||
/// fn call(&self, args: &mut[&mut Dynamic]) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
/// let x1: NUMBER = std::mem::take(args[0]).clone().cast::<NUMBER>();
|
||||
/// let y1: NUMBER = std::mem::take(args[1]).clone().cast::<NUMBER>();
|
||||
/// let x2: NUMBER = std::mem::take(args[2]).clone().cast::<NUMBER>();
|
||||
/// let y2: NUMBER = std::mem::take(args[3]).clone().cast::<NUMBER>();
|
||||
/// # #[cfg(not(feature = "no_float"))]
|
||||
/// let square_sum = (y2 - y1).abs().powf(2.0) + (x2 -x1).abs().powf(2.0);
|
||||
/// # #[cfg(feature = "no_float")]
|
||||
/// let square_sum = (y2 - y1).abs().pow(2) + (x2 -x1).abs().pow(2);
|
||||
/// Ok(Dynamic::from(square_sum))
|
||||
/// }
|
||||
///
|
||||
/// fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||
/// Box::new(DistanceFunction())
|
||||
/// }
|
||||
///
|
||||
/// fn input_types(&self) -> Box<[std::any::TypeId]> {
|
||||
/// vec![std::any::TypeId::of::<NUMBER>(),
|
||||
/// std::any::TypeId::of::<NUMBER>(),
|
||||
/// std::any::TypeId::of::<NUMBER>(),
|
||||
/// std::any::TypeId::of::<NUMBER>()].into_boxed_slice()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // A simple custom plugin. This should not usually be done with hand-written code.
|
||||
/// #[derive(Copy, Clone)]
|
||||
/// pub struct AdvancedMathPlugin();
|
||||
///
|
||||
/// # #[cfg(not(feature = "no_module"))]
|
||||
/// impl Plugin for AdvancedMathPlugin {
|
||||
/// fn register_contents(self, engine: &mut Engine) {
|
||||
/// // Plugins are allowed to have side-effects on the engine.
|
||||
/// engine.register_fn("get_mystic_number", || { 42 as NUMBER });
|
||||
///
|
||||
/// // Main purpose: create a module to expose the functions to Rhai.
|
||||
/// //
|
||||
/// // This is currently a hack. There needs to be a better API here for "plugin"
|
||||
/// // modules.
|
||||
/// let mut m = Module::new();
|
||||
/// m.set_fn("euclidean_distance".to_string(), FnAccess::Public,
|
||||
/// &[std::any::TypeId::of::<NUMBER>(),
|
||||
/// std::any::TypeId::of::<NUMBER>(),
|
||||
/// std::any::TypeId::of::<NUMBER>(),
|
||||
/// std::any::TypeId::of::<NUMBER>()],
|
||||
/// DistanceFunction().into());
|
||||
/// let mut r = StaticModuleResolver::new();
|
||||
/// r.insert("Math::Advanced".to_string(), m);
|
||||
/// engine.set_module_resolver(Some(r));
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
///
|
||||
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
||||
///
|
||||
/// # #[cfg(not(feature = "no_module"))] {
|
||||
/// let mut engine = Engine::new();
|
||||
/// engine.register_plugin(AdvancedMathPlugin());
|
||||
///
|
||||
/// # #[cfg(feature = "no_float")]
|
||||
/// assert_eq!(engine.eval::<NUMBER>(
|
||||
/// r#"import "Math::Advanced" as math;
|
||||
/// let x = math::euclidean_distance(0, 1, 0, get_mystic_number()); x"#)?, 1681);
|
||||
/// # #[cfg(not(feature = "no_float"))]
|
||||
/// assert_eq!(engine.eval::<NUMBER>(
|
||||
/// r#"import "Math::Advanced" as math;
|
||||
/// let x = math::euclidean_distance(0.0, 1.0, 0.0, get_mystic_number()); x"#)?, 1681.0);
|
||||
/// # } // end cfg
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn register_plugin(&mut self, plugin: PL);
|
||||
}
|
||||
|
||||
/// Trait to register custom functions with the `Engine`.
|
||||
pub trait RegisterFn<FN, ARGS, RET> {
|
||||
/// Register a custom function with the `Engine`.
|
||||
@@ -223,12 +117,6 @@ pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
impl<PL: Plugin> RegisterPlugin<PL> for Engine {
|
||||
fn register_plugin(&mut self, plugin: PL) {
|
||||
plugin.register_contents(self);
|
||||
}
|
||||
}
|
||||
|
||||
/// This macro creates a closure wrapping a registered function.
|
||||
macro_rules! make_func {
|
||||
($fn:ident : $map:expr ; $($par:ident => $let:stmt => $convert:expr => $arg:expr),*) => {
|
||||
|
@@ -86,7 +86,7 @@ pub use any::Dynamic;
|
||||
pub use engine::Engine;
|
||||
pub use error::{ParseError, ParseErrorType};
|
||||
pub use fn_native::{FnPtr, IteratorFn};
|
||||
pub use fn_register::{RegisterFn, RegisterPlugin, RegisterResultFn};
|
||||
pub use fn_register::{RegisterFn, RegisterResultFn};
|
||||
pub use module::Module;
|
||||
pub use parser::{ImmutableString, AST, INT};
|
||||
pub use result::EvalAltResult;
|
||||
|
@@ -1,42 +1,38 @@
|
||||
//! Module defining plugins in Rhai for use by plugin authors.
|
||||
//! Module defining macros for developing _plugins_.
|
||||
|
||||
pub use crate::{
|
||||
fn_native::CallableFunction, stdlib::any::TypeId, stdlib::boxed::Box, stdlib::format,
|
||||
stdlib::mem, stdlib::string::ToString, stdlib::vec as new_vec, stdlib::vec::Vec, Dynamic,
|
||||
Engine, EvalAltResult, FnAccess, ImmutableString, Module, RegisterResultFn,
|
||||
};
|
||||
pub use crate::any::Dynamic;
|
||||
pub use crate::engine::Engine;
|
||||
pub use crate::fn_native::CallableFunction;
|
||||
pub use crate::fn_register::{RegisterFn, RegisterResultFn};
|
||||
pub use crate::module::Module;
|
||||
pub use crate::parser::FnAccess;
|
||||
pub use crate::result::EvalAltResult;
|
||||
pub use crate::utils::ImmutableString;
|
||||
|
||||
pub use crate::stdlib::{any::TypeId, boxed::Box, format, mem, vec as new_vec};
|
||||
|
||||
#[cfg(not(features = "no_module"))]
|
||||
pub use rhai_codegen::*;
|
||||
#[cfg(features = "no_module")]
|
||||
pub use rhai_codegen::{export_fn, register_exported_fn};
|
||||
|
||||
#[cfg(features = "sync")]
|
||||
/// Represents an externally-written plugin for the Rhai interpreter.
|
||||
/// Trait implemented by a _plugin function_.
|
||||
/// This trait should not be used directly.
|
||||
///
|
||||
/// This trait should not be used directly. Use the `#[plugin]` procedural attribute instead.
|
||||
pub trait Plugin: Send {
|
||||
fn register_contents(self, engine: &mut Engine);
|
||||
}
|
||||
|
||||
#[cfg(not(features = "sync"))]
|
||||
/// Represents an externally-written plugin for the Rhai interpreter.
|
||||
///
|
||||
/// This trait should not be used directly. Use the `#[plugin]` procedural attribute instead.
|
||||
pub trait Plugin: Send + Sync {
|
||||
fn register_contents(self, engine: &mut Engine);
|
||||
}
|
||||
|
||||
/// Represents a function that is statically defined within a plugin.
|
||||
///
|
||||
/// This trait should not be used directly. Use the `#[plugin]` procedural attribute instead.
|
||||
/// Use the `#[export_module]` and `#[export_fn]` procedural attributes instead.
|
||||
pub trait PluginFunction {
|
||||
fn is_method_call(&self) -> bool;
|
||||
fn is_varadic(&self) -> bool;
|
||||
|
||||
/// Call the plugin function with the arguments provided.
|
||||
fn call(&self, args: &mut [&mut Dynamic]) -> Result<Dynamic, Box<EvalAltResult>>;
|
||||
|
||||
/// Is this plugin function a method?
|
||||
fn is_method_call(&self) -> bool;
|
||||
|
||||
/// Is this plugin function variadic?
|
||||
fn is_variadic(&self) -> bool;
|
||||
|
||||
/// Convert a plugin function into a boxed trait object.
|
||||
fn clone_boxed(&self) -> Box<dyn PluginFunction>;
|
||||
|
||||
/// Return a boxed slice of type ID's of the function's parameters.
|
||||
fn input_types(&self) -> Box<[TypeId]>;
|
||||
}
|
||||
|
Reference in New Issue
Block a user