osui::extensions::tick
The tick
module provides the TickExtension
and TickEvent
, enabling applications to receive periodic updates at a defined rate. This is useful for animations, game loops, or any time-based logic.
TickEvent
(Event)
event!(TickEvent(pub u32));
A custom event type dispatched by the TickExtension
. It contains a u32
value representing the current tick count since the extension started.
Fields:
0
:u32
- The current tick count.
Example:
use osui::prelude::*;
// Listen for TickEvent
rsx! {
@Handler::new(|_, e: &TickEvent| {
println!("Tick: {}", e.0);
});
Div { "Listening for ticks" }
}
TickExtension
Dispatches TickEvent
s at a configurable interval.
pub struct TickExtension(pub u16);
Fields:
0
:u16
- The desired ticks per second (Hz). For example,TickExtension(30)
would dispatch aTickEvent
approximately every 33 milliseconds (1000ms / 30Hz).
Extension
Trait Implementation
init(&mut self, ctx: &Context)
Called when the TickExtension
is registered with the Screen
.
- Calculates the
rate_dur
(duration per tick) in milliseconds:1000 / self.0 as u64
. - Spawns a new thread.
- In this new thread, it enters an infinite loop:
- It dispatches a
TickEvent
with the current tick count usingctx.event(&TickEvent(tick))
. - The
tick
counter is incremented. - The thread sleeps for the calculated
rate_dur
.
- It dispatches a
Why a separate thread?
Similar to InputExtension
, TickExtension
spawns a separate thread because std::thread::sleep
is a blocking operation. This ensures that the main rendering loop continues to run smoothly, independent of the tick rate.
Usage
To use TickExtension
, you simply need to create an instance with your desired tick rate and register it with the Screen
. Then, your widgets or other extensions can listen for TickEvent
s using Handler<TickEvent>
.
Example:
use osui::prelude::*;
use std::{thread, time::Duration};
fn main() -> std::io::Result<()> {
let screen = Screen::new();
// Register essential extensions
screen.extension(InputExtension);
screen.extension(RelativeFocusExtension::new());
// Register TickExtension for 30 ticks per second
screen.extension(TickExtension(30));
// Create a state to display the tick count
let tick_count_state = use_state(0u32);
rsx! {
// Attach a Handler to update the state on each TickEvent
@Handler::new({
let state_clone = tick_count_state.clone();
move |_, e: &TickEvent| {
state_clone.set(e.0); // Update the state with the current tick count
}
});
// Display the reactive tick count
%tick_count_state
Div {
format!("Current Tick: {}", tick_count_state.get())
}
}
.draw(&screen);
screen.run()
}
This example demonstrates how TickExtension
provides a consistent timing mechanism, allowing you to build dynamic and animated UIs.