Files
roblox-bot-player/native-player/src/window.rs
2026-02-20 11:09:35 -08:00

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,
),
}
}
}