diff options
author | tcmal <me@aria.rip> | 2024-08-25 17:44:22 +0100 |
---|---|---|
committer | tcmal <me@aria.rip> | 2024-08-25 17:44:22 +0100 |
commit | 8c1406f7a42822d1b020cc672ed99d02eb34d22f (patch) | |
tree | e9b3c21520786d2cb9819e46c504e759e4d2d695 | |
parent | b380ad94647c9bc446d5a76bb16dcc286077275a (diff) |
feat(render-bsp): process into inputmanager
-rw-r--r-- | examples/render-bsp/Cargo.toml | 2 | ||||
-rw-r--r-- | examples/render-bsp/src/main.rs | 27 | ||||
-rw-r--r-- | stockton-input-codegen/src/lib.rs | 8 | ||||
-rw-r--r-- | stockton-input/src/manager.rs | 8 | ||||
-rw-r--r-- | stockton-render/Cargo.toml | 1 | ||||
-rw-r--r-- | stockton-render/src/window.rs | 37 |
6 files changed, 72 insertions, 11 deletions
diff --git a/examples/render-bsp/Cargo.toml b/examples/render-bsp/Cargo.toml index 82e9cb5..dccc9c2 100644 --- a/examples/render-bsp/Cargo.toml +++ b/examples/render-bsp/Cargo.toml @@ -6,6 +6,8 @@ edition = "2018" [dependencies] stockton-render = { path = "../../stockton-render", features = ["vulkan"] } +stockton-input = { path = "../../stockton-input" } +stockton-input-codegen = { path = "../../stockton-input-codegen" } stockton-types = { path = "../../stockton-types" } stockton-levels = { path = "../../stockton-levels" } winit = "^0.21" diff --git a/examples/render-bsp/src/main.rs b/examples/render-bsp/src/main.rs index b18d7f2..96d5e42 100644 --- a/examples/render-bsp/src/main.rs +++ b/examples/render-bsp/src/main.rs @@ -17,6 +17,10 @@ //! Renders ./example.bsp +use stockton_input::{Axis, InputManager}; +#[macro_use] +extern crate stockton_input_codegen; +use std::collections::BTreeMap; use winit::{event::Event, event_loop::EventLoop, window::WindowBuilder}; use stockton_levels::{prelude::*, q3::Q3BSPFile}; @@ -25,6 +29,18 @@ use stockton_render::{ }; use stockton_types::Session; +#[derive(InputManager, Default, Clone, Debug)] +struct MovementInputs { + #[axis] + x: Axis, + + #[axis] + y: Axis, + + #[axis] + z: Axis, +} + fn main() { // Initialise logger simple_logger::SimpleLogger::new() @@ -54,15 +70,24 @@ fn main() { let (renderer, tx) = Renderer::new(&window, &bsp); let new_control_flow = renderer.update_control_flow.clone(); + // Create the input manager + let manager = { + let actions = BTreeMap::new(); + // TODO: An actual control schema + + MovementInputsManager::new(actions) + }; + // Load everything into the session let mut session = Session::new( move |resources| { resources.insert(renderer); resources.insert(bsp); + resources.insert(manager); }, move |schedule| { schedule - .add_system(process_window_events_system()) + .add_system(process_window_events_system::<MovementInputsManager>()) .add_thread_local(do_render_system::<Q3BSPFile<VulkanSystem>>()); }, ); diff --git a/stockton-input-codegen/src/lib.rs b/stockton-input-codegen/src/lib.rs index db4e5da..a6e8215 100644 --- a/stockton-input-codegen/src/lib.rs +++ b/stockton-input-codegen/src/lib.rs @@ -26,7 +26,7 @@ use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident}; /// Each button in the struct should be decorated with #[button] and each axis with #[axis]. /// Given struct MovementInputs, this will output struct MovementInputsManager which implements InputManager. /// It also creates an enum MovementInputsFields, with values for all the buttons and axes in MovementInputs. -/// You'll need to pass in an action schema to `MovementInputsManager::new()`, which is a BTreeMap<u8, (MovementInputsFields, InputMutation)> +/// You'll need to pass in an action schema to `MovementInputsManager::new()`, which is a BTreeMap<u32, (MovementInputsFields, InputMutation)> /// You can then call `.handle_frame` on MovementInputsManager and then read the inputs from MovementInputsManager.inputs. #[proc_macro_derive(InputManager, attributes(button, axis))] pub fn derive_inputmanager(input: TokenStream) -> TokenStream { @@ -174,12 +174,12 @@ fn gen_manager_struct( quote!( struct #ident { inputs: #struct_ident, - actions: ::std::collections::BTreeMap<u8, (#fields_enum_ident, ::stockton_input::InputMutation)>, + actions: ::std::collections::BTreeMap<u32, (#fields_enum_ident, ::stockton_input::InputMutation)>, just_hot: [bool; #buttons_len] } impl #ident { - pub fn new(actions: ::std::collections::BTreeMap<u8, (#fields_enum_ident, ::stockton_input::InputMutation)>) -> Self { + pub fn new(actions: ::std::collections::BTreeMap<u32, (#fields_enum_ident, ::stockton_input::InputMutation)>) -> Self { #ident { inputs: Default::default(), actions, @@ -253,6 +253,8 @@ fn gen_trait_impl( let mutation = self.actions.get(&action.keycode()); if let Some((field, mutation)) = mutation { + use ::stockton_input::InputMutation; + let mut val = match mutation { InputMutation::MapToButton | InputMutation::PositiveAxis => 1, InputMutation::NegativeAxis => -1 diff --git a/stockton-input/src/manager.rs b/stockton-input/src/manager.rs index 2b62a93..4d2d001 100644 --- a/stockton-input/src/manager.rs +++ b/stockton-input/src/manager.rs @@ -24,14 +24,14 @@ pub enum InputMutation { } /// A key being pressed or released -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum Action { - KeyPress(u8), - KeyRelease(u8), + KeyPress(u32), + KeyRelease(u32), } impl Action { - pub fn keycode(&self) -> u8 { + pub fn keycode(&self) -> u32 { match self { Action::KeyPress(x) => *x, Action::KeyRelease(x) => *x, diff --git a/stockton-render/Cargo.toml b/stockton-render/Cargo.toml index eef6bc0..e4f2153 100644 --- a/stockton-render/Cargo.toml +++ b/stockton-render/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Oscar <oscar.shrimpton.personal@gmail.com>"] edition = "2018" [dependencies] +stockton-input = { path = "../stockton-input" } stockton-levels = { path = "../stockton-levels" } stockton-types = { path = "../stockton-types" } winit = "^0.21" diff --git a/stockton-render/src/window.rs b/stockton-render/src/window.rs index 6c4cecd..fa22e1d 100644 --- a/stockton-render/src/window.rs +++ b/stockton-render/src/window.rs @@ -16,15 +16,18 @@ */ use crate::Renderer; +use legion::systems::Runnable; -use winit::event::Event as WinitEvent; -use winit::event::WindowEvent as WinitWindowEvent; +use stockton_input::{Action as KBAction, InputManager}; + +use winit::event::{ElementState, Event as WinitEvent, WindowEvent as WinitWindowEvent}; use winit::event_loop::ControlFlow; #[derive(Debug, Clone, Copy)] pub enum WindowEvent { SizeChanged, CloseRequested, + KeyboardAction(KBAction), } impl WindowEvent { @@ -34,6 +37,14 @@ impl WindowEvent { WinitEvent::WindowEvent { event, .. } => match event { WinitWindowEvent::CloseRequested => Some(WindowEvent::CloseRequested), WinitWindowEvent::Resized(_) => Some(WindowEvent::SizeChanged), + WinitWindowEvent::KeyboardInput { input, .. } => match input.state { + ElementState::Pressed => Some(WindowEvent::KeyboardAction(KBAction::KeyPress( + input.scancode, + ))), + ElementState::Released => Some(WindowEvent::KeyboardAction( + KBAction::KeyRelease(input.scancode), + )), + }, _ => None, }, _ => None, @@ -43,7 +54,13 @@ impl WindowEvent { #[system] /// A system to process the window events sent to renderer by the winit event loop. -pub fn process_window_events(#[resource] renderer: &mut Renderer<'static>) { +pub fn _process_window_events<T: 'static + InputManager>( + #[resource] renderer: &mut Renderer<'static>, + #[resource] manager: &mut T, + #[state] actions_buf: &mut Vec<KBAction>, +) { + let mut actions_buf_cursor = 0; + while let Ok(event) = renderer.window_events.try_recv() { match event { WindowEvent::SizeChanged => renderer.resize(), @@ -52,6 +69,20 @@ pub fn process_window_events(#[resource] renderer: &mut Renderer<'static>) { // TODO: Let everything know this is our last frame *flow = ControlFlow::Exit; } + WindowEvent::KeyboardAction(action) => { + if actions_buf_cursor >= actions_buf.len() { + actions_buf.push(action); + } else { + actions_buf[actions_buf_cursor] = action; + } + actions_buf_cursor += 1; + } }; } + + manager.handle_frame(&actions_buf[0..actions_buf_cursor]); +} + +pub fn process_window_events_system<T: 'static + InputManager>() -> impl Runnable { + _process_window_events_system::<T>(Vec::with_capacity(4)) } |