wire up keyboard events

This commit is contained in:
Scott Richmond 2025-07-06 01:40:03 -04:00
parent 9c8159dde6
commit ffd1aa7127
13 changed files with 55 additions and 93 deletions

View File

@ -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

14
pkg/keys.js Normal file
View File

@ -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
}

View File

@ -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"

4
pkg/rudus.d.ts vendored
View File

@ -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;
}

View File

@ -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) {

BIN
pkg/rudus_bg.wasm (Stored with Git LFS)

Binary file not shown.

View File

@ -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;

View File

@ -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),

View File

@ -34,7 +34,7 @@ pub enum MsgIn {
Input(String),
Fetch(String, f64, String),
Kill,
Key(Vec<String>),
Keys(Vec<String>),
}
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)));

View File

@ -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::*;

View File

@ -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.")

View File

@ -172,13 +172,12 @@ pub enum Value {
Keyword(&'static str),
Interned(&'static str),
String(Rc<String>),
// Number(f64),
Number(NotNan<f64>),
Tuple(Rc<Vec<Value>>),
List(Box<Vector<Value>>),
Dict(Box<HashMap<Key, Value>>),
Box(Rc<RefCell<Value>>),
Fn(Rc<LFn>),
Dict(Box<HashMap<Key, Value>>), // not hashable b/c why?
Box(Rc<RefCell<Value>>), // not hashable b/c refcell
Fn(Rc<LFn>), // not hashable b/c refcell
BaseFn(Box<BaseFn>),
Partial(Rc<Partial>),
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<String> {
// 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 {

View File

@ -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()),
}
}
}