aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortcmal <me@aria.rip>2024-08-25 17:44:22 +0100
committertcmal <me@aria.rip>2024-08-25 17:44:22 +0100
commit8c1406f7a42822d1b020cc672ed99d02eb34d22f (patch)
treee9b3c21520786d2cb9819e46c504e759e4d2d695
parentb380ad94647c9bc446d5a76bb16dcc286077275a (diff)
feat(render-bsp): process into inputmanager
-rw-r--r--examples/render-bsp/Cargo.toml2
-rw-r--r--examples/render-bsp/src/main.rs27
-rw-r--r--stockton-input-codegen/src/lib.rs8
-rw-r--r--stockton-input/src/manager.rs8
-rw-r--r--stockton-render/Cargo.toml1
-rw-r--r--stockton-render/src/window.rs37
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))
}