first commit, not pretty

This commit is contained in:
2025-12-10 23:50:28 +01:00
commit 5e9336c6c7
9 changed files with 1748 additions and 0 deletions

204
examples/bouncing_ball.rs Normal file
View File

@@ -0,0 +1,204 @@
use minifb::{Key, Window, WindowOptions};
use std::thread;
use std::time::{Duration, Instant};
use std::sync::{Arc, Mutex};
use rand::Rng;
const WIDTH: usize = 800;
const HEIGHT: usize = 600;
const BALL_RADIUS: usize = 20;
// Simple ball state
struct Ball {
x: f32,
y: f32,
vx: f32,
vy: f32,
color: u32,
}
impl Ball {
fn new() -> Self {
Self {
x: 400.0,
y: 300.0,
vx: 200.0, // pixels per second
vy: 150.0,
color: 0xFF6464FF, // Red-ish
}
}
}
fn main() {
// Start the telemetry window
teleprof::start();
println!("Bouncing Ball Demo");
println!("The ball window should appear alongside the profiler");
println!("Press Space in profiler window to pause");
println!("Press Escape in either window to quit");
println!();
let mut window = Window::new(
"Bouncing Ball",
WIDTH,
HEIGHT,
WindowOptions::default(),
)
.expect("Failed to create window");
window.set_target_fps(30);
let ball = Arc::new(Mutex::new(Ball::new()));
let mut framebuffer = vec![0u32; WIDTH * HEIGHT];
// Target 30 FPS
let frame_time = Duration::from_millis(33);
let mut frame_count = 0;
while window.is_open() && !window.is_key_down(Key::Escape) {
let frame_start = Instant::now();
teleprof::span!("main_frame");
// Check if paused
if teleprof::PAUSE.try_lock().is_err() {
println!("Paused!");
while teleprof::PAUSE.try_lock().is_err() {
thread::sleep(Duration::from_millis(100));
}
println!("Resumed!");
}
// Update physics
let hit_wall = update_physics(&ball, frame_time.as_secs_f32());
// If we hit a wall, spawn a thread to pick a new color
if hit_wall {
let ball_clone = Arc::clone(&ball);
thread::spawn(move || {
pick_new_color(ball_clone);
});
}
// Render
render(&ball, &mut framebuffer);
// Update window
window
.update_with_buffer(&framebuffer, WIDTH, HEIGHT)
.expect("Failed to update window");
frame_count += 1;
if frame_count % 30 == 0 {
print_status(&ball, frame_count);
}
// Sleep to maintain 30fps
let elapsed = frame_start.elapsed();
if elapsed < frame_time {
thread::sleep(frame_time - elapsed);
}
}
}
fn update_physics(ball: &Arc<Mutex<Ball>>, dt: f32) -> bool {
teleprof::span!("update_physics");
let mut ball = ball.lock().unwrap();
// Update position
ball.x += ball.vx * dt;
ball.y += ball.vy * dt;
let mut hit_wall = false;
// Bounce off walls
let radius = BALL_RADIUS as f32;
if ball.x - radius < 0.0 || ball.x + radius > WIDTH as f32 {
ball.vx = -ball.vx;
ball.x = ball.x.clamp(radius, WIDTH as f32 - radius);
hit_wall = true;
}
if ball.y - radius < 0.0 || ball.y + radius > HEIGHT as f32 {
ball.vy = -ball.vy;
ball.y = ball.y.clamp(radius, HEIGHT as f32 - radius);
hit_wall = true;
}
// Simulate some physics computation
thread::sleep(Duration::from_millis(5));
hit_wall
}
fn pick_new_color(ball: Arc<Mutex<Ball>>) {
teleprof::span!("pick_new_color");
// Simulate some "expensive" color selection
thread::sleep(Duration::from_millis(10));
let mut rng = rand::thread_rng();
let r = rng.gen_range(50..255);
let g = rng.gen_range(50..255);
let b = rng.gen_range(50..255);
let color = ((r as u32) << 16) | ((g as u32) << 8) | (b as u32);
let mut ball = ball.lock().unwrap();
ball.color = color;
println!(" → New color selected: RGB({}, {}, {})", r, g, b);
}
fn render(ball: &Arc<Mutex<Ball>>, framebuffer: &mut [u32]) {
teleprof::span!("render");
{
teleprof::span!("clear_background");
// Clear to dark gray
framebuffer.fill(0x2A2A2AFF);
}
{
teleprof::span!("draw_ball");
let ball = ball.lock().unwrap();
// Draw ball as a filled circle
let cx = ball.x as i32;
let cy = ball.y as i32;
let radius = BALL_RADIUS as i32;
for dy in -radius..=radius {
for dx in -radius..=radius {
// Check if point is inside circle
if dx * dx + dy * dy <= radius * radius {
let x = cx + dx;
let y = cy + dy;
if x >= 0 && x < WIDTH as i32 && y >= 0 && y < HEIGHT as i32 {
let idx = y as usize * WIDTH + x as usize;
framebuffer[idx] = ball.color;
}
}
}
}
}
{
teleprof::span!("submit_frame");
// Simulate GPU submission
thread::sleep(Duration::from_millis(2));
}
}
fn print_status(ball: &Arc<Mutex<Ball>>, frame: u32) {
teleprof::span!("print_status");
let ball = ball.lock().unwrap();
println!(
"Frame {}: Ball at ({:.1}, {:.1})",
frame, ball.x, ball.y
);
}