improve seek algorithmic complexity O(n) -> O(log(n))
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -1661,9 +1661,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strafesnet_roblox_bot_file"
|
name = "strafesnet_roblox_bot_file"
|
||||||
version = "0.9.0"
|
version = "0.9.2"
|
||||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||||
checksum = "3ee6a8c592794145fdbbb2fbdaedbbc5813373e2e2bbbb9bac6ab7944775cc0a"
|
checksum = "f3764f94fb71eba824aeabde808b490ef719331673f3f485c8b176895e4955dd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"binrw",
|
"binrw",
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ codegen-units = 1
|
|||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
strafesnet_common = { version = "0.8.3", registry = "strafesnet" }
|
strafesnet_common = { version = "0.8.3", registry = "strafesnet" }
|
||||||
strafesnet_graphics = { version = "0.0.2", registry = "strafesnet" }
|
strafesnet_graphics = { version = "0.0.2", registry = "strafesnet" }
|
||||||
strafesnet_roblox_bot_file = { version = "0.9.0", registry = "strafesnet" }
|
strafesnet_roblox_bot_file = { version = "0.9.2", registry = "strafesnet" }
|
||||||
strafesnet_snf = { version = "0.3.2", registry = "strafesnet" }
|
strafesnet_snf = { version = "0.3.2", registry = "strafesnet" }
|
||||||
|
|||||||
@@ -41,24 +41,35 @@ impl PlaybackHead{
|
|||||||
pub fn time(&self,time:SessionTime)->Time{
|
pub fn time(&self,time:SessionTime)->Time{
|
||||||
self.timer.time(time)
|
self.timer.time(time)
|
||||||
}
|
}
|
||||||
|
pub fn set_paused(&mut self,time:SessionTime,paused:bool){
|
||||||
|
_=self.timer.set_paused(time,paused);
|
||||||
|
}
|
||||||
|
pub fn set_time(&mut self,bot:&CompleteBot,time:SessionTime,new_time:Time){
|
||||||
|
self.timer.set_time(time,new_time);
|
||||||
|
// reset head
|
||||||
|
self.head=Head::after_time(bot.timelines(),bot.time(new_time).into());
|
||||||
|
|
||||||
|
// nudge indices as a hack to avoid oob index
|
||||||
|
if self.head.get_event_index(EventType::Output)==0{
|
||||||
|
self.head.push(EventType::Output);
|
||||||
|
}
|
||||||
|
if self.head.get_event_index(EventType::Output)==bot.timelines().output_events.len(){
|
||||||
|
self.head.set_event_index(EventType::Output,bot.timelines().output_events.len()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state=PlaybackState::new();
|
||||||
|
self.state.process_head(bot.timelines(),&self.head);
|
||||||
|
}
|
||||||
|
pub fn set_scale(&mut self,time:SessionTime,new_scale:strafesnet_common::integer::Ratio64){
|
||||||
|
self.timer.set_scale(time,new_scale);
|
||||||
|
}
|
||||||
pub fn next_event(&self,bot:&CompleteBot)->Option<Timed<EventType>>{
|
pub fn next_event(&self,bot:&CompleteBot)->Option<Timed<EventType>>{
|
||||||
self.head.next_event(bot.timelines())
|
self.head.next_event(bot.timelines())
|
||||||
}
|
}
|
||||||
pub fn process_event(&mut self,bot:&CompleteBot,event_type:EventType){
|
pub fn process_event(&mut self,bot:&CompleteBot,event_type:EventType){
|
||||||
self.state.process_event(bot,event_type,self.head.get_event_index(event_type));
|
self.state.process_event(bot.timelines(),event_type,self.head.get_event_index(event_type));
|
||||||
self.head.push(event_type);
|
self.head.push(event_type);
|
||||||
}
|
}
|
||||||
pub fn set_paused(&mut self,time:SessionTime,paused:bool){
|
|
||||||
_=self.timer.set_paused(time,paused);
|
|
||||||
}
|
|
||||||
pub fn set_time(&mut self,time:SessionTime,new_time:Time){
|
|
||||||
self.timer.set_time(time,new_time);
|
|
||||||
// reset head
|
|
||||||
self.head=HEAD_NO_CRASH;
|
|
||||||
}
|
|
||||||
pub fn set_scale(&mut self,time:SessionTime,new_scale:strafesnet_common::integer::Ratio64){
|
|
||||||
self.timer.set_scale(time,new_scale);
|
|
||||||
}
|
|
||||||
pub fn advance_time(&mut self,bot:&CompleteBot,time:SessionTime){
|
pub fn advance_time(&mut self,bot:&CompleteBot,time:SessionTime){
|
||||||
let mut simulation_time=bot.time(self.time(time));
|
let mut simulation_time=bot.time(self.time(time));
|
||||||
let mut time_float=simulation_time.into();
|
let mut time_float=simulation_time.into();
|
||||||
@@ -74,6 +85,7 @@ impl PlaybackHead{
|
|||||||
None=>{
|
None=>{
|
||||||
//reset playback
|
//reset playback
|
||||||
self.head=HEAD_NO_CRASH;
|
self.head=HEAD_NO_CRASH;
|
||||||
|
self.state=PlaybackState::new();
|
||||||
|
|
||||||
// hack to wind back timer offset without precise session timestamp
|
// hack to wind back timer offset without precise session timestamp
|
||||||
let (mut state,paused)=self.timer.clone().into_state();
|
let (mut state,paused)=self.timer.clone().into_state();
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ use strafesnet_common::run;
|
|||||||
use strafesnet_common::physics::Time as PhysicsTime;
|
use strafesnet_common::physics::Time as PhysicsTime;
|
||||||
use strafesnet_roblox_bot_file::v0;
|
use strafesnet_roblox_bot_file::v0;
|
||||||
|
|
||||||
use crate::bot::CompleteBot;
|
|
||||||
|
|
||||||
pub struct Run{
|
pub struct Run{
|
||||||
run:run::RunState,
|
run:run::RunState,
|
||||||
flag_reason:Option<v0::FlagReason>,
|
flag_reason:Option<v0::FlagReason>,
|
||||||
@@ -195,16 +193,45 @@ impl PlaybackState{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn process_event(&mut self,bot:&CompleteBot,event_type:v0::EventType,event_index:usize){
|
pub(crate) fn process_head(&mut self,block:&v0::Block,head:&v0::Head){
|
||||||
|
// The whole point of this is to avoid running the realtime events!
|
||||||
|
/*
|
||||||
|
for event in &block.input_events[0..head.get_event_index(v0::EventType::Input)]{
|
||||||
|
self.push_input(&event.event);
|
||||||
|
}
|
||||||
|
for event in &block.output_events[0..head.get_event_index(v0::EventType::Output)]{
|
||||||
|
self.push_output(&event.event);
|
||||||
|
}
|
||||||
|
for event in &bot.sound_events[0..head.get_event_index(v0::EventType::Sound)]{
|
||||||
|
self.push_sound(&event.event);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// for event in &bot.world_events[0..head.get_event_index(v0::EventType::World)]{
|
||||||
|
// self.push_world(&event.event);
|
||||||
|
// }
|
||||||
|
for event in &block.gravity_events[0..head.get_event_index(v0::EventType::Gravity)]{
|
||||||
|
self.push_gravity(&event.event);
|
||||||
|
}
|
||||||
|
for event in &block.run_events[0..head.get_event_index(v0::EventType::Run)]{
|
||||||
|
self.push_run(event);
|
||||||
|
}
|
||||||
|
// for event in &bot.camera_events[0..head.get_event_index(v0::EventType::Camera)]{
|
||||||
|
// self.push_camera(&event.event);
|
||||||
|
// }
|
||||||
|
for event in &block.setting_events[0..head.get_event_index(v0::EventType::Setting)]{
|
||||||
|
self.push_setting(&event.event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) fn process_event(&mut self,block:&v0::Block,event_type:v0::EventType,event_index:usize){
|
||||||
match event_type{
|
match event_type{
|
||||||
v0::EventType::Input=>self.push_input(&bot.timelines().input_events[event_index].event),
|
v0::EventType::Input=>self.push_input(&block.input_events[event_index].event),
|
||||||
v0::EventType::Output=>self.push_output(&bot.timelines().output_events[event_index].event),
|
v0::EventType::Output=>self.push_output(&block.output_events[event_index].event),
|
||||||
v0::EventType::Sound=>{},
|
v0::EventType::Sound=>{},
|
||||||
v0::EventType::World=>{},
|
v0::EventType::World=>{},
|
||||||
v0::EventType::Gravity=>self.push_gravity(&bot.timelines().gravity_events[event_index].event),
|
v0::EventType::Gravity=>self.push_gravity(&block.gravity_events[event_index].event),
|
||||||
v0::EventType::Run=>self.push_run(&bot.timelines().run_events[event_index]),
|
v0::EventType::Run=>self.push_run(&block.run_events[event_index]),
|
||||||
v0::EventType::Camera=>{},
|
v0::EventType::Camera=>{},
|
||||||
v0::EventType::Setting=>self.push_setting(&bot.timelines().setting_events[event_index].event),
|
v0::EventType::Setting=>self.push_setting(&block.setting_events[event_index].event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_fov_y(&self)->f64{
|
pub fn get_fov_y(&self)->f64{
|
||||||
|
|||||||
@@ -53,16 +53,16 @@ impl<'a> PlayerWorker<'a>{
|
|||||||
Instruction::SessionControl(SessionControlInstruction::SetPaused(paused))=>{
|
Instruction::SessionControl(SessionControlInstruction::SetPaused(paused))=>{
|
||||||
self.playback_head.set_paused(ins.time,paused);
|
self.playback_head.set_paused(ins.time,paused);
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::Restart)=>{
|
Instruction::SessionControl(SessionControlInstruction::Restart)=>if let Some(bot)=&self.bot{
|
||||||
self.playback_head.set_time(ins.time,PlaybackTime::ZERO);
|
self.playback_head.set_time(bot,ins.time,PlaybackTime::ZERO);
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::SkipForward)=>{
|
Instruction::SessionControl(SessionControlInstruction::SkipForward)=>if let Some(bot)=&self.bot{
|
||||||
let head_time=self.playback_head.time(ins.time);
|
let head_time=self.playback_head.time(ins.time);
|
||||||
self.playback_head.set_time(ins.time,head_time+PlaybackTime::from_secs(2));
|
self.playback_head.set_time(bot,ins.time,head_time+PlaybackTime::from_secs(2));
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::SkipBack)=>{
|
Instruction::SessionControl(SessionControlInstruction::SkipBack)=>if let Some(bot)=&self.bot{
|
||||||
let head_time=self.playback_head.time(ins.time);
|
let head_time=self.playback_head.time(ins.time);
|
||||||
self.playback_head.set_time(ins.time,head_time-PlaybackTime::from_secs(2));
|
self.playback_head.set_time(bot,ins.time,head_time-PlaybackTime::from_secs(2));
|
||||||
},
|
},
|
||||||
Instruction::SessionControl(SessionControlInstruction::DecreaseTimescale)=>{
|
Instruction::SessionControl(SessionControlInstruction::DecreaseTimescale)=>{
|
||||||
self.playback_speed=self.playback_speed.saturating_sub(1).max(-27);
|
self.playback_speed=self.playback_speed.saturating_sub(1).max(-27);
|
||||||
|
|||||||
@@ -134,10 +134,10 @@ impl PlaybackHead{
|
|||||||
}
|
}
|
||||||
/// Set the playback head position to new_time.
|
/// Set the playback head position to new_time.
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn set_head_time(&mut self,time:f64,new_time:f64){
|
pub fn set_head_time(&mut self,bot:&CompleteBot,time:f64,new_time:f64){
|
||||||
let time=time::from_float(time).unwrap();
|
let time=time::from_float(time).unwrap();
|
||||||
let new_time=time::from_float(new_time).unwrap();
|
let new_time=time::from_float(new_time).unwrap();
|
||||||
self.head.set_time(time,new_time);
|
self.head.set_time(&bot.bot,time,new_time);
|
||||||
}
|
}
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn get_run_time(&self,bot:&CompleteBot,time:f64,mode_id:u32)->Option<f64>{
|
pub fn get_run_time(&self,bot:&CompleteBot,time:f64,mode_id:u32)->Option<f64>{
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ function set_scale(new_scale) {
|
|||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
document.getElementById("control_reset").addEventListener("click", (e) => {
|
document.getElementById("control_reset").addEventListener("click", (e) => {
|
||||||
playback.set_head_time(elapsed(), 0.0);
|
playback.set_head_time(bot, elapsed(), 0.0);
|
||||||
});
|
});
|
||||||
document.getElementById("control_pause").addEventListener("click", (e) => {
|
document.getElementById("control_pause").addEventListener("click", (e) => {
|
||||||
paused = !paused;
|
paused = !paused;
|
||||||
@@ -65,12 +65,12 @@ document.getElementById("control_pause").addEventListener("click", (e) => {
|
|||||||
document.getElementById("control_forward").addEventListener("click", (e) => {
|
document.getElementById("control_forward").addEventListener("click", (e) => {
|
||||||
const time_now = elapsed();
|
const time_now = elapsed();
|
||||||
const playback_time = playback.get_head_time(time_now);
|
const playback_time = playback.get_head_time(time_now);
|
||||||
playback.set_head_time(time_now, playback_time + 2.0);
|
playback.set_head_time(bot, time_now, playback_time + 2.0);
|
||||||
});
|
});
|
||||||
document.getElementById("control_backward").addEventListener("click", (e) => {
|
document.getElementById("control_backward").addEventListener("click", (e) => {
|
||||||
const time_now = elapsed();
|
const time_now = elapsed();
|
||||||
const playback_time = playback.get_head_time(time_now);
|
const playback_time = playback.get_head_time(time_now);
|
||||||
playback.set_head_time(time_now, playback_time - 2.0);
|
playback.set_head_time(bot, time_now, playback_time - 2.0);
|
||||||
});
|
});
|
||||||
document.getElementById("control_slower").addEventListener("click", (e) => {
|
document.getElementById("control_slower").addEventListener("click", (e) => {
|
||||||
set_scale((scale * 4) / 5);
|
set_scale((scale * 4) / 5);
|
||||||
|
|||||||
Reference in New Issue
Block a user