[oden] Input
This commit is contained in:
parent
c934914ac5
commit
e0878b4ea6
6 changed files with 363 additions and 14 deletions
|
|
@ -3,6 +3,8 @@ use std::sync::atomic::{AtomicU32, Ordering};
|
|||
use std::sync::mpsc::Sender;
|
||||
use std::sync::Arc;
|
||||
|
||||
// TODO: Fix the dumb command structures.
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrintCommand {
|
||||
pub text: String,
|
||||
|
|
|
|||
132
src/script/input.rs
Normal file
132
src/script/input.rs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
use oden_js::{module::native::NativeModuleBuilder, ContextRef};
|
||||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode};
|
||||
|
||||
/// An abstraction over hardware keys.
|
||||
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
|
||||
enum Button {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
impl From<Button> for u32 {
|
||||
fn from(v: Button) -> Self {
|
||||
match v {
|
||||
Button::Up => 0,
|
||||
Button::Down => 1,
|
||||
Button::Left => 2,
|
||||
Button::Right => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for Button {
|
||||
type Error = &'static str;
|
||||
fn try_from(v: u32) -> Result<Self, Self::Error> {
|
||||
match v {
|
||||
0 => Ok(Button::Up),
|
||||
1 => Ok(Button::Down),
|
||||
2 => Ok(Button::Left),
|
||||
3 => Ok(Button::Right),
|
||||
_ => Err("unknown button value"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InputState {
|
||||
up_pressed: bool,
|
||||
down_pressed: bool,
|
||||
left_pressed: bool,
|
||||
right_pressed: bool,
|
||||
}
|
||||
|
||||
impl InputState {
|
||||
fn new() -> Self {
|
||||
InputState {
|
||||
up_pressed: false,
|
||||
down_pressed: false,
|
||||
left_pressed: false,
|
||||
right_pressed: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_keyboard_input(&mut self, input: &KeyboardInput) -> bool {
|
||||
let pressed = input.state == ElementState::Pressed;
|
||||
match input.virtual_keycode {
|
||||
Some(VirtualKeyCode::Left) => {
|
||||
self.left_pressed = pressed;
|
||||
true
|
||||
}
|
||||
Some(VirtualKeyCode::Right) => {
|
||||
self.right_pressed = pressed;
|
||||
true
|
||||
}
|
||||
Some(VirtualKeyCode::Up) => {
|
||||
self.up_pressed = pressed;
|
||||
true
|
||||
}
|
||||
Some(VirtualKeyCode::Down) => {
|
||||
self.down_pressed = pressed;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InputImpl {
|
||||
state: RefCell<InputState>,
|
||||
}
|
||||
|
||||
impl InputImpl {
|
||||
fn new() -> Self {
|
||||
InputImpl {
|
||||
state: RefCell::new(InputState::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_keyboard_input(&self, input: &KeyboardInput) -> bool {
|
||||
self.state.borrow_mut().handle_keyboard_input(input)
|
||||
}
|
||||
|
||||
fn btn(&self, button: u32) -> bool {
|
||||
if let Ok(b) = Button::try_from(button) {
|
||||
let state = self.state.borrow();
|
||||
match b {
|
||||
Button::Up => state.up_pressed,
|
||||
Button::Down => state.down_pressed,
|
||||
Button::Left => state.left_pressed,
|
||||
Button::Right => state.right_pressed,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InputAPI {
|
||||
input: Arc<InputImpl>,
|
||||
}
|
||||
|
||||
impl InputAPI {
|
||||
pub fn define(ctx: &ContextRef) -> oden_js::Result<Self> {
|
||||
let input = Arc::new(InputImpl::new());
|
||||
let mut builder = NativeModuleBuilder::new(ctx);
|
||||
{
|
||||
let input = input.clone();
|
||||
builder.export(
|
||||
"btn",
|
||||
ctx.new_fn(move |_ctx: &ContextRef, b: u32| input.btn(b))?,
|
||||
)?;
|
||||
}
|
||||
builder.build("input-core")?;
|
||||
Ok(InputAPI { input })
|
||||
}
|
||||
|
||||
pub fn handle_keyboard_input(&mut self, input: &KeyboardInput) -> bool {
|
||||
self.input.handle_keyboard_input(input)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue