Add set_value to Scope.
This commit is contained in:
parent
44d6a5e466
commit
c4498d147d
20
README.md
20
README.md
@ -733,12 +733,14 @@ fn main() -> Result<(), EvalAltResult>
|
||||
// First create the state
|
||||
let mut scope = Scope::new();
|
||||
|
||||
// Then push some initialized variables into the state
|
||||
// NOTE: Remember the system number types in Rhai are i64 (i32 if 'only_i32') ond f64.
|
||||
// Better stick to them or it gets hard working with the script.
|
||||
// Then push (i.e. add) some initialized variables into the state.
|
||||
// Remember the system number types in Rhai are i64 (i32 if 'only_i32') ond f64.
|
||||
// Better stick to them or it gets hard working with the script.
|
||||
scope.push("y", 42_i64);
|
||||
scope.push("z", 999_i64);
|
||||
scope.push("s", "hello, world!".to_string()); // remember to use 'String', not '&str'
|
||||
|
||||
// 'set_value' adds a variable when one doesn't exist
|
||||
scope.set_value("s", "hello, world!".to_string()); // remember to use 'String', not '&str'
|
||||
|
||||
// First invocation
|
||||
engine.eval_with_scope::<()>(&mut scope, r"
|
||||
@ -749,10 +751,14 @@ fn main() -> Result<(), EvalAltResult>
|
||||
// Second invocation using the same state
|
||||
let result = engine.eval_with_scope::<i64>(&mut scope, "x")?;
|
||||
|
||||
println!("result: {}", result); // prints 979
|
||||
println!("result: {}", result); // prints 979
|
||||
|
||||
// Variable y is changed in the script
|
||||
assert_eq!(scope.get_value::<i64>("y").expect("variable x should exist"), 1);
|
||||
// Variable y is changed in the script - read it with 'get_value'
|
||||
assert_eq!(scope.get_value::<i64>("y").expect("variable y should exist"), 1);
|
||||
|
||||
// We can modify scope variables directly with 'set_value'
|
||||
scope.set_value("y", 42_i64);
|
||||
assert_eq!(scope.get_value::<i64>("y").expect("variable y should exist"), 42);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
32
src/scope.rs
32
src/scope.rs
@ -179,16 +179,44 @@ impl<'a> Scope<'a> {
|
||||
}
|
||||
|
||||
/// Get the value of an entry in the Scope, starting from the last.
|
||||
pub fn get_value<T: Any + Clone>(&self, key: &str) -> Option<T> {
|
||||
pub fn get_value<T: Any + Clone>(&self, name: &str) -> Option<T> {
|
||||
self.0
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev() // Always search a Scope in reverse order
|
||||
.find(|(_, Entry { name, .. })| name == key)
|
||||
.find(|(_, Entry { name: key, .. })| name == key)
|
||||
.and_then(|(_, Entry { value, .. })| value.downcast_ref::<T>())
|
||||
.map(T::clone)
|
||||
}
|
||||
|
||||
/// Update the value of the named variable.
|
||||
/// Search starts from the last, and only the last variable matching the specified name is updated.
|
||||
/// If no variable matching the specified name is found, a new variable is added.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics when trying to update the value of a constant.
|
||||
pub fn set_value<T: Any + Clone>(&mut self, name: &'a str, value: T) {
|
||||
match self.get(name) {
|
||||
Some((
|
||||
EntryRef {
|
||||
typ: EntryType::Constant,
|
||||
..
|
||||
},
|
||||
_,
|
||||
)) => panic!("variable {} is constant", name),
|
||||
Some((
|
||||
EntryRef {
|
||||
index,
|
||||
typ: EntryType::Normal,
|
||||
..
|
||||
},
|
||||
_,
|
||||
)) => self.0.get_mut(index).unwrap().value = value.into_dynamic(),
|
||||
None => self.push(name, value.into_dynamic()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a mutable reference to an entry in the Scope.
|
||||
pub(crate) fn get_mut(&mut self, key: EntryRef) -> &mut Dynamic {
|
||||
let entry = self.0.get_mut(key.index).expect("invalid index in Scope");
|
||||
|
@ -9,8 +9,12 @@ fn test_var_scope() -> Result<(), EvalAltResult> {
|
||||
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "x")?, 9);
|
||||
engine.eval_with_scope::<()>(&mut scope, "x = x + 1; x = x + 2;")?;
|
||||
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "x")?, 12);
|
||||
|
||||
scope.set_value("x", 42 as INT);
|
||||
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "x")?, 42);
|
||||
|
||||
engine.eval_with_scope::<()>(&mut scope, "{let x = 3}")?;
|
||||
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "x")?, 12);
|
||||
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "x")?, 42);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user