forked from StrafesNET/roblox-bot-player
134 lines
4.2 KiB
Rust
134 lines
4.2 KiB
Rust
use strafesnet_common::instruction::TimedInstruction;
|
|
use strafesnet_common::session::Time as SessionTime;
|
|
use crate::file::LoadFormat;
|
|
use crate::player::{PlayerWorker,Instruction as PhysicsWorkerInstruction,SessionControlInstruction};
|
|
|
|
pub enum Instruction{
|
|
WindowEvent(winit::event::WindowEvent),
|
|
DeviceEvent(winit::event::DeviceEvent),
|
|
}
|
|
|
|
//holds thread handles to dispatch to
|
|
pub struct WindowContext<'a>{
|
|
simulation_paused:bool,
|
|
window:&'a winit::window::Window,
|
|
physics_thread:PlayerWorker<'a>,
|
|
}
|
|
|
|
impl WindowContext<'_>{
|
|
fn window_event(&mut self,time:SessionTime,event:winit::event::WindowEvent){
|
|
match event{
|
|
winit::event::WindowEvent::DroppedFile(path)=>{
|
|
match crate::file::load(path.as_path()){
|
|
Ok(LoadFormat::Map(map))=>self.physics_thread.send(TimedInstruction{time,instruction:PhysicsWorkerInstruction::ChangeMap(map)}),
|
|
Ok(LoadFormat::Bot(bot))=>self.physics_thread.send(TimedInstruction{time,instruction:PhysicsWorkerInstruction::LoadReplay(bot)}),
|
|
Err(e)=>println!("Failed to load file: {e}"),
|
|
}
|
|
},
|
|
winit::event::WindowEvent::Focused(state)=>{
|
|
// don't unpause if manually paused
|
|
if self.simulation_paused{
|
|
return;
|
|
}
|
|
//pause unpause
|
|
self.physics_thread.send(TimedInstruction{
|
|
time,
|
|
instruction:PhysicsWorkerInstruction::SessionControl(SessionControlInstruction::SetPaused(!state)),
|
|
});
|
|
//recalculate pressed keys on focus
|
|
},
|
|
winit::event::WindowEvent::KeyboardInput{
|
|
event:winit::event::KeyEvent{state,logical_key,repeat:false,..},
|
|
..
|
|
}=>{
|
|
match (logical_key,state){
|
|
(winit::keyboard::Key::Named(winit::keyboard::NamedKey::F11),winit::event::ElementState::Pressed)=>{
|
|
if self.window.fullscreen().is_some(){
|
|
self.window.set_fullscreen(None);
|
|
}else{
|
|
self.window.set_fullscreen(Some(winit::window::Fullscreen::Borderless(None)));
|
|
}
|
|
},
|
|
(keycode,state)=>{
|
|
let s=state.is_pressed();
|
|
|
|
macro_rules! session_ctrl{
|
|
($variant:ident,$state:expr)=>{
|
|
s.then_some(PhysicsWorkerInstruction::SessionControl(SessionControlInstruction::$variant))
|
|
};
|
|
}
|
|
|
|
if let Some(instruction)=match keycode{
|
|
winit::keyboard::Key::Named(winit::keyboard::NamedKey::Space)=>if s{
|
|
let paused=!self.simulation_paused;
|
|
self.simulation_paused=paused;
|
|
Some(PhysicsWorkerInstruction::SessionControl(SessionControlInstruction::SetPaused(paused)))
|
|
}else{None},
|
|
winit::keyboard::Key::Named(winit::keyboard::NamedKey::ArrowUp)=>session_ctrl!(IncreaseTimescale,s),
|
|
winit::keyboard::Key::Named(winit::keyboard::NamedKey::ArrowDown)=>session_ctrl!(DecreaseTimescale,s),
|
|
winit::keyboard::Key::Named(winit::keyboard::NamedKey::ArrowLeft)=>session_ctrl!(SkipBack,s),
|
|
winit::keyboard::Key::Named(winit::keyboard::NamedKey::ArrowRight)=>session_ctrl!(SkipForward,s),
|
|
_=>None,
|
|
}{
|
|
self.physics_thread.send(TimedInstruction{
|
|
time,
|
|
instruction,
|
|
});
|
|
}
|
|
},
|
|
}
|
|
},
|
|
winit::event::WindowEvent::Resized(size)=>{
|
|
self.physics_thread.send(
|
|
TimedInstruction{
|
|
time,
|
|
instruction:PhysicsWorkerInstruction::Resize(size)
|
|
}
|
|
);
|
|
},
|
|
winit::event::WindowEvent::RedrawRequested=>{
|
|
self.window.request_redraw();
|
|
self.physics_thread.send(
|
|
TimedInstruction{
|
|
time,
|
|
instruction:PhysicsWorkerInstruction::Render
|
|
}
|
|
);
|
|
},
|
|
_=>(),
|
|
}
|
|
}
|
|
|
|
fn device_event(&mut self,_time:SessionTime,_event:winit::event::DeviceEvent){
|
|
}
|
|
|
|
pub fn send(&mut self,ins:TimedInstruction<Instruction,SessionTime>){
|
|
match ins.instruction{
|
|
Instruction::WindowEvent(window_event)=>{
|
|
self.window_event(ins.time,window_event);
|
|
},
|
|
Instruction::DeviceEvent(device_event)=>{
|
|
self.device_event(ins.time,device_event);
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn new<'a>(
|
|
window:&'a winit::window::Window,
|
|
device:wgpu::Device,
|
|
queue:wgpu::Queue,
|
|
surface:wgpu::Surface<'a>,
|
|
config:wgpu::SurfaceConfiguration,
|
|
)->WindowContext<'a>{
|
|
let graphics=strafesnet_roblox_bot_player::graphics::Graphics::new(device,queue,config);
|
|
WindowContext{
|
|
simulation_paused:false,
|
|
window,
|
|
physics_thread:crate::player::PlayerWorker::new(
|
|
surface,
|
|
graphics,
|
|
),
|
|
}
|
|
}
|
|
}
|