Encapsulated winit into solar_engine. No winit is required anymore within the API
This commit is contained in:
parent
9a81d6d474
commit
03c061839c
@ -5,7 +5,6 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solar_engine = { path = "../solar_engine" }
|
||||
winit = "0.30.10"
|
||||
log = "0.4"
|
||||
env_logger = "0.11.8"
|
||||
pollster = "0.4.0"
|
||||
|
||||
@ -1,16 +1,9 @@
|
||||
use cgmath::Rotation3;
|
||||
use solar_engine::{Application, Body, Simulator};
|
||||
use solar_engine::{Application, Body, Key, KeyState, Simulator};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::thread;
|
||||
use winit::event::ElementState;
|
||||
use winit::event::WindowEvent::KeyboardInput;
|
||||
use winit::event_loop::EventLoop;
|
||||
use winit::keyboard::Key;
|
||||
use winit::platform::modifier_supplement::KeyEventExtModifierSupplement;
|
||||
|
||||
pub async fn run() {
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let simulator = Arc::new(RwLock::new(Simulator::new()));
|
||||
{
|
||||
let mut sim = simulator.write().unwrap();
|
||||
@ -49,59 +42,58 @@ pub async fn run() {
|
||||
|
||||
let simulator_clone = simulator.clone();
|
||||
|
||||
let mut window_state = Application::new().on_update(move |state| {
|
||||
let sim = simulator_clone.read().unwrap();
|
||||
let bodies = &sim.bodies;
|
||||
Application::new()
|
||||
.on_update(move |state| {
|
||||
let sim = simulator_clone.read().unwrap();
|
||||
let bodies = &sim.bodies;
|
||||
|
||||
let instances = bodies
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, b)| {
|
||||
solar_engine::RenderInstance {
|
||||
position: cgmath::Vector3::new(
|
||||
(b.position[0] / 1.496e11) as f32,
|
||||
(b.position[1] / 1.496e11) as f32,
|
||||
0.0,
|
||||
),
|
||||
rotation: cgmath::Quaternion::from_angle_z(cgmath::Deg(0.0)),
|
||||
color: match i {
|
||||
0 => [1.0, 1.0, 0.0], // Sun
|
||||
1 => [0.0, 0.0, 1.0], // Earth
|
||||
_ => [0.5, 0.5, 0.5],
|
||||
},
|
||||
scale: 0.05,
|
||||
shape: solar_engine::Shape::Circle,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let instances = bodies
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, b)| {
|
||||
solar_engine::RenderInstance {
|
||||
position: cgmath::Vector3::new(
|
||||
(b.position[0] / 1.496e11) as f32,
|
||||
(b.position[1] / 1.496e11) as f32,
|
||||
0.0,
|
||||
),
|
||||
rotation: cgmath::Quaternion::from_angle_z(cgmath::Deg(0.0)),
|
||||
color: match i {
|
||||
0 => [1.0, 1.0, 0.0], // Sun
|
||||
1 => [0.0, 0.0, 1.0], // Earth
|
||||
_ => [0.5, 0.5, 0.5],
|
||||
},
|
||||
scale: 0.05,
|
||||
shape: solar_engine::Shape::Circle,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
state.set_instances(instances);
|
||||
}).on_input(move |_state, event| {
|
||||
if let KeyboardInput { event, .. } = event {
|
||||
if event.state == ElementState::Pressed {
|
||||
return match event.key_without_modifiers().as_ref() {
|
||||
Key::Character(".") => {
|
||||
state.set_instances(instances);
|
||||
})
|
||||
.on_input(move |_state, event| {
|
||||
if event.state == KeyState::Pressed {
|
||||
return match event.key {
|
||||
Key::Period => {
|
||||
let mut sim = simulator.write().unwrap();
|
||||
sim.increase_timewarp();
|
||||
println!("Timewarp: {}", sim.get_timewarp());
|
||||
}
|
||||
Key::Character(",") => {
|
||||
Key::Comma => {
|
||||
let mut sim = simulator.write().unwrap();
|
||||
sim.decrease_timewarp();
|
||||
println!("Timewarp: {}", sim.get_timewarp());
|
||||
}
|
||||
Key::Character("-") => {
|
||||
Key::Minus => {
|
||||
let mut sim = simulator.write().unwrap();
|
||||
sim.reset_timewarp();
|
||||
println!("Timewarp: {}", sim.get_timewarp());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let _ = event_loop.run_app(&mut window_state);
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
use winit::application::ApplicationHandler;
|
||||
use winit::event::WindowEvent;
|
||||
use winit::event::{Modifiers, WindowEvent};
|
||||
use winit::event_loop::ActiveEventLoop;
|
||||
use winit::window::{Window, WindowId};
|
||||
use crate::input::{from_winit_input, InputEvent};
|
||||
|
||||
pub struct StateApplication<'a> {
|
||||
state: Option<crate::state::State<'a>>,
|
||||
modifiers: Modifiers,
|
||||
update_fn: Option<Box<dyn FnMut(&mut crate::state::State<'a>) + 'a>>,
|
||||
input_fn: Option<Box<dyn FnMut(&mut crate::state::State<'a>, &WindowEvent) + 'a>>,
|
||||
input_fn: Option<Box<dyn FnMut(&mut crate::state::State<'a>, &InputEvent) + 'a>>,
|
||||
}
|
||||
|
||||
impl<'a> StateApplication<'a> {
|
||||
pub fn new() -> Self {
|
||||
Self { state: None, update_fn: None, input_fn: None }
|
||||
Self { state: None, update_fn: None, input_fn: None, modifiers: Modifiers::default() }
|
||||
}
|
||||
|
||||
pub fn on_update<F: FnMut(&mut crate::state::State<'a>) + 'a>(mut self, func: F) -> Self {
|
||||
@ -19,10 +21,15 @@ impl<'a> StateApplication<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_input<F: FnMut(&mut crate::state::State<'a>, &WindowEvent) + 'a>(mut self, func: F) -> Self {
|
||||
pub fn on_input<F: FnMut(&mut crate::state::State<'a>, &InputEvent) + 'a>(mut self, func: F) -> Self {
|
||||
self.input_fn = Some(Box::new(func));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn run(mut self) {
|
||||
let event_loop = winit::event_loop::EventLoop::new().unwrap();
|
||||
let _ = event_loop.run_app(&mut self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ApplicationHandler for StateApplication<'a> {
|
||||
@ -56,13 +63,17 @@ impl<'a> ApplicationHandler for StateApplication<'a> {
|
||||
|
||||
self.state.as_mut().unwrap().render().unwrap();
|
||||
}
|
||||
WindowEvent::KeyboardInput { .. } => {
|
||||
WindowEvent::KeyboardInput { event, .. } => {
|
||||
if let Some(state) = self.state.as_mut() {
|
||||
if let Some(input_fn) = self.input_fn.as_mut() {
|
||||
input_fn(state, &event);
|
||||
let key_event = from_winit_input(&event, self.modifiers);
|
||||
input_fn(state, &key_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
WindowEvent::ModifiersChanged(modifiers) => {
|
||||
self.modifiers = modifiers;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
191
solar_engine/src/input.rs
Normal file
191
solar_engine/src/input.rs
Normal file
@ -0,0 +1,191 @@
|
||||
use winit::event::{ElementState, KeyEvent, Modifiers};
|
||||
use winit::keyboard::{Key as WinitKey, ModifiersKeyState};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Key {
|
||||
// Symbols
|
||||
Comma, Period, Minus, Plus, Slash, Backslash, Semicolon, Apostrophe,
|
||||
LeftBracket, RightBracket, Grave, Equal,
|
||||
|
||||
// Digits
|
||||
Num0, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9,
|
||||
|
||||
// Letters
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M,
|
||||
N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
|
||||
|
||||
// Arrows
|
||||
ArrowUp, ArrowDown, ArrowLeft, ArrowRight,
|
||||
|
||||
// Controls
|
||||
Escape, Enter, Space, Tab, Backspace,
|
||||
Insert, Delete, Home, End, PageUp, PageDown,
|
||||
|
||||
// Modifier keys
|
||||
Shift, Control, Alt, Super,
|
||||
|
||||
// Function keys
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
|
||||
// Numpad
|
||||
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4,
|
||||
Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
|
||||
NumpadAdd, NumpadSubtract, NumpadMultiply, NumpadDivide, NumpadEnter,
|
||||
|
||||
// Unknown
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum KeyState {
|
||||
Pressed,
|
||||
Released,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct KeyModifiers {
|
||||
pub lshift: bool,
|
||||
pub rshift: bool,
|
||||
pub lcontrol: bool,
|
||||
pub rcontrol: bool,
|
||||
pub lalt: bool,
|
||||
pub ralt: bool,
|
||||
pub rsuper_key: bool,
|
||||
pub lsuper_key: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InputEvent {
|
||||
pub key: Key,
|
||||
pub state: KeyState,
|
||||
pub text: String,
|
||||
pub modifiers: KeyModifiers,
|
||||
}
|
||||
|
||||
pub fn from_winit_input(event: &KeyEvent, modifiers: Modifiers) -> InputEvent {
|
||||
InputEvent {
|
||||
key: map_winit_key(&event.logical_key),
|
||||
state: match event.state {
|
||||
ElementState::Pressed => KeyState::Pressed,
|
||||
ElementState::Released => KeyState::Released,
|
||||
},
|
||||
text: event.text.clone().unwrap_or_default().into(),
|
||||
modifiers: KeyModifiers {
|
||||
lshift: modifiers.lshift_state() == ModifiersKeyState::Pressed,
|
||||
rshift: modifiers.rshift_state() == ModifiersKeyState::Pressed,
|
||||
lcontrol: modifiers.lcontrol_state() == ModifiersKeyState::Pressed,
|
||||
rcontrol: modifiers.rcontrol_state() == ModifiersKeyState::Pressed,
|
||||
lalt: modifiers.lalt_state() == ModifiersKeyState::Pressed,
|
||||
ralt: modifiers.ralt_state() == ModifiersKeyState::Pressed,
|
||||
rsuper_key: modifiers.rsuper_state() == ModifiersKeyState::Pressed,
|
||||
lsuper_key: modifiers.lsuper_state() == ModifiersKeyState::Pressed,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_winit_key(key: &WinitKey) -> Key {
|
||||
use Key::*;
|
||||
match key {
|
||||
WinitKey::Character(s) => match s.as_str() {
|
||||
"a" | "A" => A,
|
||||
"b" | "B" => B,
|
||||
"c" | "C" => C,
|
||||
"d" | "D" => D,
|
||||
"e" | "E" => E,
|
||||
"f" | "F" => F,
|
||||
"g" | "G" => G,
|
||||
"h" | "H" => H,
|
||||
"i" | "I" => I,
|
||||
"j" | "J" => J,
|
||||
"k" | "K" => K,
|
||||
"l" | "L" => L,
|
||||
"m" | "M" => M,
|
||||
"n" | "N" => N,
|
||||
"o" | "O" => O,
|
||||
"p" | "P" => P,
|
||||
"q" | "Q" => Q,
|
||||
"r" | "R" => R,
|
||||
"s" | "S" => S,
|
||||
"t" | "T" => T,
|
||||
"u" | "U" => U,
|
||||
"v" | "V" => V,
|
||||
"w" | "W" => W,
|
||||
"x" | "X" => X,
|
||||
"y" | "Y" => Y,
|
||||
"z" | "Z" => Z,
|
||||
"0" => Num0,
|
||||
"1" => Num1,
|
||||
"2" => Num2,
|
||||
"3" => Num3,
|
||||
"4" => Num4,
|
||||
"5" => Num5,
|
||||
"6" => Num6,
|
||||
"7" => Num7,
|
||||
"8" => Num8,
|
||||
"9" => Num9,
|
||||
"," => Comma,
|
||||
"." => Period,
|
||||
"-" => Minus,
|
||||
"+" => Plus,
|
||||
"/" => Slash,
|
||||
"\\" => Backslash,
|
||||
";" => Semicolon,
|
||||
"'" => Apostrophe,
|
||||
"[" => LeftBracket,
|
||||
"]" => RightBracket,
|
||||
"`" => Grave,
|
||||
"=" => Equal,
|
||||
_ => Unknown,
|
||||
},
|
||||
WinitKey::Named(n) => match n.to_text().unwrap_or("") {
|
||||
"ArrowUp" => ArrowUp,
|
||||
"ArrowDown" => ArrowDown,
|
||||
"ArrowLeft" => ArrowLeft,
|
||||
"ArrowRight" => ArrowRight,
|
||||
"Escape" => Escape,
|
||||
"Enter" => Enter,
|
||||
"Tab" => Tab,
|
||||
"Space" => Space,
|
||||
"Backspace" => Backspace,
|
||||
"Insert" => Insert,
|
||||
"Delete" => Delete,
|
||||
"Home" => Home,
|
||||
"End" => End,
|
||||
"PageUp" => PageUp,
|
||||
"PageDown" => PageDown,
|
||||
"Shift" => Shift,
|
||||
"Control" => Control,
|
||||
"Alt" => Alt,
|
||||
"Super" => Super,
|
||||
"F1" => F1,
|
||||
"F2" => F2,
|
||||
"F3" => F3,
|
||||
"F4" => F4,
|
||||
"F5" => F5,
|
||||
"F6" => F6,
|
||||
"F7" => F7,
|
||||
"F8" => F8,
|
||||
"F9" => F9,
|
||||
"F10" => F10,
|
||||
"F11" => F11,
|
||||
"F12" => F12,
|
||||
"Numpad0" => Numpad0,
|
||||
"Numpad1" => Numpad1,
|
||||
"Numpad2" => Numpad2,
|
||||
"Numpad3" => Numpad3,
|
||||
"Numpad4" => Numpad4,
|
||||
"Numpad5" => Numpad5,
|
||||
"Numpad6" => Numpad6,
|
||||
"Numpad7" => Numpad7,
|
||||
"Numpad8" => Numpad8,
|
||||
"Numpad9" => Numpad9,
|
||||
"NumpadAdd" => NumpadAdd,
|
||||
"NumpadSubtract" => NumpadSubtract,
|
||||
"NumpadMultiply" => NumpadMultiply,
|
||||
"NumpadDivide" => NumpadDivide,
|
||||
"NumpadEnter" => NumpadEnter,
|
||||
_ => Unknown,
|
||||
},
|
||||
_ => Unknown,
|
||||
}
|
||||
}
|
||||
@ -3,11 +3,21 @@ mod simulator;
|
||||
mod state;
|
||||
mod render;
|
||||
mod application;
|
||||
mod input;
|
||||
|
||||
pub use body::Body;
|
||||
|
||||
pub use simulator::Simulator;
|
||||
pub use simulator::distance_squared;
|
||||
|
||||
pub use application::StateApplication as Application;
|
||||
|
||||
pub use render::RenderInstance;
|
||||
pub use render::Shape;
|
||||
pub use state::State;
|
||||
|
||||
pub use state::State;
|
||||
|
||||
pub use input::Key;
|
||||
pub use input::map_winit_key;
|
||||
pub use input::InputEvent;
|
||||
pub use input::KeyState;
|
||||
Loading…
x
Reference in New Issue
Block a user