From ffd1aa712702dd5e9c228282c9bb2aff77a800b2 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Sun, 6 Jul 2025 01:40:03 -0400 Subject: [PATCH] wire up keyboard events --- assets/test_prelude.ld | 8 +++++ pkg/keys.js | 14 ++++++++ pkg/ludus.js | 12 +++---- pkg/rudus.d.ts | 4 +-- pkg/rudus.js | 8 ++--- pkg/rudus_bg.wasm | 4 +-- pkg/rudus_bg.wasm.d.ts | 4 +-- src/base.rs | 2 +- src/io.rs | 6 ++-- src/lib.rs | 4 +-- src/main.rs | 7 ++++ src/value.rs | 73 ++---------------------------------------- src/world.rs | 2 +- 13 files changed, 55 insertions(+), 93 deletions(-) create mode 100644 pkg/keys.js diff --git a/assets/test_prelude.ld b/assets/test_prelude.ld index 90a0291..83ad42f 100644 --- a/assets/test_prelude.ld +++ b/assets/test_prelude.ld @@ -1438,6 +1438,12 @@ fn llist { (...xs) -> foldr (cons, xs, nil) } +&&& keyboard input +fn key_pressed? { + "Returns true ie the key is currently pressed. Keys are indicated by strings. For non-alphanumeric keys, consult the documentation to get key codes." + (key as :string) -> do keys_down > unbox > contains? (key, _) +} + #{ & completed actor functions self @@ -1455,6 +1461,8 @@ fn llist { heed! spawn_turtle! + + key_pressed? & shared memory w/ rust & `box`es are actually way cool diff --git a/pkg/keys.js b/pkg/keys.js new file mode 100644 index 0000000..9531c98 --- /dev/null +++ b/pkg/keys.js @@ -0,0 +1,14 @@ +const codes = { + "Tab": "tab", + "Enter": "enter", + "Escape": "esc", + "ArrowLeft": "left", + "ArrowRight": "right", + "ArrowUp": "up", + "ArrowDown": "down", + "Delete": "delete", +} + +export function get_code (key) { + return codes[key] ?? key +} diff --git a/pkg/ludus.js b/pkg/ludus.js index 6ed8425..30af0be 100644 --- a/pkg/ludus.js +++ b/pkg/ludus.js @@ -1,6 +1,6 @@ import {p5} from "./p5.js" - import {svg as svg_2} from "./svg.js" +import {get_code} from "./keys.js" if (window) window.ludus = {run, kill, flush_stdout, stdout, p5, flush_commands, commands, result, flush_result, input, is_running, key_down, key_up, is_starting_up, p5, svg} @@ -92,7 +92,7 @@ function io_poller () { } function bundle_keys () { - outbox.push({verb: "Keys", data: keys_down}) + outbox.push({verb: "Keys", data: Array.from(keys_down)}) } function start_io_polling () { @@ -183,12 +183,12 @@ export function flush_result () { return out } -export function key_down (str) { - if (is_running()) keys_down.add(str) +export function key_down (key) { + if (is_running()) keys_down.add(get_code(key)) } -export function key_up (str) { - if (is_running()) keys_down.delete(str) +export function key_up (key) { + if (is_running()) keys_down.delete(get_code(key)) } export {p5} from "./p5.js" diff --git a/pkg/rudus.d.ts b/pkg/rudus.d.ts index 5913583..89d7481 100644 --- a/pkg/rudus.d.ts +++ b/pkg/rudus.d.ts @@ -14,8 +14,8 @@ export interface InitOutput { readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; readonly __wbindgen_export_6: WebAssembly.Table; - readonly closure357_externref_shim: (a: number, b: number, c: any) => void; - readonly closure380_externref_shim: (a: number, b: number, c: any, d: any) => void; + readonly closure358_externref_shim: (a: number, b: number, c: any) => void; + readonly closure381_externref_shim: (a: number, b: number, c: any, d: any) => void; readonly __wbindgen_start: () => void; } diff --git a/pkg/rudus.js b/pkg/rudus.js index e5f1e2e..65e5e4e 100644 --- a/pkg/rudus.js +++ b/pkg/rudus.js @@ -240,13 +240,13 @@ function _assertNum(n) { function __wbg_adapter_20(arg0, arg1, arg2) { _assertNum(arg0); _assertNum(arg1); - wasm.closure357_externref_shim(arg0, arg1, arg2); + wasm.closure358_externref_shim(arg0, arg1, arg2); } function __wbg_adapter_46(arg0, arg1, arg2, arg3) { _assertNum(arg0); _assertNum(arg1); - wasm.closure380_externref_shim(arg0, arg1, arg2, arg3); + wasm.closure381_externref_shim(arg0, arg1, arg2, arg3); } async function __wbg_load(module, imports) { @@ -403,8 +403,8 @@ function __wbg_get_imports() { _assertBoolean(ret); return ret; }; - imports.wbg.__wbindgen_closure_wrapper8156 = function() { return logError(function (arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 358, __wbg_adapter_20); + imports.wbg.__wbindgen_closure_wrapper8157 = function() { return logError(function (arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 359, __wbg_adapter_20); return ret; }, arguments) }; imports.wbg.__wbindgen_debug_string = function(arg0, arg1) { diff --git a/pkg/rudus_bg.wasm b/pkg/rudus_bg.wasm index 4811ed9..1b4a9ac 100644 --- a/pkg/rudus_bg.wasm +++ b/pkg/rudus_bg.wasm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49098e30b1c09fc518086777a0e61b6e3a2b9d9cc70b5a24e0be15241631e947 -size 16769925 +oid sha256:3e605d8a2c5a125dc5b386be2c7f6579c4fbfeeaa7c5a4296d30b87f1d081671 +size 16771299 diff --git a/pkg/rudus_bg.wasm.d.ts b/pkg/rudus_bg.wasm.d.ts index 77b24ed..fec9303 100644 --- a/pkg/rudus_bg.wasm.d.ts +++ b/pkg/rudus_bg.wasm.d.ts @@ -9,6 +9,6 @@ export const __wbindgen_free: (a: number, b: number, c: number) => void; export const __wbindgen_malloc: (a: number, b: number) => number; export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; export const __wbindgen_export_6: WebAssembly.Table; -export const closure357_externref_shim: (a: number, b: number, c: any) => void; -export const closure380_externref_shim: (a: number, b: number, c: any, d: any) => void; +export const closure358_externref_shim: (a: number, b: number, c: any) => void; +export const closure381_externref_shim: (a: number, b: number, c: any, d: any) => void; export const __wbindgen_start: () => void; diff --git a/src/base.rs b/src/base.rs index 999afa7..4292d0f 100644 --- a/src/base.rs +++ b/src/base.rs @@ -3,7 +3,7 @@ use crate::value::*; use imbl::*; use std::rc::Rc; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Hash)] pub enum BaseFn { Nullary(&'static str, fn() -> Value), Unary(&'static str, fn(&Value) -> Value), diff --git a/src/io.rs b/src/io.rs index 305ceaf..98abf4f 100644 --- a/src/io.rs +++ b/src/io.rs @@ -34,7 +34,7 @@ pub enum MsgIn { Input(String), Fetch(String, f64, String), Kill, - Key(Vec), + Keys(Vec), } impl std::fmt::Display for MsgIn { @@ -43,7 +43,7 @@ impl std::fmt::Display for MsgIn { MsgIn::Input(str) => write!(f, "Input: {str}"), MsgIn::Kill => write!(f, "Kill"), MsgIn::Fetch(url, code, text) => write!(f, "Fetch: {url} :: {code} ::\n{text}"), - _ => todo!() + MsgIn::Keys(keys) => write!(f, "Keys: {:?}", keys), } } } @@ -64,7 +64,7 @@ impl MsgIn { Value::tuple(vec![url, result_tuple]) } MsgIn::Kill => Value::Nothing, - MsgIn::Key(downkeys) => { + MsgIn::Keys(downkeys) => { let mut vector = Vector::new(); for key in downkeys { vector.push_back(Value::String(Rc::new(key))); diff --git a/src/lib.rs b/src/lib.rs index dcfdd8b..e063d0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,9 +4,8 @@ use wasm_bindgen::prelude::*; use std::rc::Rc; use std::cell::RefCell; - const DEBUG_SCRIPT_COMPILE: bool = false; -const DEBUG_SCRIPT_RUN: bool = false; +const DEBUG_SCRIPT_RUN: bool = true; const DEBUG_PRELUDE_COMPILE: bool = false; const DEBUG_PRELUDE_RUN: bool = false; @@ -41,6 +40,7 @@ mod errors; use crate::errors::{lexing, parsing, validation}; mod panic; +mod keywords; mod js; use crate::js::*; diff --git a/src/main.rs b/src/main.rs index 7886be9..cbcdcdf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,12 @@ +use phf::phf_map; +use rudus::value::Value; use std::env; +const KEYWORDS: phf::Map<&'static str, Value> = phf_map! { + "ok" => Value::keyword("ok"), + "err" => Value::keyword("err"), +} + pub fn main() { env::set_var("RUST_BACKTRACE", "1"); println!("Hello, world.") diff --git a/src/value.rs b/src/value.rs index 16955cd..a2a8ae9 100644 --- a/src/value.rs +++ b/src/value.rs @@ -172,13 +172,12 @@ pub enum Value { Keyword(&'static str), Interned(&'static str), String(Rc), - // Number(f64), Number(NotNan), Tuple(Rc>), List(Box>), - Dict(Box>), - Box(Rc>), - Fn(Rc), + Dict(Box>), // not hashable b/c why? + Box(Rc>), // not hashable b/c refcell + Fn(Rc), // not hashable b/c refcell BaseFn(Box), Partial(Rc), Process, @@ -352,72 +351,6 @@ impl Value { } } - // pub fn to_js(&self) -> JsValue { - // use Value::*; - // match self { - // Nil => JsValue::NULL, - // True => JsValue::TRUE, - // False => JsValue::FALSE, - // Number(n) => JsValue::from_f64(*n), - // Interned(s) => JsValue::from_str(s), - // String(s) => JsValue::from_str(s.as_str()), - // Keyword(k) => JsValue::from_str(k), - // _ => todo!(), - // } - // } - - // pub fn to_json(&self) -> Option { - // use Value::*; - // match self { - // True | False | Number(..) => Some(self.show()), - // String(string) => Some(string.escape_default().to_string()), - // Interned(str) => Some(str.escape_default().to_string()), - // Keyword(str) => Some(format!("\"{str}\"")), - // List(members) => { - // let mut joined = "".to_string(); - // let mut members = members.iter(); - // if let Some(member) = members.next() { - // joined = member.to_json()?; - // } - // for member in members { - // let json = member.to_json()?; - // joined = format!("{joined},{json}"); - // } - // Some(format!("[{joined}]")) - // } - // Tuple(members) => { - // let mut joined = "".to_string(); - // let mut members = members.iter(); - // if let Some(member) = members.next() { - // joined = member.to_json()?; - // } - // for member in members { - // let json = member.to_json()?; - // joined = format!("{joined},{json}"); - // } - // Some(format!("[{joined}]")) - // } - // Dict(members) => { - // let mut joined = "".to_string(); - // let mut members = members.iter(); - // if let Some((key, value)) = members.next() { - // let json = value.to_json()?; - // joined = format!("\"{key}\":{json}") - // } - // for (key, value) in members { - // let json = value.to_json()?; - // joined = format!("{joined},\"{key}\": {json}"); - // } - // Some(format!("{{{joined}}}")) - // } - // not_serializable => { - // println!("Cannot convert to json:"); - // dbg!(not_serializable); - // None - // } - // } - // } - pub fn stringify(&self) -> String { use Value::*; match &self { diff --git a/src/world.rs b/src/world.rs index 67c1fcf..929597a 100644 --- a/src/world.rs +++ b/src/world.rs @@ -482,7 +482,7 @@ impl World { MsgIn::Input(str) => self.fill_input(str), MsgIn::Kill => self.kill_signal = true, MsgIn::Fetch(..) => self.fetch_reply(msg.into_value()), - MsgIn::Key(..) => self.register_keys(msg.into_value()), + MsgIn::Keys(..) => self.register_keys(msg.into_value()), } } }