Add scoring update timeout

This commit is contained in:
hodasemi 2023-01-19 07:39:34 +01:00
parent 5186b96b44
commit eec17e1039
3 changed files with 156 additions and 111 deletions

View file

@ -26,6 +26,8 @@ pub struct Pedals {
throttle: Arc<ProgressBar>, throttle: Arc<ProgressBar>,
_history: Arc<Icon>, _history: Arc<Icon>,
enable: bool,
throttle_samples: HeapRb<f32>, throttle_samples: HeapRb<f32>,
brake_samples: HeapRb<f32>, brake_samples: HeapRb<f32>,
@ -138,6 +140,8 @@ impl Pedals {
throttle, throttle,
_history: history, _history: history,
enable: false,
throttle_samples, throttle_samples,
brake_samples, brake_samples,
@ -202,7 +206,7 @@ impl Pedals {
let command_buffer = let command_buffer =
CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?; CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?;
{ if self.enable {
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new( let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
@ -231,7 +235,18 @@ impl Pedals {
impl UiOverlay for Pedals {} impl UiOverlay for Pedals {}
impl DataReceiver for Pedals { impl DataReceiver for Pedals {
fn game_phase_change(&mut self, _phase: GamePhase) -> Result<()> { fn game_phase_change(&mut self, phase: GamePhase) -> Result<()> {
match phase {
GamePhase::None => {
self.enable = false;
self.gui.disable()?;
}
_ => {
self.enable = true;
self.gui.enable()?;
}
}
Ok(()) Ok(())
} }
@ -257,25 +272,18 @@ impl DataReceiver for Pedals {
player_id: Option<i32>, player_id: Option<i32>,
telemetries: &[rF2VehicleTelemetry], telemetries: &[rF2VehicleTelemetry],
) -> Result<()> { ) -> Result<()> {
match player_id { if let Some(id) = player_id {
Some(id) => { if let Some(telemetry) = telemetries.iter().find(|telemetry| telemetry.id == id) {
self.gui.enable()?; let brake = 1.0 - telemetry.unfiltered_brake as f32;
let throttle = 1.0 - telemetry.unfiltered_throttle as f32;
if let Some(telemetry) = telemetries.iter().find(|telemetry| telemetry.id == id) { self.throttle.set_progress(throttle)?;
let brake = 1.0 - telemetry.unfiltered_brake as f32; self.brake.set_progress(brake)?;
let throttle = 1.0 - telemetry.unfiltered_throttle as f32;
self.throttle.set_progress(throttle)?; self.throttle_samples.push_overwrite(throttle);
self.brake.set_progress(brake)?; self.brake_samples.push_overwrite(brake);
self.throttle_samples.push_overwrite(throttle); self.update_vertex_buffers()?;
self.brake_samples.push_overwrite(brake);
self.update_vertex_buffers()?;
}
}
None => {
self.gui.disable()?;
} }
} }

View file

@ -73,6 +73,8 @@ pub struct Radar {
car_width: f32, car_width: f32,
car_height: f32, car_height: f32,
enable: bool,
device: Arc<Device>, device: Arc<Device>,
queue: Arc<Mutex<Queue>>, queue: Arc<Mutex<Queue>>,
@ -171,6 +173,8 @@ impl Radar {
car_width, car_width,
car_height, car_height,
enable: false,
device, device,
queue, queue,
@ -216,7 +220,7 @@ impl Radar {
let command_buffer = let command_buffer =
CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?; CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?;
{ if self.enable {
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new( let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
@ -268,7 +272,12 @@ impl Radar {
impl UiOverlay for Radar {} impl UiOverlay for Radar {}
impl DataReceiver for Radar { impl DataReceiver for Radar {
fn game_phase_change(&mut self, _phase: GamePhase) -> Result<()> { fn game_phase_change(&mut self, phase: GamePhase) -> Result<()> {
match phase {
GamePhase::None => self.enable = false,
_ => self.enable = true,
}
Ok(()) Ok(())
} }
@ -299,68 +308,71 @@ impl DataReceiver for Radar {
self.cars.clear(); self.cars.clear();
if let Some(player_id) = player_id { if self.enable {
// make sure there are enough cars in buffer if let Some(player_id) = player_id {
if self.car_handles.len() < telemetries.len() { // make sure there are enough cars in buffer
let size_diff = telemetries.len() - self.car_handles.len(); if self.car_handles.len() < telemetries.len() {
let size_diff = telemetries.len() - self.car_handles.len();
for _ in 0..size_diff { for _ in 0..size_diff {
self.car_handles self.car_handles
.push(self.create_car_object(vec2(0.0, 0.0), [0.0, 0.0, 0.0, 0.0])?); .push(self.create_car_object(vec2(0.0, 0.0), [0.0, 0.0, 0.0, 0.0])?);
}
}
let mut player_position = CarPosition::default();
let mut other_positions = Vec::new();
for telemetry in telemetries {
let car = CarPosition::new(
convert_vec(telemetry.position),
[
convert_vec(telemetry.orientation[0]),
convert_vec(telemetry.orientation[1]),
convert_vec(telemetry.orientation[2]),
],
);
if telemetry.id == player_id {
player_position = car
} else {
other_positions.push(car);
}
}
// update radar objects
let mut buffer_car_index = 0;
for other_position in other_positions {
let diff = player_position.position - other_position.position;
let distance = diff.magnitude();
// check if car is close enough to the players car
if distance < self.config.radar_car_distance {
let offset =
diff.xz() * (self.radar_extent / self.config.radar_car_distance);
let buffered_car = self.car_handles[buffer_car_index].clone();
buffer_car_index += 1;
buffered_car.update(
self.ortho,
offset,
player_position.rotation,
other_position.rotation,
self.radar_center,
self.car_width,
self.car_height,
[0.9, 0.9, 0.0, 0.9],
)?;
self.cars.push(buffered_car);
}
} }
} }
let mut player_position = CarPosition::default(); write_log!(format!("other cars: {:?}", self.cars.len()));
let mut other_positions = Vec::new();
for telemetry in telemetries {
let car = CarPosition::new(
convert_vec(telemetry.position),
[
convert_vec(telemetry.orientation[0]),
convert_vec(telemetry.orientation[1]),
convert_vec(telemetry.orientation[2]),
],
);
if telemetry.id == player_id {
player_position = car
} else {
other_positions.push(car);
}
}
// update radar objects
let mut buffer_car_index = 0;
for other_position in other_positions {
let diff = player_position.position - other_position.position;
let distance = diff.magnitude();
// check if car is close enough to the players car
if distance < self.config.radar_car_distance {
let offset = diff.xz() * (self.radar_extent / self.config.radar_car_distance);
let buffered_car = self.car_handles[buffer_car_index].clone();
buffer_car_index += 1;
buffered_car.update(
self.ortho,
offset,
player_position.rotation,
other_position.rotation,
self.radar_center,
self.car_width,
self.car_height,
[0.9, 0.9, 0.0, 0.9],
)?;
self.cars.push(buffered_car);
}
}
} }
write_log!(format!("other cars: {:?}", self.cars.len()));
Ok(()) Ok(())
} }
} }

View file

@ -1,7 +1,11 @@
use anyhow::Result; use anyhow::Result;
use rfactor_sm_reader::*; use rfactor_sm_reader::*;
use std::{cell::RefCell, rc::Rc, time::Instant}; use std::{
cell::RefCell,
rc::Rc,
time::{Duration, Instant},
};
use crate::write_log; use crate::write_log;
@ -25,6 +29,8 @@ pub trait DataReceiver {
) -> Result<()>; ) -> Result<()>;
} }
const GAME_PHASE_TIME_OUT: Duration = Duration::from_secs(2);
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum GamePhase { pub enum GamePhase {
TestDay, TestDay,
@ -56,6 +62,7 @@ pub struct RFactorData {
telemetry_reader: TelemetryReader, telemetry_reader: TelemetryReader,
scoring_reader: ScoringReader, scoring_reader: ScoringReader,
last_scoring_read: Duration,
start_time: Instant, start_time: Instant,
player_id: Option<i32>, player_id: Option<i32>,
previous_game_phase: GamePhase, previous_game_phase: GamePhase,
@ -73,6 +80,7 @@ impl RFactorData {
telemetry_reader: TelemetryReader::new(start_time.elapsed().as_secs_f32())?, telemetry_reader: TelemetryReader::new(start_time.elapsed().as_secs_f32())?,
scoring_reader: ScoringReader::new(start_time.elapsed().as_secs_f32())?, scoring_reader: ScoringReader::new(start_time.elapsed().as_secs_f32())?,
last_scoring_read: start_time.elapsed(),
start_time, start_time,
player_id: None, player_id: None,
previous_game_phase: GamePhase::None, previous_game_phase: GamePhase::None,
@ -93,48 +101,65 @@ impl RFactorData {
write_log!(" =================== update RFactorData ==================="); write_log!(" =================== update RFactorData ===================");
// get scoring info // get scoring info
if let Some((scoring_info, vehicle_scorings)) = match self.scoring_reader.vehicle_scoring(self.now()) {
self.scoring_reader.vehicle_scoring(self.now()) Some((scoring_info, vehicle_scorings)) => {
{ self.last_scoring_read = self.start_time.elapsed();
write_log!(format!(
"new scoring info: vehicles: {}",
scoring_info.mNumVehicles
));
// check for player id write_log!(format!(
if scoring_info.mNumVehicles == 0 { "new scoring info: vehicles: {}",
self.player_id = None; scoring_info.mNumVehicles
} else if self.player_id.is_none() { ));
for vehicle_scoring in vehicle_scorings.iter() {
if vehicle_scoring.mIsPlayer != 0 {
write_log!(format!("player found: {}", vehicle_scoring.mID));
self.player_id = Some(vehicle_scoring.mID);
break;
}
}
}
{ // check for player id
let phase = GamePhase::try_from(scoring_info.mSession)?; if scoring_info.mNumVehicles == 0 {
self.player_id = None;
if self.previous_game_phase != phase { } else if self.player_id.is_none() {
self.previous_game_phase = phase; for vehicle_scoring in vehicle_scorings.iter() {
if vehicle_scoring.mIsPlayer != 0 {
for receiver in self.receivers.iter() { write_log!(format!("player found: {}", vehicle_scoring.mID));
receiver self.player_id = Some(vehicle_scoring.mID);
.borrow_mut() break;
.game_phase_change(self.previous_game_phase)?; }
} }
} }
write_log!(format!("GamePhase: {:?}", self.previous_game_phase)); {
let phase = GamePhase::try_from(scoring_info.mSession)?;
if self.previous_game_phase != phase {
self.previous_game_phase = phase;
for receiver in self.receivers.iter() {
receiver
.borrow_mut()
.game_phase_change(self.previous_game_phase)?;
}
}
write_log!(format!("GamePhase: {:?}", self.previous_game_phase));
}
for receiver in self.receivers.iter() {
let mut rec_mut = receiver.borrow_mut();
if rec_mut.update_for_phase(self.previous_game_phase) {
rec_mut.scoring_update(self.previous_game_phase, &vehicle_scorings)?;
}
}
} }
None => {
let now = self.start_time.elapsed();
for receiver in self.receivers.iter() { if now > (self.last_scoring_read + GAME_PHASE_TIME_OUT) {
let mut rec_mut = receiver.borrow_mut(); if self.previous_game_phase != GamePhase::None {
self.previous_game_phase = GamePhase::None;
if rec_mut.update_for_phase(self.previous_game_phase) { for receiver in self.receivers.iter() {
rec_mut.scoring_update(self.previous_game_phase, &vehicle_scorings)?; receiver
.borrow_mut()
.game_phase_change(self.previous_game_phase)?;
}
}
} }
} }
} }