Compare commits
13 Commits
master
...
mouse-inte
Author | SHA1 | Date | |
---|---|---|---|
ead0e33546 | |||
b376c03bde | |||
d7dc08092a | |||
d898d7cf67 | |||
7f68fd9b21 | |||
0b8a433640 | |||
9646804dcd | |||
9cd72d5809 | |||
9ecfe26a0c | |||
fbb2ba369c | |||
d1f78b6e18 | |||
8cade8134f | |||
3268d92d24 |
@ -1,5 +1,6 @@
|
||||
mod file;
|
||||
mod setup;
|
||||
mod timer;
|
||||
mod window;
|
||||
mod worker;
|
||||
mod physics;
|
||||
|
@ -104,7 +104,8 @@ impl InputState{
|
||||
&self.next_mouse
|
||||
}
|
||||
fn set_next_mouse(&mut self,next_mouse:MouseState){
|
||||
(self.next_mouse,self.mouse)=(next_mouse,self.next_mouse.clone());
|
||||
//I like your functions magic language
|
||||
self.mouse=std::mem::replace(&mut self.next_mouse,next_mouse);
|
||||
}
|
||||
fn replace_mouse(&mut self,mouse:MouseState,next_mouse:MouseState){
|
||||
(self.next_mouse,self.mouse)=(next_mouse,mouse);
|
||||
|
@ -16,7 +16,10 @@ pub enum InputInstruction{
|
||||
PracticeFly,
|
||||
}
|
||||
pub enum Instruction{
|
||||
Input(InputInstruction),
|
||||
Passthrough(PassthroughInstruction),
|
||||
Interpolate(InputInstruction),
|
||||
}
|
||||
pub enum PassthroughInstruction{
|
||||
Render,
|
||||
Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
|
||||
GenerateModels(strafesnet_common::map::CompleteMap),
|
||||
@ -24,140 +27,179 @@ pub enum Instruction{
|
||||
//Graphics(crate::graphics_worker::Instruction),
|
||||
}
|
||||
pub struct MouseInterpolator{
|
||||
timeline:std::collections::VecDeque<TimedInstruction<PhysicsInputInstruction>>,
|
||||
last_mouse_time:Time,
|
||||
mouse_blocking:bool,
|
||||
queue:std::collections::VecDeque<TimedInstruction<InputInstruction>>,
|
||||
}
|
||||
fn drain_queue(physics:&mut crate::physics::PhysicsContext,iterable:impl IntoIterator<Item=TimedInstruction<InputInstruction>>){
|
||||
for ins in iterable{
|
||||
let physics_input=match &ins.instruction{
|
||||
InputInstruction::MoveMouse(_)=>panic!("Queue was confirmed to contain no MoveMouse events1"),
|
||||
&InputInstruction::MoveForward(s)=>PhysicsInputInstruction::SetMoveForward(s),
|
||||
&InputInstruction::MoveLeft(s)=>PhysicsInputInstruction::SetMoveLeft(s),
|
||||
&InputInstruction::MoveBack(s)=>PhysicsInputInstruction::SetMoveBack(s),
|
||||
&InputInstruction::MoveRight(s)=>PhysicsInputInstruction::SetMoveRight(s),
|
||||
&InputInstruction::MoveUp(s)=>PhysicsInputInstruction::SetMoveUp(s),
|
||||
&InputInstruction::MoveDown(s)=>PhysicsInputInstruction::SetMoveDown(s),
|
||||
&InputInstruction::Jump(s)=>PhysicsInputInstruction::SetJump(s),
|
||||
&InputInstruction::Zoom(s)=>PhysicsInputInstruction::SetZoom(s),
|
||||
InputInstruction::Reset=>PhysicsInputInstruction::Reset,
|
||||
InputInstruction::PracticeFly=>PhysicsInputInstruction::PracticeFly,
|
||||
};
|
||||
physics.run_input_instruction(TimedInstruction{
|
||||
time:ins.time,
|
||||
instruction:physics_input,
|
||||
});
|
||||
}
|
||||
}
|
||||
impl MouseInterpolator{
|
||||
fn push_mouse_instruction(&mut self,physics:&crate::physics::PhysicsContext,ins:&TimedInstruction<Instruction>,m:glam::IVec2){
|
||||
if self.mouse_blocking{
|
||||
//tell the game state which is living in the past about its future
|
||||
self.timeline.push_front(TimedInstruction{
|
||||
time:self.last_mouse_time,
|
||||
instruction:PhysicsInputInstruction::SetNextMouse(MouseState{time:ins.time,pos:m}),
|
||||
});
|
||||
}else{
|
||||
//mouse has just started moving again after being still for longer than 10ms.
|
||||
//replace the entire mouse interpolation state to avoid an intermediate state with identical m0.t m1.t timestamps which will divide by zero
|
||||
self.timeline.push_front(TimedInstruction{
|
||||
time:self.last_mouse_time,
|
||||
instruction:PhysicsInputInstruction::ReplaceMouse(
|
||||
MouseState{time:self.last_mouse_time,pos:physics.get_next_mouse().pos},
|
||||
MouseState{time:ins.time,pos:m}
|
||||
),
|
||||
});
|
||||
//delay physics execution until we have an interpolation target
|
||||
self.mouse_blocking=true;
|
||||
}
|
||||
self.last_mouse_time=ins.time;
|
||||
}
|
||||
/// returns the mapped physics input instruction
|
||||
/// may or may not mutate internal state XD!
|
||||
fn map_instruction(&mut self,physics:&crate::physics::PhysicsContext,ins:&TimedInstruction<Instruction>)->Option<PhysicsInputInstruction>{
|
||||
match &ins.instruction{
|
||||
Instruction::Input(input_instruction)=>match input_instruction{
|
||||
&InputInstruction::MoveMouse(m)=>{
|
||||
self.push_mouse_instruction(physics,ins,m);
|
||||
None
|
||||
fn handle_instruction(&mut self,physics:&mut crate::physics::PhysicsContext,ins:TimedInstruction<InputInstruction>){
|
||||
//need to handle the case where mouse polling rate is less than 100hz
|
||||
//also the whole thing is probably wrong lol
|
||||
let is_inserting_mouse_instruction=matches!(ins.instruction,InputInstruction::MoveMouse(_));
|
||||
self.queue.push_back(ins);
|
||||
//We just pushed an element.
|
||||
//The first element is guaranteed to exist.
|
||||
let mut iter=self.queue.iter();
|
||||
//find a mouse input
|
||||
'outer:loop{
|
||||
match iter.next(){
|
||||
Some(ins0)=>{
|
||||
let physics_input=match &ins0.instruction{
|
||||
&InputInstruction::MoveMouse(mut mouse0)=>{
|
||||
//mouse instruction found.
|
||||
//enter a new loop with different behaviour
|
||||
//we have to wait for the next mouse event
|
||||
//so there is a before and after interpolation target
|
||||
//write down ins0.time to appease the borrow checker
|
||||
let mut t0=ins0.time;
|
||||
'inner:loop{
|
||||
match iter.next(){
|
||||
Some(ins1)=>match &ins1.instruction{
|
||||
&InputInstruction::MoveMouse(mouse1)=>{
|
||||
//we found two mouse events to interpolate between
|
||||
let consume_count=self.queue.len()-iter.len()-1;//don't consume the mouse1 instruction
|
||||
//fire off a mouse instruction
|
||||
physics.run_input_instruction(TimedInstruction{
|
||||
time:t0,
|
||||
instruction:PhysicsInputInstruction::SetNextMouse(
|
||||
MouseState{time:ins1.time,pos:mouse1}
|
||||
),
|
||||
});
|
||||
//update inner loop state
|
||||
mouse0=mouse1;
|
||||
t0=ins1.time;
|
||||
//drain and handle the elements from the front
|
||||
std::mem::drop(iter);
|
||||
let mut hot_queue=self.queue.drain(0..consume_count);
|
||||
hot_queue.next();
|
||||
drain_queue(physics,hot_queue);
|
||||
iter=self.queue.iter();
|
||||
//keep looking for another mouse instruction in the inner loop
|
||||
continue 'inner;
|
||||
},
|
||||
_=>if Time::from_millis(10)<ins1.time-t0{
|
||||
//we have passed more than 10ms of instructions and have not seen a mouse event.
|
||||
let consume_count=self.queue.len()-iter.len();
|
||||
//run an event to extrapolate no movement from
|
||||
let last_mouse=physics.get_next_mouse();
|
||||
physics.run_input_instruction(TimedInstruction{
|
||||
time:last_mouse.time,
|
||||
instruction:PhysicsInputInstruction::SetNextMouse(
|
||||
MouseState{time:ins1.time,pos:last_mouse.pos}
|
||||
),
|
||||
});
|
||||
//drop the iterator so we can consume the queue up to this point
|
||||
std::mem::drop(iter);
|
||||
//consume queue up to the scanned point
|
||||
let mut hot_queue=self.queue.drain(0..consume_count);
|
||||
//the first element is always the last mouse instruction (last_mouse above)
|
||||
hot_queue.next();
|
||||
drain_queue(physics,hot_queue);
|
||||
//make a new iterator starting from the new beginning
|
||||
//and continue looping like nothing happened
|
||||
iter=self.queue.iter();
|
||||
continue 'outer;
|
||||
},
|
||||
},
|
||||
None=>{
|
||||
if is_inserting_mouse_instruction{
|
||||
//the mouse started moving again after being still for over 10ms.
|
||||
//replace the entire mouse state
|
||||
physics.run_input_instruction(TimedInstruction{
|
||||
time:physics.get_next_mouse().time,
|
||||
instruction:PhysicsInputInstruction::ReplaceMouse(
|
||||
physics.get_next_mouse().clone(),
|
||||
MouseState{time:t0,pos:mouse0}
|
||||
),
|
||||
});
|
||||
}
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
&InputInstruction::MoveForward(s)=>PhysicsInputInstruction::SetMoveForward(s),
|
||||
&InputInstruction::MoveLeft(s)=>PhysicsInputInstruction::SetMoveLeft(s),
|
||||
&InputInstruction::MoveBack(s)=>PhysicsInputInstruction::SetMoveBack(s),
|
||||
&InputInstruction::MoveRight(s)=>PhysicsInputInstruction::SetMoveRight(s),
|
||||
&InputInstruction::MoveUp(s)=>PhysicsInputInstruction::SetMoveUp(s),
|
||||
&InputInstruction::MoveDown(s)=>PhysicsInputInstruction::SetMoveDown(s),
|
||||
&InputInstruction::Jump(s)=>PhysicsInputInstruction::SetJump(s),
|
||||
&InputInstruction::Zoom(s)=>PhysicsInputInstruction::SetZoom(s),
|
||||
InputInstruction::Reset=>PhysicsInputInstruction::Reset,
|
||||
InputInstruction::PracticeFly=>PhysicsInputInstruction::PracticeFly,
|
||||
};
|
||||
//handle each event immediately, we are not waiting for mouse
|
||||
physics.run_input_instruction(TimedInstruction{
|
||||
time:ins0.time,
|
||||
instruction:physics_input,
|
||||
});
|
||||
//drop it and pop it! consume one element and continue the loop
|
||||
std::mem::drop(iter);
|
||||
self.queue.pop_front();
|
||||
iter=self.queue.iter();
|
||||
},
|
||||
&InputInstruction::MoveForward(s)=>Some(PhysicsInputInstruction::SetMoveForward(s)),
|
||||
&InputInstruction::MoveLeft(s)=>Some(PhysicsInputInstruction::SetMoveLeft(s)),
|
||||
&InputInstruction::MoveBack(s)=>Some(PhysicsInputInstruction::SetMoveBack(s)),
|
||||
&InputInstruction::MoveRight(s)=>Some(PhysicsInputInstruction::SetMoveRight(s)),
|
||||
&InputInstruction::MoveUp(s)=>Some(PhysicsInputInstruction::SetMoveUp(s)),
|
||||
&InputInstruction::MoveDown(s)=>Some(PhysicsInputInstruction::SetMoveDown(s)),
|
||||
&InputInstruction::Jump(s)=>Some(PhysicsInputInstruction::SetJump(s)),
|
||||
&InputInstruction::Zoom(s)=>Some(PhysicsInputInstruction::SetZoom(s)),
|
||||
InputInstruction::Reset=>Some(PhysicsInputInstruction::Reset),
|
||||
InputInstruction::PracticeFly=>Some(PhysicsInputInstruction::PracticeFly),
|
||||
},
|
||||
Instruction::GenerateModels(_)=>Some(PhysicsInputInstruction::Idle),
|
||||
Instruction::ClearModels=>Some(PhysicsInputInstruction::Idle),
|
||||
Instruction::Resize(_,_)=>Some(PhysicsInputInstruction::Idle),
|
||||
Instruction::Render=>Some(PhysicsInputInstruction::Idle),
|
||||
}
|
||||
}
|
||||
fn update_mouse_blocking(&mut self,physics:&crate::physics::PhysicsContext,ins:&TimedInstruction<Instruction>)->bool{
|
||||
if self.mouse_blocking{
|
||||
//assume the mouse has stopped moving after 10ms.
|
||||
//shitty mice are 125Hz which is 8ms so this should cover that.
|
||||
//setting this to 100us still doesn't print even though it's 10x lower than the polling rate,
|
||||
//so mouse events are probably not handled separately from drawing and fire right before it :(
|
||||
if Time::from_millis(10)<ins.time-physics.get_next_mouse().time{
|
||||
//push an event to extrapolate no movement from
|
||||
self.timeline.push_front(TimedInstruction{
|
||||
time:self.last_mouse_time,
|
||||
instruction:PhysicsInputInstruction::SetNextMouse(MouseState{time:ins.time,pos:physics.get_next_mouse().pos}),
|
||||
});
|
||||
self.last_mouse_time=ins.time;
|
||||
//stop blocking. the mouse is not moving so the physics does not need to live in the past and wait for interpolation targets.
|
||||
self.mouse_blocking=false;
|
||||
true
|
||||
}else{
|
||||
false
|
||||
None=>{
|
||||
//if mouse0 is never found and the loop ends, we can drain the entire queue
|
||||
//because we are not waiting for mouse events.
|
||||
drain_queue(physics,self.queue.drain(..));
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//keep this up to date so that it can be used as a known-timestamp
|
||||
//that the mouse was not moving when the mouse starts moving again
|
||||
self.last_mouse_time=ins.time;
|
||||
true
|
||||
}
|
||||
}
|
||||
/// returns whether or not to empty the instruction queue
|
||||
fn handle_physics_input(&mut self,physics:&crate::physics::PhysicsContext,ins:&TimedInstruction<Instruction>,phys_input_option:Option<PhysicsInputInstruction>)->bool{
|
||||
if let Some(phys_input)=phys_input_option{
|
||||
//non-mouse event
|
||||
self.timeline.push_back(TimedInstruction{
|
||||
time:ins.time,
|
||||
instruction:phys_input,
|
||||
});
|
||||
|
||||
//this returns the bool for us
|
||||
self.update_mouse_blocking(physics,ins)
|
||||
}else{
|
||||
//mouse event
|
||||
true
|
||||
}
|
||||
}
|
||||
fn empty_queue(&mut self,physics:&mut crate::physics::PhysicsContext){
|
||||
while let Some(instruction)=self.timeline.pop_front(){
|
||||
physics.run_input_instruction(instruction);
|
||||
}
|
||||
}
|
||||
fn handle_instruction(&mut self,physics:&mut crate::physics::PhysicsContext,ins:&TimedInstruction<Instruction>){
|
||||
let physics_input_option=self.map_instruction(physics,ins);
|
||||
let should_empty_queue=self.handle_physics_input(physics,ins,physics_input_option);
|
||||
if should_empty_queue{
|
||||
self.empty_queue(physics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(mut physics:crate::physics::PhysicsContext,mut graphics_worker:crate::compat_worker::INWorker<crate::graphics_worker::Instruction>)->crate::compat_worker::QNWorker<TimedInstruction<Instruction>>{
|
||||
let mut interpolator=MouseInterpolator{
|
||||
mouse_blocking:true,
|
||||
last_mouse_time:physics.get_next_mouse().time,
|
||||
timeline:std::collections::VecDeque::new(),
|
||||
queue:std::collections::VecDeque::new(),
|
||||
};
|
||||
crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<Instruction>|{
|
||||
interpolator.handle_instruction(&mut physics,&ins);
|
||||
match ins.instruction{
|
||||
Instruction::Render=>{
|
||||
let passthrough_instruction=match ins.instruction{
|
||||
Instruction::Passthrough(passthrough_instruction)=>passthrough_instruction,
|
||||
Instruction::Interpolate(input_instruction)=>{
|
||||
interpolator.handle_instruction(&mut physics,TimedInstruction{
|
||||
instruction:input_instruction,
|
||||
time:ins.time,
|
||||
});
|
||||
return;
|
||||
},
|
||||
};
|
||||
match passthrough_instruction{
|
||||
PassthroughInstruction::Render=>{
|
||||
graphics_worker.send(crate::graphics_worker::Instruction::Render(physics.output(),ins.time,physics.get_next_mouse().pos)).unwrap();
|
||||
},
|
||||
Instruction::Resize(size,user_settings)=>{
|
||||
PassthroughInstruction::Resize(size,user_settings)=>{
|
||||
graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,user_settings)).unwrap();
|
||||
},
|
||||
Instruction::GenerateModels(map)=>{
|
||||
PassthroughInstruction::GenerateModels(map)=>{
|
||||
physics.generate_models(&map);
|
||||
physics.spawn();
|
||||
graphics_worker.send(crate::graphics_worker::Instruction::GenerateModels(map)).unwrap();
|
||||
},
|
||||
Instruction::ClearModels=>{
|
||||
PassthroughInstruction::ClearModels=>{
|
||||
physics.clear();
|
||||
graphics_worker.send(crate::graphics_worker::Instruction::ClearModels).unwrap();
|
||||
},
|
||||
_=>(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
179
src/timer.rs
Normal file
179
src/timer.rs
Normal file
@ -0,0 +1,179 @@
|
||||
use strafesnet_common::integer::{Time,Ratio64};
|
||||
|
||||
pub trait TimerState:Copy{
|
||||
fn get_time(&self,time:Time)->Time;
|
||||
fn set_time(&mut self,time:Time,new_time:Time);
|
||||
fn get_offset(&self)->Time;
|
||||
fn set_offset(&mut self,offset:Time);
|
||||
}
|
||||
|
||||
#[derive(Clone,Copy,Debug)]
|
||||
struct Scaled{
|
||||
scale:Ratio64,
|
||||
offset:Time,
|
||||
}
|
||||
impl Scaled{
|
||||
fn scale(&self,time:Time)->Time{
|
||||
Time::raw(self.scale.mul_int(time.get()))
|
||||
}
|
||||
fn get_scale(&self)->Ratio64{
|
||||
self.scale
|
||||
}
|
||||
fn set_scale(&mut self,time:Time,new_scale:Ratio64){
|
||||
let new_time=self.get_time(time);
|
||||
self.scale=new_scale;
|
||||
self.set_time(time,new_time);
|
||||
}
|
||||
}
|
||||
impl TimerState for Scaled{
|
||||
fn get_time(&self,time:Time)->Time{
|
||||
self.scale(time)+self.offset
|
||||
}
|
||||
fn set_time(&mut self,time:Time,new_time:Time){
|
||||
self.offset=new_time-self.scale(time);
|
||||
}
|
||||
fn get_offset(&self)->Time{
|
||||
self.offset
|
||||
}
|
||||
fn set_offset(&mut self,offset:Time){
|
||||
self.offset=offset;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,Copy,Debug)]
|
||||
struct Realtime{
|
||||
offset:Time,
|
||||
}
|
||||
impl TimerState for Realtime{
|
||||
fn get_time(&self,time:Time)->Time{
|
||||
time+self.offset
|
||||
}
|
||||
fn set_time(&mut self,time:Time,new_time:Time){
|
||||
self.offset=new_time-time;
|
||||
}
|
||||
fn get_offset(&self)->Time{
|
||||
self.offset
|
||||
}
|
||||
fn set_offset(&mut self,offset:Time){
|
||||
self.offset=offset;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
pub struct Timer<T>{
|
||||
state:T,
|
||||
paused:bool,
|
||||
}
|
||||
|
||||
impl Timer<Realtime>{
|
||||
pub fn realtime(offset:Time)->Self{
|
||||
Self{
|
||||
state:Realtime{offset},
|
||||
paused:false,
|
||||
}
|
||||
}
|
||||
pub fn realtime_paused(offset:Time)->Self{
|
||||
Self{
|
||||
state:Realtime{offset},
|
||||
paused:true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
AlreadyPaused,
|
||||
AlreadyUnpaused,
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
write!(f,"{self:?}")
|
||||
}
|
||||
}
|
||||
impl std::error::Error for Error{}
|
||||
|
||||
impl Timer<Scaled>{
|
||||
pub fn scaled(scale:Ratio64,offset:Time)->Self{
|
||||
Self{
|
||||
state:Scaled{scale,offset},
|
||||
paused:false,
|
||||
}
|
||||
}
|
||||
pub fn scaled_paused(scale:Ratio64,offset:Time)->Self{
|
||||
Self{
|
||||
state:Scaled{scale,offset},
|
||||
paused:true,
|
||||
}
|
||||
}
|
||||
pub fn get_scale(&mut self)->Ratio64{
|
||||
self.state.get_scale()
|
||||
}
|
||||
pub fn set_scale(&mut self,time:Time,new_scale:Ratio64){
|
||||
self.state.set_scale(time,new_scale)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:TimerState> Timer<T>{
|
||||
pub fn time(&self,time:Time)->Time{
|
||||
match self.paused{
|
||||
true=>self.state.get_offset(),
|
||||
false=>self.state.get_time(time),
|
||||
}
|
||||
}
|
||||
pub fn set_time(&mut self,time:Time,new_time:Time){
|
||||
match self.paused{
|
||||
true=>self.state.set_offset(new_time),
|
||||
false=>self.state.set_time(time,new_time),
|
||||
}
|
||||
}
|
||||
pub fn pause(&mut self,time:Time)->Result<(),Error>{
|
||||
match self.paused{
|
||||
true=>Err(Error::AlreadyPaused),
|
||||
false=>{
|
||||
let new_time=self.time(time);
|
||||
self.state.set_offset(new_time);
|
||||
self.paused=true;
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
pub fn unpause(&mut self,time:Time)->Result<(),Error>{
|
||||
match self.paused{
|
||||
true=>{
|
||||
let new_time=self.time(time);
|
||||
self.state.set_time(time,new_time);
|
||||
self.paused=false;
|
||||
Ok(())
|
||||
},
|
||||
false=>Err(Error::AlreadyUnpaused),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
use super::{Time,Timer,Error};
|
||||
macro_rules! sec {
|
||||
($s: expr) => {
|
||||
Time::from_secs($s)
|
||||
};
|
||||
}
|
||||
#[test]
|
||||
fn test_timer()->Result<(),Error>{
|
||||
//create a paused timer that reads 0s
|
||||
let mut timer=Timer::realtime_paused(sec!(0));
|
||||
//the paused timer at 1 second should read 0s
|
||||
assert_eq!(timer.time(sec!(1)),sec!(0));
|
||||
|
||||
//unpause it after one second
|
||||
timer.unpause(sec!(1))?;
|
||||
//the timer at 6 seconds should read 5s
|
||||
assert_eq!(timer.time(sec!(6)),sec!(5));
|
||||
|
||||
//pause the timer after 11 seconds
|
||||
timer.pause(sec!(11))?;
|
||||
//the paused timer at 20 seconds should read 10s
|
||||
assert_eq!(timer.time(sec!(20)),sec!(10));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -29,8 +29,12 @@ impl WindowContext<'_>{
|
||||
winit::event::WindowEvent::DroppedFile(path)=>{
|
||||
match crate::file::load(path.as_path()){
|
||||
Ok(map)=>{
|
||||
self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::ClearModels}).unwrap();
|
||||
self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::GenerateModels(map)}).unwrap();
|
||||
self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::Passthrough(
|
||||
crate::physics_worker::PassthroughInstruction::ClearModels
|
||||
)}).unwrap();
|
||||
self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::Passthrough(
|
||||
crate::physics_worker::PassthroughInstruction::GenerateModels(map)
|
||||
)}).unwrap();
|
||||
},
|
||||
Err(e)=>println!("Failed to load map: {e}"),
|
||||
}
|
||||
@ -115,7 +119,7 @@ impl WindowContext<'_>{
|
||||
}{
|
||||
self.physics_thread.send(TimedInstruction{
|
||||
time,
|
||||
instruction:crate::physics_worker::Instruction::Input(input_instruction),
|
||||
instruction:crate::physics_worker::Instruction::Interpolate(input_instruction),
|
||||
}).unwrap();
|
||||
}
|
||||
},
|
||||
@ -143,7 +147,7 @@ impl WindowContext<'_>{
|
||||
self.mouse.pos+=delta;
|
||||
self.physics_thread.send(TimedInstruction{
|
||||
time,
|
||||
instruction:crate::physics_worker::Instruction::Input(InputInstruction::MoveMouse(self.mouse.pos)),
|
||||
instruction:crate::physics_worker::Instruction::Interpolate(InputInstruction::MoveMouse(self.mouse.pos)),
|
||||
}).unwrap();
|
||||
},
|
||||
winit::event::DeviceEvent::MouseWheel {
|
||||
@ -153,7 +157,7 @@ impl WindowContext<'_>{
|
||||
if false{//self.physics.style.use_scroll{
|
||||
self.physics_thread.send(TimedInstruction{
|
||||
time,
|
||||
instruction:crate::physics_worker::Instruction::Input(InputInstruction::Jump(true)),//activates the immediate jump path, but the style modifier prevents controls&CONTROL_JUMP bit from being set to auto jump
|
||||
instruction:crate::physics_worker::Instruction::Interpolate(InputInstruction::Jump(true)),//activates the immediate jump path, but the style modifier prevents controls&CONTROL_JUMP bit from being set to auto jump
|
||||
}).unwrap();
|
||||
}
|
||||
}
|
||||
@ -218,7 +222,9 @@ impl<'a> WindowContextSetup<'a>{
|
||||
window_context.physics_thread.send(
|
||||
TimedInstruction{
|
||||
time:ins.time,
|
||||
instruction:crate::physics_worker::Instruction::Resize(size,window_context.user_settings.clone())
|
||||
instruction:crate::physics_worker::Instruction::Passthrough(
|
||||
crate::physics_worker::PassthroughInstruction::Resize(size,window_context.user_settings.clone())
|
||||
)
|
||||
}
|
||||
).unwrap();
|
||||
}
|
||||
@ -226,11 +232,13 @@ impl<'a> WindowContextSetup<'a>{
|
||||
window_context.physics_thread.send(
|
||||
TimedInstruction{
|
||||
time:ins.time,
|
||||
instruction:crate::physics_worker::Instruction::Render
|
||||
instruction:crate::physics_worker::Instruction::Passthrough(
|
||||
crate::physics_worker::PassthroughInstruction::Render
|
||||
)
|
||||
}
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user