take() keyword; shared test with registered functions with callbacks
This commit is contained in:
parent
060dd33046
commit
ca64668e58
@ -34,7 +34,7 @@ no_index = [] # no arrays and indexing
|
|||||||
no_object = [] # no custom objects
|
no_object = [] # no custom objects
|
||||||
no_function = [] # no script-defined functions
|
no_function = [] # no script-defined functions
|
||||||
no_capture = [] # no automatic read/write binding of anonymous function's local variables to it's external context
|
no_capture = [] # no automatic read/write binding of anonymous function's local variables to it's external context
|
||||||
no_shared = [] # no explicit shared variables in the script code
|
no_shared = [] # no explicit shared() and take() functions in the script code
|
||||||
no_module = [] # no modules
|
no_module = [] # no modules
|
||||||
internals = [] # expose internal data structures
|
internals = [] # expose internal data structures
|
||||||
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
||||||
|
@ -568,7 +568,7 @@ impl Dynamic {
|
|||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
///
|
///
|
||||||
/// Both situations normally shouldn't happen since all operations in Rhai
|
/// Both situations normally shouldn't happen since most operations in Rhai
|
||||||
/// use pass-by-value data and the script executed in a single thread.
|
/// use pass-by-value data and the script executed in a single thread.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -741,7 +741,9 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a copy of a specific type to the `Dynamic`.
|
/// Get a copy of a specific type to the `Dynamic`.
|
||||||
/// Casting to `Dynamic` just returns a reference to it.
|
/// Casting to `Dynamic` returns a clone of the value in case of NON-shared
|
||||||
|
/// Dynamic. In case of Shared Dynamic returns a clone of the inner data of
|
||||||
|
/// Shared Dynamic.
|
||||||
/// Returns `None` if the cast fails.
|
/// Returns `None` if the cast fails.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn read<T: Variant + Clone>(&self) -> Option<T> {
|
pub fn read<T: Variant + Clone>(&self) -> Option<T> {
|
||||||
|
@ -93,6 +93,7 @@ pub const KEYWORD_FN_PTR: &str = "Fn";
|
|||||||
pub const KEYWORD_FN_PTR_CALL: &str = "call";
|
pub const KEYWORD_FN_PTR_CALL: &str = "call";
|
||||||
pub const KEYWORD_FN_PTR_CURRY: &str = "curry";
|
pub const KEYWORD_FN_PTR_CURRY: &str = "curry";
|
||||||
pub const KEYWORD_SHARED: &str = "shared";
|
pub const KEYWORD_SHARED: &str = "shared";
|
||||||
|
pub const KEYWORD_TAKE: &str = "take";
|
||||||
pub const KEYWORD_THIS: &str = "this";
|
pub const KEYWORD_THIS: &str = "this";
|
||||||
pub const FN_TO_STRING: &str = "to_string";
|
pub const FN_TO_STRING: &str = "to_string";
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
@ -5,7 +5,7 @@ use crate::calc_fn_hash;
|
|||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
search_imports, search_namespace, search_scope_only, Engine, Imports, State, KEYWORD_DEBUG,
|
search_imports, search_namespace, search_scope_only, Engine, Imports, State, KEYWORD_DEBUG,
|
||||||
KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_PRINT,
|
KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_PRINT,
|
||||||
KEYWORD_TYPE_OF, KEYWORD_SHARED
|
KEYWORD_TYPE_OF, KEYWORD_SHARED, KEYWORD_TAKE
|
||||||
};
|
};
|
||||||
use crate::error::ParseErrorType;
|
use crate::error::ParseErrorType;
|
||||||
use crate::fn_native::{FnCallArgs, FnPtr};
|
use crate::fn_native::{FnCallArgs, FnPtr};
|
||||||
@ -593,6 +593,9 @@ impl Engine {
|
|||||||
.into(),
|
.into(),
|
||||||
false,
|
false,
|
||||||
))
|
))
|
||||||
|
} else if _fn_name == KEYWORD_TAKE {
|
||||||
|
// take call
|
||||||
|
return Ok((obj.read::<Dynamic>().unwrap(), false));
|
||||||
} else {
|
} else {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
let redirected;
|
let redirected;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
Engine, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY,
|
Engine, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY,
|
||||||
KEYWORD_SHARED, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
KEYWORD_SHARED, KEYWORD_TAKE, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::LexError;
|
use crate::error::LexError;
|
||||||
@ -503,11 +503,12 @@ impl Token {
|
|||||||
"===" | "!==" | "->" | "<-" | "=>" | ":=" | "::<" | "(*" | "*)" | "#" | "public"
|
"===" | "!==" | "->" | "<-" | "=>" | ":=" | "::<" | "(*" | "*)" | "#" | "public"
|
||||||
| "new" | "use" | "module" | "package" | "var" | "static" | "with" | "do" | "each"
|
| "new" | "use" | "module" | "package" | "var" | "static" | "with" | "do" | "each"
|
||||||
| "then" | "goto" | "exit" | "switch" | "match" | "case" | "try" | "catch"
|
| "then" | "goto" | "exit" | "switch" | "match" | "case" | "try" | "catch"
|
||||||
| "default" | "void" | "null" | "nil" | "spawn" | "go" | "shared" | "sync"
|
| "default" | "void" | "null" | "nil" | "spawn" | "go" | "sync"
|
||||||
| "async" | "await" | "yield" => Reserved(syntax.into()),
|
| "async" | "await" | "yield" => Reserved(syntax.into()),
|
||||||
|
|
||||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
||||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_SHARED | KEYWORD_THIS => Reserved(syntax.into()),
|
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_SHARED
|
||||||
|
| KEYWORD_TAKE |KEYWORD_THIS => Reserved(syntax.into()),
|
||||||
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
@ -1440,7 +1441,7 @@ pub fn is_keyword_function(name: &str) -> bool {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no-shared"))]
|
#[cfg(not(feature = "no-shared"))]
|
||||||
{
|
{
|
||||||
result = result || name == KEYWORD_SHARED;
|
result = result || name == KEYWORD_SHARED || name == KEYWORD_TAKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -116,8 +116,8 @@ fn test_shared() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let s = shared("test");
|
let s = shared("test");
|
||||||
let i = shared(0);
|
let i = shared(0);
|
||||||
i = 2;
|
i = 2;
|
||||||
|
|
||||||
s[i] = 'S';
|
s[i] = 'S';
|
||||||
|
|
||||||
s
|
s
|
||||||
"#
|
"#
|
||||||
)?,
|
)?,
|
||||||
@ -283,6 +283,26 @@ fn test_shared() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_fn("update", TestStruct::update);
|
engine.register_fn("update", TestStruct::update);
|
||||||
engine.register_fn("merge", TestStruct::merge);
|
engine.register_fn("merge", TestStruct::merge);
|
||||||
engine.register_fn("new_ts", TestStruct::new);
|
engine.register_fn("new_ts", TestStruct::new);
|
||||||
|
engine.
|
||||||
|
register_raw_fn(
|
||||||
|
"mutate_with_cb",
|
||||||
|
&[
|
||||||
|
TypeId::of::<TestStruct>(),
|
||||||
|
TypeId::of::<INT>(),
|
||||||
|
TypeId::of::<FnPtr>(),
|
||||||
|
],
|
||||||
|
move |engine: &Engine, lib: &Module, args: &mut [&mut Dynamic]| {
|
||||||
|
let fp = std::mem::take(args[2]).cast::<FnPtr>();
|
||||||
|
let mut value = args[1].clone();
|
||||||
|
{
|
||||||
|
let mut lock = value.write_lock::<INT>().unwrap();
|
||||||
|
*lock = *lock + 1;
|
||||||
|
}
|
||||||
|
let this_ptr = args.get_mut(0).unwrap();
|
||||||
|
|
||||||
|
fp.call_dynamic(engine, lib, Some(this_ptr), [value])
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<INT>(
|
engine.eval::<INT>(
|
||||||
@ -291,11 +311,33 @@ fn test_shared() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
a.x = 100;
|
a.x = 100;
|
||||||
a.update();
|
a.update();
|
||||||
// a.merge(a);
|
a.merge(a.take()); // take is important to prevent a deadlock
|
||||||
|
|
||||||
a.x
|
a.x
|
||||||
"
|
"
|
||||||
)?,
|
)?,
|
||||||
1100
|
2200
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<INT>(
|
||||||
|
r"
|
||||||
|
let a = shared(new_ts());
|
||||||
|
let b = shared(100);
|
||||||
|
|
||||||
|
a.mutate_with_cb(b, |param| {
|
||||||
|
this.x = param;
|
||||||
|
param = 50;
|
||||||
|
this.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
a.update();
|
||||||
|
a.x += b;
|
||||||
|
|
||||||
|
a.x
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
2151
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user