Skip to content

Commit

Permalink
Code improvements and less audio interface querying (#140)
Browse files Browse the repository at this point in the history
* move network stats to a better place

* remove `GuiComponent::prepare`
  • Loading branch information
tedsteen authored Jan 13, 2025
1 parent 2556e0c commit f5d6658
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 105 deletions.
9 changes: 0 additions & 9 deletions src/audio/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,6 @@ impl AudioGui {
// }

impl GuiComponent for AudioGui {
fn prepare(&mut self) {
// #[cfg(feature = "debug")]
// if let Some(tx) = &instance.stream.tx {
// self.stats.push_stat(AudioStat::new(tx.len()));
// }

self.audio.sync_audio_devices();
}

fn ui(&mut self, ui: &mut Ui) {
// #[cfg(feature = "debug")]
// Self::stats_ui(ui, &self.stats);
Expand Down
9 changes: 4 additions & 5 deletions src/audio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,16 @@ impl Audio {
}

pub fn sync_audio_devices(&mut self) {
let available_device_names =
Self::get_available_output_device_names_for_subsystem(&self.audio_subsystem);
if self.next_device_names_clear < Instant::now() {
self.next_device_names_clear = Instant::now().add(Duration::new(1, 0));
self.available_device_names
.clone_from(&available_device_names);
self.available_device_names.clone_from(
&Self::get_available_output_device_names_for_subsystem(&self.audio_subsystem),
);
}

let selected_device = &mut Settings::current_mut().audio.output_device;
if let Some(name) = selected_device {
if !available_device_names.contains(name) {
if !self.available_device_names.contains(name) {
*selected_device = None;
}
}
Expand Down
7 changes: 0 additions & 7 deletions src/emulation/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ impl GuiComponent for EmulatorGui {

#[cfg(feature = "netplay")]
fn messages(&self) -> Option<Vec<String>> {
#[cfg(feature = "debug")]
puffin::profile_function!();
self.netplay_gui.messages(&self.nes_state.lock().unwrap())
}

Expand All @@ -96,9 +94,4 @@ impl GuiComponent for EmulatorGui {

None
}

#[cfg(all(feature = "netplay", feature = "debug"))]
fn prepare(&mut self) {
self.netplay_gui.prepare(&self.nes_state.lock().unwrap());
}
}
4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ impl ApplicationHandler for Application {
}
}

fn about_to_wait(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) {
self.audio_gui.audio.sync_audio_devices();
}

fn window_event(
&mut self,
event_loop: &winit::event_loop::ActiveEventLoop,
Expand Down
16 changes: 1 addition & 15 deletions src/main_view/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ pub enum GuiEvent {
}

pub trait GuiComponent {
// Runs every frame
fn prepare(&mut self) {}

// Runs if gui is visible
// Runs when gui is visible
fn ui(&mut self, _ui: &mut Ui) {}

fn messages(&self) -> Option<Vec<String>> {
Expand Down Expand Up @@ -251,8 +248,6 @@ impl MainGui {
}
}
{
#[cfg(feature = "debug")]
puffin::profile_scope!("Messages");
egui::TopBottomPanel::top("messages")
.show_separator_line(false)
.frame(
Expand All @@ -266,17 +261,8 @@ impl MainGui {
let gui_components: &mut [&mut dyn GuiComponent] =
&mut [audio_gui, inputs_gui, emulator_gui];
for gui in gui_components.iter_mut() {
{
#[cfg(feature = "debug")]
puffin::profile_scope!(format!("Prepare {:?}", gui.name()));

gui.prepare();
}
if gui.name().is_some() {
{
#[cfg(feature = "debug")]
puffin::profile_scope!(format!("Messages {:?}", gui.name()));

if let Some(messages) = gui.messages() {
for message in messages {
Self::message_ui(ui, message);
Expand Down
66 changes: 6 additions & 60 deletions src/netplay/gui/debug.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,12 @@
use std::{
collections::VecDeque,
time::{Duration, Instant},
};

use ggrs::NetworkStats;

use crate::{
netplay::{netplay_state::NetplayState, NetplayStateHandler},
settings::MAX_PLAYERS,
};

pub struct NetplayStat {
pub stat: NetworkStats,
pub duration: Duration,
}
pub const STATS_HISTORY: usize = 100;

pub struct NetplayStats {
stats: VecDeque<NetplayStat>,
start_time: Instant,
}

impl NetplayStats {
pub fn new() -> Self {
Self {
start_time: Instant::now(),
stats: VecDeque::with_capacity(STATS_HISTORY),
}
}

pub fn get_ping(&self) -> &VecDeque<NetplayStat> {
&self.stats
}

pub fn push_stats(&mut self, stat: NetworkStats) {
let duration = Instant::now().duration_since(self.start_time);
self.stats.push_back(NetplayStat { duration, stat });
if self.stats.len() == STATS_HISTORY {
self.stats.pop_front();
}
}
}
use super::NetplayGui;

impl NetplayGui {
pub fn prepare(&mut self, netplay_state_handler: &NetplayStateHandler) {
puffin::profile_function!();

if let Some(NetplayState::Connected(netplay)) = &netplay_state_handler.netplay {
let sess = &netplay.state.netplay_session.p2p_session;
if netplay.state.netplay_session.game_state.frame % 30 == 0 {
for i in 0..MAX_PLAYERS {
if let Ok(stats) = sess.network_stats(i) {
if !sess.local_player_handles().contains(&i) {
self.stats[i].push_stats(stats);
}
}
}
};
}
}
pub(crate) fn stats_ui(ui: &mut egui::Ui, stats: &NetplayStats, player: usize) {
#[cfg(feature = "debug")]
pub(crate) fn stats_ui(
ui: &mut egui::Ui,
stats: &crate::netplay::stats::NetplayStats,
player: usize,
) {
if !stats.get_ping().is_empty() {
ui.label(format!("Player {player}"));
use egui_plot::{Line, Plot};
Expand Down
11 changes: 2 additions & 9 deletions src/netplay/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,13 @@ impl Default for NetplayVoca {
}

pub struct NetplayGui {
#[cfg(feature = "debug")]
pub stats: [debug::NetplayStats; crate::settings::MAX_PLAYERS],
room_name: Option<String>,
last_screen: Option<&'static str>,
}

impl NetplayGui {
pub fn new() -> Self {
Self {
#[cfg(feature = "debug")]
stats: [debug::NetplayStats::new(), debug::NetplayStats::new()],
room_name: None,
last_screen: None,
}
Expand Down Expand Up @@ -76,9 +72,6 @@ impl NetplayGui {
None
}
pub fn messages(&self, netplay_state_handler: &NetplayStateHandler) -> Option<Vec<String>> {
#[cfg(feature = "debug")]
puffin::profile_function!();

if matches!(MainGui::main_menu_state(), MainMenuState::Netplay) {
// No need to show messages when the netplay menu is already showing status
return None;
Expand Down Expand Up @@ -460,8 +453,8 @@ impl NetplayGui {
{
ui.vertical_centered(|ui| {
ui.collapsing("Stats", |ui| {
Self::stats_ui(ui, &self.stats[0], 0);
Self::stats_ui(ui, &self.stats[1], 1);
Self::stats_ui(ui, &netplay_connected.state.stats[0], 0);
Self::stats_ui(ui, &netplay_connected.state.stats[1], 1);
});
if ui.button("Fake connection lost").clicked() {
action = Some(Action::FakeDisconnect);
Expand Down
18 changes: 18 additions & 0 deletions src/netplay/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub mod gui;
mod netplay_session;
mod netplay_state;

#[cfg(feature = "debug")]
mod stats;

#[derive(Clone, Debug)]
pub enum JoypadMapping {
P1,
Expand Down Expand Up @@ -91,6 +94,21 @@ impl DerefMut for NetplayNesState {

impl NesStateHandler for NetplayStateHandler {
fn advance(&mut self, joypad_state: [JoypadState; MAX_PLAYERS], buffers: &mut NESBuffers) {
#[cfg(feature = "debug")]
if let Some(NetplayState::Connected(netplay)) = &mut self.netplay {
let sess = &netplay.state.netplay_session.p2p_session;
if netplay.state.netplay_session.game_state.frame % 30 == 0 {
puffin::profile_scope!("Netplay stats");
for i in 0..MAX_PLAYERS {
if let Ok(stats) = sess.network_stats(i) {
if !sess.local_player_handles().contains(&i) {
netplay.state.stats[i].push_stats(stats);
}
}
}
};
}

if let Some(new_state) = self
.netplay
.take()
Expand Down
7 changes: 7 additions & 0 deletions src/netplay/netplay_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ pub struct ConnectedState {
pub netplay_session: NetplaySessionState,
session_id: String,
pub start_time: Instant,
#[cfg(feature = "debug")]
pub stats: [crate::netplay::stats::NetplayStats; crate::settings::MAX_PLAYERS],
}

pub struct ResumingState {
Expand Down Expand Up @@ -211,6 +213,11 @@ impl Netplay<ConnectingState> {
}
},
netplay_session: connected,
#[cfg(feature = "debug")]
stats: [
crate::netplay::stats::NetplayStats::new(),
crate::netplay::stats::NetplayStats::new(),
],
},
})
}
Expand Down
38 changes: 38 additions & 0 deletions src/netplay/stats.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::{
collections::VecDeque,
time::{Duration, Instant},
};

use ggrs::NetworkStats;

pub struct NetplayStat {
pub stat: NetworkStats,
pub duration: Duration,
}
pub const STATS_HISTORY: usize = 100;

pub struct NetplayStats {
stats: VecDeque<NetplayStat>,
start_time: Instant,
}

impl NetplayStats {
pub fn new() -> Self {
Self {
start_time: Instant::now(),
stats: VecDeque::with_capacity(STATS_HISTORY),
}
}

pub fn get_ping(&self) -> &VecDeque<NetplayStat> {
&self.stats
}

pub fn push_stats(&mut self, stat: NetworkStats) {
let duration = Instant::now().duration_since(self.start_time);
self.stats.push_back(NetplayStat { duration, stat });
if self.stats.len() == STATS_HISTORY {
self.stats.pop_front();
}
}
}

0 comments on commit f5d6658

Please # to comment.