From 6703f1c56605ca7dca8f7fe87b79badb764bd461 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 18 Jan 2025 00:57:22 +0100 Subject: profiler interface --- client/src/download.rs | 21 +++++++++++ client/src/interfaces/mod.rs | 70 ++++++++++++++++++++++++++++++++++++ client/src/interfaces/prefabindex.rs | 44 +++++++++++++++++++++++ client/src/interfaces/profiler.rs | 33 +++++++++++++++++ client/src/main.rs | 1 + client/src/scene_prepare.rs | 35 ++++++++++++++++++ client/src/state.rs | 35 +++++++----------- client/src/ui.rs | 8 ++--- 8 files changed, 221 insertions(+), 26 deletions(-) create mode 100644 client/src/interfaces/mod.rs create mode 100644 client/src/interfaces/prefabindex.rs create mode 100644 client/src/interfaces/profiler.rs (limited to 'client/src') diff --git a/client/src/download.rs b/client/src/download.rs index bcdd80e..4e2f0aa 100644 --- a/client/src/download.rs +++ b/client/src/download.rs @@ -16,6 +16,7 @@ */ use crate::network::Network; use anyhow::Result; +use egui::{Grid, Widget}; use log::debug; use std::{collections::HashSet, marker::PhantomData, sync::RwLock}; use weareshared::{ @@ -100,3 +101,23 @@ impl Downloader { Ok(()) } } + +impl Widget for &Downloader { + fn ui(self, ui: &mut egui::Ui) -> egui::Response { + let state = self.inner.read().unwrap(); + Grid::new("dl") + .num_columns(2) + .show(ui, |ui| { + ui.label("Need"); + ui.label(state.need.len().to_string()); + ui.end_row(); + ui.label("Pending"); + ui.label(state.pending.len().to_string()); + ui.end_row(); + ui.label("Have"); + ui.label(state.have.len().to_string()); + ui.end_row(); + }) + .response + } +} diff --git a/client/src/interfaces/mod.rs b/client/src/interfaces/mod.rs new file mode 100644 index 0000000..09db60f --- /dev/null +++ b/client/src/interfaces/mod.rs @@ -0,0 +1,70 @@ +/* + wearechat - generic multiplayer game with voip + Copyright (C) 2025 metamuffin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +pub mod prefabindex; +pub mod profiler; + +use crate::{download::Downloader, network::Network, scene_prepare::ScenePreparer}; +use egui::Widget; +use prefabindex::PrefabIndexInterface; +use profiler::Profiler; +use std::sync::{Arc, Mutex}; +use weareshared::resources::PrefabIndex; + +enum Interface { + Selector, + Profiler(Profiler), + PrefabIndex(PrefabIndexInterface), +} + +pub struct InterfaceData { + pub scene_prepare: Arc, + pub network: Arc, + pub downloader: Arc, + pub prefab_index: Arc, +} + +pub fn ui_selector(idata: Arc) -> impl Fn(&egui::Context) -> bool { + let state = Mutex::new(Interface::Selector); + move |ctx| { + let mut open = true; + let mut state = state.lock().unwrap(); + egui::Window::new(match &*state { + Interface::Selector => "Select Interface", + Interface::Profiler(_) => "Profiler", + Interface::PrefabIndex(_) => "Prefab Index", + }) + .open(&mut open) + .show(ctx, |ui| match &mut *state { + Interface::Selector => { + if ui.button("Profiler").clicked() { + *state = Interface::Profiler(Profiler { + idata: idata.clone(), + }) + } + if ui.button("Prefab Index").clicked() { + *state = Interface::PrefabIndex(PrefabIndexInterface { + idata: idata.clone(), + }) + } + ui.response() + } + Interface::Profiler(profiler) => profiler.ui(ui), + Interface::PrefabIndex(prefab_index_interface) => prefab_index_interface.ui(ui), + }); + open + } +} diff --git a/client/src/interfaces/prefabindex.rs b/client/src/interfaces/prefabindex.rs new file mode 100644 index 0000000..6f3611b --- /dev/null +++ b/client/src/interfaces/prefabindex.rs @@ -0,0 +1,44 @@ +/* + wearechat - generic multiplayer game with voip + Copyright (C) 2025 metamuffin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +use super::InterfaceData; +use egui::Widget; +use log::info; +use std::sync::Arc; +use weareshared::packets::{Object, Packet}; + +pub struct PrefabIndexInterface { + pub idata: Arc, +} + +impl Widget for &mut PrefabIndexInterface { + fn ui(self, ui: &mut egui::Ui) -> egui::Response { + for (key, res) in &self.idata.prefab_index.0 { + ui.horizontal(|ui| { + ui.label(key); + if ui.button("Add").clicked() { + info!("spawn {res}"); + self.idata + .network + .packet_send + .send(Packet::Add(Object::new(), res.clone())) + .unwrap(); + } + }); + } + ui.response() + } +} diff --git a/client/src/interfaces/profiler.rs b/client/src/interfaces/profiler.rs new file mode 100644 index 0000000..5c8737b --- /dev/null +++ b/client/src/interfaces/profiler.rs @@ -0,0 +1,33 @@ +/* + wearechat - generic multiplayer game with voip + Copyright (C) 2025 metamuffin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +use super::InterfaceData; +use egui::Widget; +use std::sync::Arc; + +pub struct Profiler { + pub idata: Arc, +} + +impl Widget for &mut Profiler { + fn ui(self, ui: &mut egui::Ui) -> egui::Response { + ui.heading("Scene"); + ui.add(&*self.idata.scene_prepare); + ui.heading("Download"); + ui.add(&*self.idata.downloader); + ui.response() + } +} diff --git a/client/src/main.rs b/client/src/main.rs index bfd7d10..a1213d1 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -28,6 +28,7 @@ pub mod state; pub mod ui; pub mod window; pub mod audio; +pub mod interfaces; use anyhow::Result; use clap::Parser; diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs index d26ed1c..cee55f7 100644 --- a/client/src/scene_prepare.rs +++ b/client/src/scene_prepare.rs @@ -16,6 +16,7 @@ */ use crate::download::Downloader; use anyhow::Result; +use egui::{Grid, Widget}; use image::ImageReader; use log::debug; use std::{ @@ -354,3 +355,37 @@ fn create_texture( }); (Arc::new(texture), Arc::new(bindgroup)) } + +impl Widget for &DemandMap { + fn ui(self, ui: &mut egui::Ui) -> egui::Response { + let state = self.inner.read().unwrap(); + ui.label(state.needed.len().to_string()); + ui.label(state.values.len().to_string()); + ui.end_row(); + ui.response() + } +} + +impl Widget for &ScenePreparer { + fn ui(self, ui: &mut egui::Ui) -> egui::Response { + Grid::new("sp") + .num_columns(3) + .show(ui, |ui| { + ui.label("prefabs"); + self.prefabs.ui(ui); + ui.label("mesh_parts"); + self.mesh_parts.ui(ui); + ui.label("vertex_buffers"); + self.vertex_buffers.ui(ui); + ui.label("index_buffers"); + self.index_buffers.ui(ui); + ui.label("placeholder_textures"); + self.placeholder_textures.ui(ui); + ui.label("placeholder_vertex_buffers"); + self.placeholder_vertex_buffers.ui(ui); + ui.label("textures"); + self.textures.ui(ui); + }) + .response + } +} diff --git a/client/src/state.rs b/client/src/state.rs index 60be957..439b7ca 100644 --- a/client/src/state.rs +++ b/client/src/state.rs @@ -15,7 +15,12 @@ along with this program. If not, see . */ use crate::{ - audio::Audio, camera::Camera, download::Downloader, network::Network, renderer::Renderer, + audio::Audio, + camera::Camera, + download::Downloader, + interfaces::{InterfaceData, ui_selector}, + network::Network, + renderer::Renderer, ui::UiEvent, }; use anyhow::{Context, Result}; @@ -98,29 +103,15 @@ impl<'a> State<'a> { if !down || button != MouseButton::Right { return; } - let pi = self.prefab_index.clone(); - let net = self.network.clone(); + let idata = Arc::new(InterfaceData { + scene_prepare: self.renderer.scene_prepare.clone(), + downloader: self.downloader.clone(), + network: self.network.clone(), + prefab_index: self.prefab_index.clone(), + }); self.renderer .ui_renderer - .add_surface(self.camera.new_ui_affine(), move |ctx| { - let mut open = true; - egui::Window::new("Prefab Index") - .open(&mut open) - .show(ctx, |ui| { - for (key, res) in &pi.0 { - ui.horizontal(|ui| { - ui.label(key); - if ui.button("Add").clicked() { - info!("spawn {res}"); - net.packet_send - .send(Packet::Add(Object::new(), res.clone())) - .unwrap(); - } - }); - } - }); - open - }); + .add_surface(self.camera.new_ui_affine(), ui_selector(idata)); } pub fn update(&mut self) -> Result<()> { let now = Instant::now(); diff --git a/client/src/ui.rs b/client/src/ui.rs index c477d07..6f41ea6 100644 --- a/client/src/ui.rs +++ b/client/src/ui.rs @@ -427,28 +427,28 @@ impl UiRenderer { while index_count > surf.index_capacity { info!( - "index buffer overflow. expanding {} -> {}", + "index buffer overflow ({index_count}). expanding {} -> {}", surf.index_capacity, surf.index_capacity * 2 ); surf.index_capacity *= 2; surf.index = self.device.create_buffer(&BufferDescriptor { label: None, - size: (size_of::() * surf.index_capacity) as u64, + size: (size_of::() * surf.index_capacity) as u64, usage: BufferUsages::INDEX | BufferUsages::COPY_DST, mapped_at_creation: false, }); } while vertex_count > surf.vertex_capacity { info!( - "vertex buffer overflow. expanding {} -> {}", + "vertex buffer overflow ({vertex_count}). expanding {} -> {}", surf.vertex_capacity, surf.vertex_capacity * 2 ); surf.vertex_capacity *= 2; surf.vertex = self.device.create_buffer(&BufferDescriptor { label: None, - size: (size_of::() * surf.vertex_capacity) as u64, + size: (size_of::() * surf.vertex_capacity) as u64, usage: BufferUsages::VERTEX | BufferUsages::COPY_DST, mapped_at_creation: false, }); -- cgit v1.2.3-70-g09d2