engine: add input module

master
q3k 2021-04-04 15:46:29 +00:00
parent 2be6a7be48
commit 6d4088a173
4 changed files with 158 additions and 10 deletions

View File

@ -13,6 +13,8 @@ rust_binary(
srcs = [ srcs = [
"src/main.rs", "src/main.rs",
"src/input.rs",
"src/physics/mod.rs", "src/physics/mod.rs",
"src/physics/color.rs", "src/physics/color.rs",

68
engine/src/input.rs Normal file
View File

@ -0,0 +1,68 @@
use std::collections::{BTreeMap,BTreeSet};
#[derive(Clone, Debug)]
pub struct Input {
pub devices: BTreeMap<u64, Device>,
highest_no: u64,
}
impl ecs::Global for Input {}
impl Input {
pub fn allocate_device(&mut self) -> u64 {
self.highest_no += 1;
self.highest_no
}
pub fn new() -> Self {
Self {
devices: BTreeMap::new(),
highest_no: 0,
}
}
pub fn mouse_cursor(&self) -> Option<&MouseCursor> {
for dev in self.devices.values() {
if let &Device::MouseCursor(cursor) = &dev {
return Some(&cursor);
}
}
None
}
}
#[derive(Clone, Debug)]
pub enum Device {
MouseCursor(MouseCursor),
}
#[derive(Clone, Debug)]
pub struct MouseCursor {
// x and y coordinates [0.0, 1.0), top left at (0, 0).
pub x: f32,
pub y: f32,
pressed: BTreeSet<MouseButton>,
}
impl MouseCursor {
pub fn new() -> Self {
Self {
x: 0., y: 0.,
pressed: BTreeSet::new(),
}
}
pub fn set_mouse_pressed(&mut self, button: MouseButton) {
self.pressed.insert(button);
}
pub fn set_mouse_released(&mut self, button: MouseButton) {
self.pressed.remove(&button);
}
}
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum MouseButton {
Left,
Middle,
Right,
Other,
}

View File

@ -21,6 +21,7 @@ use std::time;
use cgmath as cgm; use cgmath as cgm;
pub mod input;
mod render; mod render;
mod util; mod util;
mod physics; mod physics;
@ -158,13 +159,17 @@ impl Main {
struct MainData<'a> { struct MainData<'a> {
scene_info: ecs::ReadWriteGlobal<'a, render::SceneInfo>, scene_info: ecs::ReadWriteGlobal<'a, render::SceneInfo>,
time: ecs::ReadGlobal<'a, Time>, time: ecs::ReadGlobal<'a, Time>,
input: ecs::ReadGlobal<'a, input::Input>,
transforms: ecs::ReadWriteComponent<'a, Transform>, transforms: ecs::ReadWriteComponent<'a, Transform>,
} }
impl<'a> ecs::System <'a> for Main { impl<'a> ecs::System <'a> for Main {
type SystemData = MainData<'a>; type SystemData = MainData<'a>;
fn run(&mut self, sd: Self::SystemData) { fn run(&mut self, sd: Self::SystemData) {
let position = (sd.time.get().instant() / 10.0) * 3.14 * 2.0; let position: f32 = match sd.input.get().mouse_cursor() {
Some(cursor) => cursor.x,
_ => (sd.time.get().instant() / 10.0) * 3.14 * 2.0,
};
let camera = cgm::Point3::new( let camera = cgm::Point3::new(
7.0 + (position / 4.0).sin(), 7.0 + (position / 4.0).sin(),
@ -209,10 +214,11 @@ fn main() {
p.add_system(renderer); p.add_system(renderer);
let start = time::Instant::now(); let start = time::Instant::now();
world.set_global(Time{ world.set_global(Time {
start, start,
now: start, now: start,
}); });
world.set_global(input::Input::new());
loop { loop {
world.global_mut::<Time>().get().now = time::Instant::now(); world.global_mut::<Time>().get().now = time::Instant::now();

View File

@ -48,6 +48,8 @@ pub use mesh::Mesh;
pub use renderable::{Transform, Renderable}; pub use renderable::{Transform, Renderable};
pub use resource::{Resource, ResourceID}; pub use resource::{Resource, ResourceID};
use crate::input;
const WIDTH: u32 = 800; const WIDTH: u32 = 800;
const HEIGHT: u32 = 600; const HEIGHT: u32 = 600;
@ -57,9 +59,11 @@ pub struct Renderer {
rm: resource::Manager, rm: resource::Manager,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Status { pub struct Status {
pub closed: bool, pub closed: bool,
pub input_device_id: u64,
} }
impl ecs::Global for Status {} impl ecs::Global for Status {}
@ -76,15 +80,19 @@ impl<'a> ecs::System<'a> for Renderer {
ecs::ReadComponent<'a, Renderable>, ecs::ReadComponent<'a, Renderable>,
ecs::ReadWriteGlobal<'a, Status>, ecs::ReadWriteGlobal<'a, Status>,
ecs::ReadGlobal<'a, SceneInfo>, ecs::ReadGlobal<'a, SceneInfo>,
ecs::ReadWriteGlobal<'a, input::Input>,
); );
fn run(&mut self, fn run(&mut self,
( transforms ( transforms
, renderables , renderables
, status , status
, scene): Self::SystemData, , scene
, input): Self::SystemData,
) { ) {
let transformedRenderables = (transforms, renderables); let transformedRenderables = (transforms, renderables);
let mut input = input.get();
let mut status = status.get();
let mut rd = vulkan::RenderData { let mut rd = vulkan::RenderData {
meshes: BTreeMap::new(), meshes: BTreeMap::new(),
@ -106,12 +114,38 @@ impl<'a> ecs::System<'a> for Renderer {
let view = &scene.get().view; let view = &scene.get().view;
self.instance.flip(camera, view, &rd, &self.rm); self.instance.flip(camera, view, &rd, &self.rm);
if self.poll_close() { if status.input_device_id == 0 {
status.get().closed = true; status.input_device_id = input.allocate_device();
}
let (close, events) = self.poll_close();
if close {
status.closed = true;
} else {
let mut device = input.devices.entry(status.input_device_id).or_insert(input::Device::MouseCursor(input::MouseCursor::new()));
if let &mut input::Device::MouseCursor(cursor) = &mut device {
for event in events {
match event {
InternalEvent::MousePressed(button) => cursor.set_mouse_pressed(button),
InternalEvent::MouseReleased(button) => cursor.set_mouse_released(button),
InternalEvent::MouseMoved(x, y) => {
cursor.x = x as f32;
cursor.y = y as f32;
},
}
}
}
} }
} }
} }
#[derive(Clone,Debug)]
enum InternalEvent {
MousePressed(input::MouseButton),
MouseReleased(input::MouseButton),
MouseMoved(f64, f64),
}
impl Renderer { impl Renderer {
pub fn initialize(world: &mut ecs::World) -> Self { pub fn initialize(world: &mut ecs::World) -> Self {
world.set_global(SceneInfo { world.set_global(SceneInfo {
@ -120,6 +154,7 @@ impl Renderer {
}); });
world.set_global(Status { world.set_global(Status {
closed: false, closed: false,
input_device_id: 0,
}); });
let mut instance = vulkan::Instance::new("abrasion".to_string()); let mut instance = vulkan::Instance::new("abrasion".to_string());
@ -143,16 +178,53 @@ impl Renderer {
(events_loop, surface) (events_loop, surface)
} }
fn poll_close(&mut self) -> bool { fn poll_close(&mut self) -> (bool, Vec<InternalEvent>) {
let mut close = false; let mut close = false;
let mut events = vec![];
// TODO(q3k): migrate to EventLoop::run // TODO(q3k): migrate to EventLoop::run
self.events_loop.run_return(|ev, _, control_flow| { self.events_loop.run_return(|ev, _, control_flow| {
if let Event::WindowEvent { event: WindowEvent::CloseRequested, .. } = ev { match ev {
close = true; Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
close = true;
},
Event::MainEventsCleared => {
*control_flow = winit::event_loop::ControlFlow::Exit;
},
Event::WindowEvent {
event: WindowEvent::CursorMoved { position, .. },
..
} => {
events.push(InternalEvent::MouseMoved(position.x, position.y));
},
Event::WindowEvent {
event: WindowEvent::MouseInput { state, button, .. },
..
} => {
let button = match button {
winit::event::MouseButton::Left => input::MouseButton::Left,
winit::event::MouseButton::Middle => input::MouseButton::Middle,
winit::event::MouseButton::Right => input::MouseButton::Right,
_ => input::MouseButton::Other,
};
match state {
winit::event::ElementState::Pressed => {
events.push(InternalEvent::MousePressed(button));
},
winit::event::ElementState::Released => {
events.push(InternalEvent::MouseReleased(button));
},
}
},
_ => {
*control_flow = winit::event_loop::ControlFlow::Poll;
},
} }
*control_flow = winit::event_loop::ControlFlow::Exit;
}); });
return close; return (close, events);
} }
pub fn add_resource<T: Resource>(&mut self, r: T) -> ResourceID<T> { pub fn add_resource<T: Resource>(&mut self, r: T) -> ResourceID<T> {