events and input

This commit is contained in:
griffi-gh 2023-01-25 03:01:44 +01:00
parent 8615853deb
commit 83f06950e2
5 changed files with 151 additions and 18 deletions

55
src/events.rs Normal file
View file

@ -0,0 +1,55 @@
use glam::UVec2;
use shipyard::{World, Component, AllStoragesViewMut, SparseSet};
use glium::glutin::event::{Event, DeviceEvent, DeviceId, WindowEvent};
#[derive(Component, Clone, Copy, Debug, Default)]
pub struct EventComponent;
#[derive(Component, Clone, Copy, Debug, Default)]
pub struct OnBeforeExitEvent;
#[derive(Component, Clone, Debug)]
pub struct InputDeviceEvent{
pub device_id: DeviceId,
pub event: DeviceEvent
}
#[derive(Component, Clone, Copy, Debug, Default)]
pub struct WindowResizedEvent(UVec2);
pub fn process_glutin_events(world: &mut World, event: &Event<'_, ()>) {
#[allow(clippy::collapsible_match, clippy::single_match)]
match event {
Event::WindowEvent { window_id: _, event } => match event {
WindowEvent::Resized(size) => {
world.add_entity((
EventComponent,
WindowResizedEvent(UVec2::new(size.width as _, size.height as _))
));
},
_ => ()
},
Event::DeviceEvent { device_id, event } => {
world.add_entity((
EventComponent,
InputDeviceEvent {
device_id: *device_id,
event: event.clone()
}
));
},
Event::LoopDestroyed => {
world.add_entity((
EventComponent,
OnBeforeExitEvent
));
},
_ => (),
}
}
pub fn clear_events(
mut all_storages: AllStoragesViewMut,
) {
all_storages.delete_any::<SparseSet<EventComponent>>();
}

View file

@ -1,6 +1,73 @@
use glium::glutin::event::VirtualKeyCode; use glam::{Vec2, DVec2};
use shipyard::{AllStoragesView, Unique}; use glium::glutin::event::{DeviceEvent, VirtualKeyCode, ElementState};
use hashbrown::HashMap; use hashbrown::HashSet;
use nohash_hasher::BuildNoHashHasher; use nohash_hasher::BuildNoHashHasher;
use shipyard::{AllStoragesView, Unique, View, IntoIter, UniqueViewMut, Workload, IntoWorkload, UniqueView};
use crate::events::InputDeviceEvent;
//todo #[derive(Unique, Clone, Copy, Default, Debug)]
pub struct Inputs {
pub movement: Vec2,
pub look: Vec2,
pub action_a: bool,
pub action_b: bool,
}
#[derive(Unique, Clone, Default, Debug)]
pub struct RawInputState {
pub keyboard_state: HashSet<VirtualKeyCode, BuildNoHashHasher<u32>>,
pub mouse_delta: DVec2
}
pub fn process_events(
device_events: View<InputDeviceEvent>,
mut input_state: UniqueViewMut<RawInputState>,
) {
input_state.mouse_delta = DVec2::ZERO;
for event in device_events.iter() {
match event.event {
DeviceEvent::MouseMotion { delta } => {
input_state.mouse_delta = DVec2::from(delta);
},
DeviceEvent::Key(input) => {
if let Some(keycode) = input.virtual_keycode {
match input.state {
ElementState::Pressed => input_state.keyboard_state.insert(keycode),
ElementState::Released => input_state.keyboard_state.remove(&keycode),
};
}
},
DeviceEvent::Button { button, state } => {
println!("Button {button} {state:?}");
},
_ => ()
}
}
}
pub fn update_input_states (
raw_inputs: UniqueView<RawInputState>,
mut inputs: UniqueViewMut<Inputs>,
) {
inputs.movement = Vec2::new(
raw_inputs.keyboard_state.contains(&VirtualKeyCode::D) as u32 as f32 -
raw_inputs.keyboard_state.contains(&VirtualKeyCode::A) as u32 as f32,
raw_inputs.keyboard_state.contains(&VirtualKeyCode::W) as u32 as f32 -
raw_inputs.keyboard_state.contains(&VirtualKeyCode::S) as u32 as f32
).normalize_or_zero();
inputs.look = raw_inputs.mouse_delta.as_vec2();
}
pub fn init_input (
storages: AllStoragesView
) {
storages.add_unique(Inputs::default());
storages.add_unique(RawInputState::default());
}
pub fn process_inputs() -> Workload {
(
process_events,
update_input_states
).into_workload()
}

View file

@ -20,28 +20,36 @@ pub(crate) mod prefabs;
pub(crate) mod transform; pub(crate) mod transform;
pub(crate) mod settings; pub(crate) mod settings;
pub(crate) mod camera; pub(crate) mod camera;
pub(crate) mod events;
pub(crate) mod input; pub(crate) mod input;
pub(crate) mod fly_controller; pub(crate) mod fly_controller;
use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background}; use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background};
use world::{loading::update_loaded_world_around_player, render::draw_world, init_world}; use world::{loading::update_loaded_world_around_player, render::draw_world, init_game_world};
use player::spawn_player; use player::spawn_player;
use prefabs::load_prefabs; use prefabs::load_prefabs;
use settings::GameSettings; use settings::GameSettings;
use camera::compute_cameras; use camera::compute_cameras;
use events::{clear_events, process_glutin_events};
use input::{init_input, process_inputs};
#[derive(Unique)] #[derive(Unique)]
pub(crate) struct DeltaTime(Duration); pub(crate) struct DeltaTime(Duration);
fn startup() -> Workload { fn startup() -> Workload {
( (
load_prefabs,
init_input,
init_game_world,
spawn_player, spawn_player,
).into_workload() ).into_workload()
} }
fn update() -> Workload { fn update() -> Workload {
( (
process_inputs,
update_loaded_world_around_player, update_loaded_world_around_player,
compute_cameras, compute_cameras,
clear_events
).into_workload() ).into_workload()
} }
fn render() -> Workload { fn render() -> Workload {
@ -58,15 +66,13 @@ fn main() {
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
//Create a shipyard world //Create a shipyard world
let world = World::new(); let mut world = World::new();
//Add systems and uniques, Init and load things //Add systems and uniques, Init and load things
world.add_unique_non_send_sync(Renderer::init(&event_loop)); world.add_unique_non_send_sync(Renderer::init(&event_loop));
world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.))); world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.)));
world.add_unique(DeltaTime(Duration::default())); world.add_unique(DeltaTime(Duration::default()));
world.add_unique(GameSettings::default()); world.add_unique(GameSettings::default());
load_prefabs(&world);
init_world(&world);
//Register workloads //Register workloads
world.add_workload(startup); world.add_workload(startup);
@ -80,6 +86,7 @@ fn main() {
let mut last_update = Instant::now(); let mut last_update = Instant::now();
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll; *control_flow = ControlFlow::Poll;
process_glutin_events(&mut world, &event);
match event { match event {
Event::WindowEvent { event, .. } => match event { Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(_size) => { WindowEvent::Resized(_size) => {

View file

@ -1,4 +1,4 @@
use shipyard::{World, NonSendSync, UniqueView, Unique}; use shipyard::{NonSendSync, UniqueView, Unique, AllStoragesView};
use glium::{texture::{SrgbTexture2dArray, MipmapsOption}, Program}; use glium::{texture::{SrgbTexture2dArray, MipmapsOption}, Program};
use strum::EnumIter; use strum::EnumIter;
use crate::rendering::Renderer; use crate::rendering::Renderer;
@ -56,16 +56,18 @@ pub struct BlockTexturesPrefab(pub SrgbTexture2dArray);
#[derive(Unique)] #[derive(Unique)]
pub struct ChunkShaderPrefab(pub Program); pub struct ChunkShaderPrefab(pub Program);
pub fn load_prefabs(world: &World) { pub fn load_prefabs(
let renderer = world.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap(); storages: AllStoragesView,
world.add_unique_non_send_sync(BlockTexturesPrefab( renderer: NonSendSync<UniqueView<Renderer>>
) {
storages.add_unique_non_send_sync(BlockTexturesPrefab(
load_texture2darray_prefab::<BlockTextures, _>( load_texture2darray_prefab::<BlockTextures, _>(
"./assets/blocks/".into(), "./assets/blocks/".into(),
&renderer.display, &renderer.display,
MipmapsOption::AutoGeneratedMipmaps MipmapsOption::AutoGeneratedMipmaps
) )
)); ));
world.add_unique_non_send_sync(ChunkShaderPrefab( storages.add_unique_non_send_sync(ChunkShaderPrefab(
include_shader_prefab!( include_shader_prefab!(
"../shaders/world.vert", "../shaders/world.vert",
"../shaders/world.frag", "../shaders/world.frag",

View file

@ -1,5 +1,5 @@
use nohash_hasher::BuildNoHashHasher; use nohash_hasher::BuildNoHashHasher;
use shipyard::{Unique, World}; use shipyard::{Unique, AllStoragesView};
use glam::IVec3; use glam::IVec3;
use hashbrown::HashMap; use hashbrown::HashMap;
use anyhow::{Result, Context}; use anyhow::{Result, Context};
@ -66,8 +66,10 @@ impl ChunkMeshStorage {
} }
} }
pub fn init_world(world: &World) { pub fn init_game_world(
world.add_unique_non_send_sync(ChunkMeshStorage::new()); storages: AllStoragesView,
world.add_unique(ChunkStorage::new()); ) {
world.add_unique(ChunkTaskManager::new()); storages.add_unique_non_send_sync(ChunkMeshStorage::new());
storages.add_unique(ChunkStorage::new());
storages.add_unique(ChunkTaskManager::new());
} }