Add custom state.

This commit is contained in:
Stephen Chung
2022-05-02 00:03:45 +08:00
parent 98e0042214
commit c69f98c2c4
13 changed files with 91 additions and 46 deletions

View File

@@ -18,7 +18,7 @@ pub type OnDebuggingInit = dyn Fn() -> Dynamic + Send + Sync;
/// Callback function for debugging.
#[cfg(not(feature = "sync"))]
pub type OnDebuggerCallback = dyn Fn(
&mut EvalContext,
EvalContext,
DebuggerEvent,
ASTNode,
Option<&str>,
@@ -26,13 +26,7 @@ pub type OnDebuggerCallback = dyn Fn(
) -> RhaiResultOf<DebuggerCommand>;
/// Callback function for debugging.
#[cfg(feature = "sync")]
pub type OnDebuggerCallback = dyn Fn(
&mut EvalContext,
DebuggerEvent,
ASTNode,
Option<&str>,
Position,
) -> RhaiResultOf<DebuggerCommand>
pub type OnDebuggerCallback = dyn Fn(EvalContext, DebuggerEvent, ASTNode, Option<&str>, Position) -> RhaiResultOf<DebuggerCommand>
+ Send
+ Sync;
@@ -525,7 +519,7 @@ impl Engine {
Some(source.as_str())
};
let mut context = crate::EvalContext {
let context = crate::EvalContext {
engine: self,
scope,
global,
@@ -536,7 +530,7 @@ impl Engine {
};
if let Some((.., ref on_debugger)) = self.debugger {
let command = on_debugger(&mut context, event, node, source, node.position())?;
let command = on_debugger(context, event, node, source, node.position())?;
match command {
DebuggerCommand::Continue => {
@@ -559,12 +553,12 @@ impl Engine {
// Bump a level if it is a function call
let level = match node {
ASTNode::Expr(Expr::FnCall(..)) | ASTNode::Stmt(Stmt::FnCall(..)) => {
context.call_level() + 1
level + 1
}
ASTNode::Stmt(Stmt::Expr(e)) if matches!(e.as_ref(), Expr::FnCall(..)) => {
context.call_level() + 1
level + 1
}
_ => context.call_level(),
_ => level,
};
global.debugger.status = DebuggerStatus::FunctionExit(level);
Ok(None)

View File

@@ -60,6 +60,18 @@ impl<'s, 'ps, 'm, 'pm, 'pt> EvalContext<'_, 's, 'ps, 'm, 'pm, '_, '_, 'pt> {
pub fn iter_imports(&self) -> impl Iterator<Item = (&str, &Module)> {
self.global.iter_imports()
}
/// Custom state kept in a [`Dynamic`].
#[inline(always)]
#[must_use]
pub const fn tag(&self) -> &Dynamic {
&self.global.tag
}
/// Mutable reference to the custom state kept in a [`Dynamic`].
#[inline(always)]
#[must_use]
pub fn tag_mut(&mut self) -> &mut Dynamic {
&mut self.global.tag
}
/// _(internals)_ The current [`GlobalRuntimeState`].
/// Exported under the `internals` feature only.
#[cfg(feature = "internals")]

View File

@@ -161,7 +161,7 @@ impl Engine {
level,
};
let var_name = expr.get_variable_name(true).expect("`Expr::Variable`");
match resolve_var(var_name, index, &context) {
match resolve_var(var_name, index, context) {
Ok(Some(mut result)) => {
result.set_access_mode(AccessMode::ReadOnly);
return Ok((result.into(), var_pos));

View File

@@ -1,6 +1,6 @@
//! Global runtime state.
use crate::{Engine, Identifier};
use crate::{Dynamic, Engine, Identifier};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{fmt, marker::PhantomData};
@@ -9,7 +9,7 @@ use std::{fmt, marker::PhantomData};
#[cfg(not(feature = "no_module"))]
#[cfg(not(feature = "no_function"))]
pub type GlobalConstants =
crate::Shared<crate::Locked<std::collections::BTreeMap<Identifier, crate::Dynamic>>>;
crate::Shared<crate::Locked<std::collections::BTreeMap<Identifier, Dynamic>>>;
/// _(internals)_ Global runtime states.
/// Exported under the `internals` feature only.
@@ -64,6 +64,8 @@ pub struct GlobalRuntimeState<'a> {
#[cfg(not(feature = "no_module"))]
#[cfg(not(feature = "no_function"))]
pub constants: Option<GlobalConstants>,
/// Custom state that can be used by the external host.
pub tag: Dynamic,
/// Debugging interface.
#[cfg(feature = "debugging")]
pub debugger: super::Debugger,
@@ -95,6 +97,7 @@ impl GlobalRuntimeState<'_> {
#[cfg(not(feature = "no_module"))]
#[cfg(not(feature = "no_function"))]
constants: None,
tag: Dynamic::UNIT,
#[cfg(feature = "debugging")]
debugger: crate::eval::Debugger::new(_engine),
dummy: PhantomData::default(),

View File

@@ -841,7 +841,7 @@ impl Engine {
level,
};
match filter(true, info, &context) {
match filter(true, info, context) {
Ok(true) => None,
Ok(false) => {
Some(Err(