diff --git a/dash-frontend/src/frontend.rs b/dash-frontend/src/frontend.rs index 0b4ee7c..befd7cb 100644 --- a/dash-frontend/src/frontend.rs +++ b/dash-frontend/src/frontend.rs @@ -125,8 +125,7 @@ impl Frontend { let id_label_time = state.get_widget_id("label_time")?; let id_rect_content = state.get_widget_id("rect_content")?; - let mut timestep = Timestep::new(); - timestep.set_tps(30.0); // 30 ticks per second + let timestep = Timestep::new(60.0); let mut frontend = Self { layout, diff --git a/dash-frontend/src/util/toast_manager.rs b/dash-frontend/src/util/toast_manager.rs index 692047f..b2c0f03 100644 --- a/dash-frontend/src/util/toast_manager.rs +++ b/dash-frontend/src/util/toast_manager.rs @@ -47,7 +47,7 @@ impl Drop for MountedToast { } } -const TOAST_DURATION_TICKS: u32 = 90; +const TOAST_DURATION_TICKS: u32 = 150; impl ToastManager { pub fn new() -> Self { @@ -130,7 +130,7 @@ impl ToastManager { // show-up animation layout.animations.add(Animation::new( rect.id, - (120.0 * globals.defaults.animation_mult) as u32, + (TOAST_DURATION_TICKS as f32 * globals.defaults.animation_mult) as u32, AnimationEasing::Linear, Box::new(move |common, data| { let pos_showup = AnimationEasing::OutQuint.interpolate((data.pos * 4.0).min(1.0)); diff --git a/uidev/src/main.rs b/uidev/src/main.rs index 04dcbbf..ba3b1a5 100644 --- a/uidev/src/main.rs +++ b/uidev/src/main.rs @@ -1,7 +1,6 @@ use glam::{Vec2, vec2}; use std::sync::Arc; use testbed::{Testbed, testbed_any::TestbedAny}; -use timestep::Timestep; use tracing_subscriber::EnvFilter; use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::layer::SubscriberExt; @@ -28,6 +27,7 @@ use winit::{ event_loop::ControlFlow, keyboard::{KeyCode, PhysicalKey}, }; +use wlx_common::timestep::Timestep; use crate::{ rate_limiter::RateLimiter, @@ -40,7 +40,6 @@ mod assets; mod profiler; mod rate_limiter; mod testbed; -mod timestep; mod vulkan; fn init_logging() { @@ -114,8 +113,7 @@ fn main() -> Result<(), Box> { let mut profiler = profiler::Profiler::new(1000); let mut frame_index: u64 = 0; - let mut timestep = Timestep::new(); - timestep.set_tps(60.0); + let mut timestep = Timestep::new(60.0); let mut limiter = RateLimiter::new(); diff --git a/uidev/src/profiler.rs b/uidev/src/profiler.rs index f450310..23c183b 100644 --- a/uidev/src/profiler.rs +++ b/uidev/src/profiler.rs @@ -1,4 +1,4 @@ -use crate::timestep::get_micros; +use wlx_common::timestep::get_micros; pub struct Profiler { interval_us: u64, diff --git a/uidev/src/rate_limiter.rs b/uidev/src/rate_limiter.rs index 4ad3186..d8d990c 100644 --- a/uidev/src/rate_limiter.rs +++ b/uidev/src/rate_limiter.rs @@ -1,4 +1,4 @@ -use crate::timestep::get_micros; +use wlx_common::timestep::get_micros; #[derive(Default)] pub struct RateLimiter { diff --git a/uidev/src/timestep.rs b/uidev/src/timestep.rs deleted file mode 100644 index e0e1101..0000000 --- a/uidev/src/timestep.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::{sync::LazyLock, time::Instant}; -static TIME_START: LazyLock = LazyLock::new(Instant::now); - -pub fn get_micros() -> u64 { - TIME_START.elapsed().as_micros() as u64 -} - -#[derive(Default)] -pub struct Timestep { - current_time_us: u64, - accumulator: f32, - time_micros: u64, - ticks: u32, - speed: f32, - pub alpha: f32, - delta: f32, - loopnum: u8, -} - -impl Timestep { - pub fn new() -> Timestep { - let mut timestep = Timestep { - speed: 1.0, - ..Default::default() - }; - - timestep.reset(); - timestep - } - - fn calculate_alpha(&mut self) { - self.alpha = (self.accumulator / self.delta).clamp(0.0, 1.0); - } - - pub fn set_tps(&mut self, tps: f32) { - self.delta = 1000.0 / tps; - } - - pub fn reset(&mut self) { - self.current_time_us = get_micros(); - self.accumulator = 0.0; - } - - pub fn on_tick(&mut self) -> bool { - let newtime = get_micros(); - let frametime = newtime - self.current_time_us; - self.time_micros += frametime; - self.current_time_us = newtime; - self.accumulator += frametime as f32 * self.speed / 1000.0; - self.calculate_alpha(); - - if self.accumulator >= self.delta { - self.accumulator -= self.delta; - self.loopnum += 1; - self.ticks += 1; - - if self.loopnum > 5 { - // cannot keep up! - self.loopnum = 0; - self.accumulator = 0.0; - return false; - } - - true - } else { - self.loopnum = 0; - false - } - } -} diff --git a/wgui/src/components/slider.rs b/wgui/src/components/slider.rs index 229680e..0a5c4ee 100644 --- a/wgui/src/components/slider.rs +++ b/wgui/src/components/slider.rs @@ -18,11 +18,11 @@ use crate::{ util, }, widget::{ + ConstructEssentials, EventResult, div::WidgetDiv, label::{WidgetLabel, WidgetLabelParams}, rectangle::{WidgetRectangle, WidgetRectangleParams}, util::WLength, - ConstructEssentials, EventResult, }, }; @@ -224,7 +224,7 @@ impl State { return; // nothing changed visually } - common.alterables.mark_dirty(data.slider_handle_node_id); + common.alterables.mark_dirty(data.slider_handle_id); common.alterables.mark_redraw(); if let Some(slider_text_id) = data.slider_text_id diff --git a/wgui/src/event.rs b/wgui/src/event.rs index 619221d..83d8725 100644 --- a/wgui/src/event.rs +++ b/wgui/src/event.rs @@ -104,7 +104,7 @@ pub enum StyleSetRequest { // alterables which will be dispatched in the next loop iteration phase #[derive(Default)] pub struct EventAlterables { - pub dirty_nodes: Vec, + pub dirty_widgets: Vec, pub style_set_requests: Vec<(WidgetID, StyleSetRequest)>, pub animations: Vec, pub widgets_to_tick: HashSet, // widgets which needs to be ticked in the next `Layout::update()` fn @@ -125,8 +125,8 @@ impl EventAlterables { self.style_set_requests.push((widget_id, request)); } - pub fn mark_dirty(&mut self, node_id: taffy::NodeId) { - self.dirty_nodes.push(node_id); + pub fn mark_dirty(&mut self, widget_id: WidgetID) { + self.dirty_widgets.push(widget_id); } pub fn mark_tick(&mut self, widget_id: WidgetID) { @@ -154,9 +154,7 @@ impl CallbackDataCommon<'_> { // helper function pub fn mark_widget_dirty(&mut self, id: WidgetID) { - if let Some(node_id) = self.state.nodes.get(id) { - self.alterables.mark_dirty(*node_id); - } + self.alterables.mark_dirty(id); self.alterables.mark_redraw(); } } diff --git a/wgui/src/layout.rs b/wgui/src/layout.rs index af61062..2fbf5af 100644 --- a/wgui/src/layout.rs +++ b/wgui/src/layout.rs @@ -683,8 +683,10 @@ impl Layout { self.process_tasks()?; - for node in alterables.dirty_nodes { - self.state.tree.mark_dirty(node)?; + for dirty_widget_id in alterables.dirty_widgets { + if let Some(dirty_node_id) = self.state.nodes.get(dirty_widget_id) { + self.state.tree.mark_dirty(*dirty_node_id)?; + } } if alterables.needs_redraw { diff --git a/wlx-common/src/timestep.rs b/wlx-common/src/timestep.rs index be31516..9ef8b82 100644 --- a/wlx-common/src/timestep.rs +++ b/wlx-common/src/timestep.rs @@ -18,13 +18,14 @@ pub struct Timestep { } impl Timestep { - pub fn new() -> Self { + pub fn new(ticks_per_second: f32) -> Self { let mut timestep = Self { speed: 1.0, ..Default::default() }; timestep.reset(); + timestep.set_tps(ticks_per_second); timestep } diff --git a/wlx-overlay-s/src/gui/panel/mod.rs b/wlx-overlay-s/src/gui/panel/mod.rs index a43665a..1467312 100644 --- a/wlx-overlay-s/src/gui/panel/mod.rs +++ b/wlx-overlay-s/src/gui/panel/mod.rs @@ -160,8 +160,7 @@ impl GuiPanel { } let context = WguiContext::new(&mut app.wgui_shared, 1.0)?; - let mut timestep = Timestep::new(); - timestep.set_tps(60.0); + let timestep = Timestep::new(60.0); Ok(Self { layout, @@ -192,8 +191,7 @@ impl GuiPanel { }, )?; let context = WguiContext::new(&mut app.wgui_shared, 1.0)?; - let mut timestep = Timestep::new(); - timestep.set_tps(60.0); + let timestep = Timestep::new(60.0); Ok(Self { layout, diff --git a/wlx-overlay-s/src/overlays/dashboard.rs b/wlx-overlay-s/src/overlays/dashboard.rs index 0e4a54c..19da5b4 100644 --- a/wlx-overlay-s/src/overlays/dashboard.rs +++ b/wlx-overlay-s/src/overlays/dashboard.rs @@ -37,7 +37,7 @@ use crate::{ pub const DASH_NAME: &str = "Dashboard"; -const DASH_RES_U32A: [u32; 2] = [1280, 720]; +const DASH_RES_U32A: [u32; 2] = [1920, 1080]; const DASH_RES_VEC2: Vec2 = vec2(DASH_RES_U32A[0] as _, DASH_RES_U32A[1] as _); //FIXME: replace with proper impl @@ -86,6 +86,8 @@ pub struct DashFrontend { context: WguiContext, } +const GUI_SCALE: f32 = 2.0; + impl DashFrontend { fn new(app: &mut AppState) -> anyhow::Result { let settings = SimpleSettingsIO::new(); @@ -100,15 +102,18 @@ impl DashFrontend { inner: frontend, initialized: false, interaction_transform: None, - timestep: Timestep::new(), + timestep: Timestep::new(60.0), has_focus: [false, false], context, }) } - fn update(&mut self) -> anyhow::Result<()> { - log::info!("update layout"); - self.inner.update(DASH_RES_VEC2.x, DASH_RES_VEC2.y, 0.0) + fn update(&mut self, timestep_alpha: f32) -> anyhow::Result<()> { + self.inner.update( + DASH_RES_VEC2.x / GUI_SCALE, + DASH_RES_VEC2.y / GUI_SCALE, + timestep_alpha, + ) } fn push_event(&mut self, event: &WguiEvent) -> EventResult { @@ -125,11 +130,11 @@ impl DashFrontend { impl OverlayBackend for DashFrontend { fn init(&mut self, app: &mut AppState) -> anyhow::Result<()> { self.context - .update_viewport(&mut app.wgui_shared, DASH_RES_U32A, 1.0)?; + .update_viewport(&mut app.wgui_shared, DASH_RES_U32A, GUI_SCALE)?; self.interaction_transform = Some(ui_transform(DASH_RES_U32A)); if self.inner.layout.content_size.x * self.inner.layout.content_size.y != 0.0 { - self.update()?; + self.update(0.0)?; self.initialized = true; } Ok(()) @@ -150,6 +155,10 @@ impl OverlayBackend for DashFrontend { self.inner.layout.tick()?; } + if let Err(e) = self.update(self.timestep.alpha) { + log::error!("uncaught exception: {e:?}"); + } + Ok(if self.inner.layout.check_toggle_needs_redraw() { ShouldRender::Should } else { @@ -158,14 +167,6 @@ impl OverlayBackend for DashFrontend { } fn render(&mut self, app: &mut AppState, rdr: &mut RenderResources) -> anyhow::Result<()> { - self.inner - .layout - .update(DASH_RES_VEC2, self.timestep.alpha)?; - - if let Err(e) = self.update() { - log::error!("uncaught exception: {e:?}"); - } - let globals = self.inner.layout.state.globals.clone(); // sorry let mut globals = globals.get();