Skip to main content

siglus_scene_vm/runtime/forms/
keylist.rs

1use anyhow::Result;
2
3use crate::runtime::{CommandContext, Value};
4
5use super::key;
6
7fn current_chain(ctx: &CommandContext) -> Option<&[i32]> {
8    let vm_call = ctx.vm_call.as_ref()?;
9    Some(vm_call.element.as_slice())
10}
11
12pub fn dispatch(ctx: &mut CommandContext, _args: &[Value]) -> Result<bool> {
13    let Some(chain) = current_chain(ctx) else {
14        return Ok(false);
15    };
16    if chain.len() < 2 {
17        return Ok(false);
18    }
19    let op = chain[1] as i64;
20    match op {
21        // testcase startup still uses compact keylist alias 24 with -1 as the
22        // array/index marker instead of the canonical ELM_ARRAY id.
23        o if o == ctx.ids.elm_array as i64 || o == -1 => {
24            if chain.len() == 3 {
25                ctx.push(Value::Element(chain.to_vec()));
26                return Ok(true);
27            }
28            if chain.len() < 4 {
29                return Ok(false);
30            }
31            let vk = chain[2] as i64;
32            let key_op = chain[3] as i64;
33            let v = key::query(ctx, vk, key_op);
34            ctx.push(Value::Int(v));
35            Ok(true)
36        }
37        o if o == ctx.ids.keylist_op_wait as i64 => {
38            ctx.wait.wait_key();
39            Ok(true)
40        }
41        o if o == ctx.ids.keylist_op_wait_force as i64 => {
42            ctx.wait.clear();
43            ctx.wait.wait_key();
44            Ok(true)
45        }
46        o if o == ctx.ids.keylist_op_clear as i64 => {
47            ctx.script_input.clear_keyboard();
48            Ok(true)
49        }
50        o if o == ctx.ids.keylist_op_next as i64 => {
51            ctx.script_input.next_keyboard_frame();
52            Ok(true)
53        }
54        _ => Ok(false),
55    }
56}