Skip to main content
Version: 0.1.1

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 TickEvents at a configurable interval.

pub struct TickExtension(pub u16);

Fields:

  • 0: u16 - The desired ticks per second (Hz). For example, TickExtension(30) would dispatch a TickEvent approximately every 33 milliseconds (1000ms / 30Hz).

Extension Trait Implementation

init(&mut self, ctx: &Context)

Called when the TickExtension is registered with the Screen.

  1. Calculates the rate_dur (duration per tick) in milliseconds: 1000 / self.0 as u64.
  2. Spawns a new thread.
  3. In this new thread, it enters an infinite loop:
    • It dispatches a TickEvent with the current tick count using ctx.event(&TickEvent(tick)).
    • The tick counter is incremented.
    • The thread sleeps for the calculated rate_dur.

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 TickEvents 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.