Archived
add state_get/state_set builtins for frame-persistent key-value store
This commit is contained in:
+24
-1
@@ -2322,7 +2322,9 @@ fn dispatch_builtin(
|
|||||||
"Content-Type", content_type
|
"Content-Type", content_type
|
||||||
).unwrap();
|
).unwrap();
|
||||||
if let Some(dir) = html_dir {
|
if let Some(dir) = html_dir {
|
||||||
let asset_path = dir.join(file_name);
|
// Try src/assets/<file> first, then src/<file> as fallback
|
||||||
|
let asset_path = dir.join("assets").join(file_name);
|
||||||
|
let asset_path = if asset_path.exists() { asset_path } else { dir.join(file_name) };
|
||||||
if let Ok(bytes) = std::fs::read(&asset_path) {
|
if let Ok(bytes) = std::fs::read(&asset_path) {
|
||||||
let _ = request.respond(
|
let _ = request.respond(
|
||||||
tiny_http::Response::from_data(bytes)
|
tiny_http::Response::from_data(bytes)
|
||||||
@@ -4551,6 +4553,27 @@ fn dispatch_builtin(
|
|||||||
BuiltinResult::Handled
|
BuiltinResult::Handled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Frame-persistent key-value state ────────────────────────────────
|
||||||
|
// state_set / state_get use GLOBAL_STATE so values survive between frames
|
||||||
|
// when canvas_run_loop calls the draw function repeatedly.
|
||||||
|
|
||||||
|
"state_set" => {
|
||||||
|
// state_set(key: String, val: String) -> Void
|
||||||
|
let val = match stack.pop().unwrap_or(Value::Nil) { Value::Str(s) => s, _ => String::new() };
|
||||||
|
let key = match stack.pop().unwrap_or(Value::Nil) { Value::Str(s) => s, _ => String::new() };
|
||||||
|
GLOBAL_STATE.with(|gs| gs.borrow_mut().insert(key, val));
|
||||||
|
stack.push(Value::Nil);
|
||||||
|
BuiltinResult::Handled
|
||||||
|
}
|
||||||
|
|
||||||
|
"state_get" => {
|
||||||
|
// state_get(key: String) -> String
|
||||||
|
let key = match stack.pop().unwrap_or(Value::Nil) { Value::Str(s) => s, _ => String::new() };
|
||||||
|
let val = GLOBAL_STATE.with(|gs| gs.borrow().get(&key).cloned().unwrap_or_default());
|
||||||
|
stack.push(Value::Str(val));
|
||||||
|
BuiltinResult::Handled
|
||||||
|
}
|
||||||
|
|
||||||
"canvas_run_loop" => {
|
"canvas_run_loop" => {
|
||||||
// canvas_run_loop(draw_fn: String) -> Void (never returns)
|
// canvas_run_loop(draw_fn: String) -> Void (never returns)
|
||||||
let draw_fn = match stack.pop().unwrap_or(Value::Nil) { Value::Str(s) => s, _ => "draw".into() };
|
let draw_fn = match stack.pop().unwrap_or(Value::Nil) { Value::Str(s) => s, _ => "draw".into() };
|
||||||
|
|||||||
@@ -278,6 +278,8 @@ impl TypeEnv {
|
|||||||
env.functions.insert("canvas_events".into(), str_fn(vec![], s.clone()));
|
env.functions.insert("canvas_events".into(), str_fn(vec![], s.clone()));
|
||||||
env.functions.insert("canvas_swap".into(), str_fn(vec![], Type::Void));
|
env.functions.insert("canvas_swap".into(), str_fn(vec![], Type::Void));
|
||||||
env.functions.insert("canvas_run_loop".into(), str_fn(vec![s.clone()], Type::Void));
|
env.functions.insert("canvas_run_loop".into(), str_fn(vec![s.clone()], Type::Void));
|
||||||
|
env.functions.insert("state_set".into(), str_fn(vec![s.clone(), s.clone()], Type::Void));
|
||||||
|
env.functions.insert("state_get".into(), str_fn(vec![s.clone()], s.clone()));
|
||||||
|
|
||||||
// Math
|
// Math
|
||||||
for name in &["math_abs","math_floor","math_ceil","math_round","math_sqrt"] {
|
for name in &["math_abs","math_floor","math_ceil","math_round","math_sqrt"] {
|
||||||
|
|||||||
Reference in New Issue
Block a user