Merge pull request #5 from jhwgh1968/rhai_plugin
Added basic Plugin trait and test
This commit is contained in:
commit
976f22d613
@ -22,6 +22,7 @@ num-traits = { version = "0.2.11", default-features = false }
|
|||||||
[features]
|
[features]
|
||||||
#default = ["no_stdlib", "no_function", "no_index", "no_object", "no_float", "only_i32", "unchecked", "no_optimize", "sync"]
|
#default = ["no_stdlib", "no_function", "no_index", "no_object", "no_float", "only_i32", "unchecked", "no_optimize", "sync"]
|
||||||
default = []
|
default = []
|
||||||
|
plugins = []
|
||||||
unchecked = [] # unchecked arithmetic
|
unchecked = [] # unchecked arithmetic
|
||||||
no_index = [] # no arrays and indexing
|
no_index = [] # no arrays and indexing
|
||||||
no_float = [] # no floating-point
|
no_float = [] # no floating-point
|
||||||
|
@ -9,6 +9,49 @@ use crate::token::Position;
|
|||||||
|
|
||||||
use crate::stdlib::{any::TypeId, boxed::Box, string::ToString};
|
use crate::stdlib::{any::TypeId, boxed::Box, string::ToString};
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[cfg(feature = "plugins")]
|
||||||
|
pub trait RegisterPlugin<PL: Plugin> {
|
||||||
|
/// Register a custom function with the `Engine`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rhai::{Dynamic, Engine, INT, Plugin, RegisterDynamicFn, RegisterPlugin};
|
||||||
|
///
|
||||||
|
/// // A simple custom plugin type. This should not usually be done with hand-written code.
|
||||||
|
/// struct AddOffsetPlugin(INT);
|
||||||
|
/// impl AddOffsetPlugin {
|
||||||
|
/// fn add_offset(&self, x: INT) -> Dynamic {
|
||||||
|
/// Dynamic::from(x + self.0)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// impl Plugin for AddOffsetPlugin {
|
||||||
|
/// fn name(&self) -> &str {
|
||||||
|
/// "My Plugin"
|
||||||
|
/// }
|
||||||
|
/// fn register_contents(self, engine: &mut Engine) {
|
||||||
|
/// let add_offset_fn: Box<dyn Fn(INT) -> Dynamic> = {
|
||||||
|
/// Box::new(move |x| self.add_offset(x))
|
||||||
|
/// };
|
||||||
|
/// engine.register_dynamic_fn("add_offset", add_offset_fn);
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
||||||
|
///
|
||||||
|
/// let mut engine = Engine::new();
|
||||||
|
/// engine.register_plugin(AddOffsetPlugin(50));
|
||||||
|
///
|
||||||
|
/// assert_eq!(engine.eval::<i64>("add_offset(42)")?, 92);
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
fn register_plugin(&mut self, plugin: PL);
|
||||||
|
}
|
||||||
|
|
||||||
/// A trait to register custom functions with the `Engine`.
|
/// A trait to register custom functions with the `Engine`.
|
||||||
pub trait RegisterFn<FN, ARGS, RET> {
|
pub trait RegisterFn<FN, ARGS, RET> {
|
||||||
/// Register a custom function with the `Engine`.
|
/// Register a custom function with the `Engine`.
|
||||||
@ -98,6 +141,15 @@ pub trait RegisterResultFn<FN, ARGS, RET> {
|
|||||||
fn register_result_fn(&mut self, name: &str, f: FN);
|
fn register_result_fn(&mut self, name: &str, f: FN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents an externally-written plugin for the Rhai interpreter.
|
||||||
|
///
|
||||||
|
/// This should not be used directly. Use the `plugin_module!` macro instead.
|
||||||
|
#[cfg(feature = "plugins")]
|
||||||
|
pub trait Plugin {
|
||||||
|
fn register_contents(self, engine: &mut Engine);
|
||||||
|
fn name(&self) -> &str;
|
||||||
|
}
|
||||||
|
|
||||||
// These types are used to build a unique _marker_ tuple type for each combination
|
// These types are used to build a unique _marker_ tuple type for each combination
|
||||||
// of function parameter types in order to make each trait implementation unique.
|
// of function parameter types in order to make each trait implementation unique.
|
||||||
// That is because stable Rust currently does not allow distinguishing implementations
|
// That is because stable Rust currently does not allow distinguishing implementations
|
||||||
@ -127,6 +179,13 @@ pub fn cloned<T: Clone>(data: &mut T) -> T {
|
|||||||
data.clone()
|
data.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "plugins")]
|
||||||
|
impl<PL: Plugin> RegisterPlugin<PL> for Engine {
|
||||||
|
fn register_plugin(&mut self, plugin: PL) {
|
||||||
|
plugin.register_contents(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This macro counts the number of arguments via recursion.
|
/// This macro counts the number of arguments via recursion.
|
||||||
macro_rules! count_args {
|
macro_rules! count_args {
|
||||||
() => { 0_usize };
|
() => { 0_usize };
|
||||||
|
@ -89,6 +89,8 @@ pub use engine::{calc_fn_spec as calc_fn_hash, Engine};
|
|||||||
pub use error::{ParseError, ParseErrorType};
|
pub use error::{ParseError, ParseErrorType};
|
||||||
pub use fn_call::FuncArgs;
|
pub use fn_call::FuncArgs;
|
||||||
pub use fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
|
pub use fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
|
||||||
|
#[cfg(feature = "plugins")]
|
||||||
|
pub use fn_register::{Plugin, RegisterPlugin};
|
||||||
pub use parser::{AST, INT};
|
pub use parser::{AST, INT};
|
||||||
pub use result::EvalAltResult;
|
pub use result::EvalAltResult;
|
||||||
pub use scope::Scope;
|
pub use scope::Scope;
|
||||||
|
Loading…
Reference in New Issue
Block a user