use std::time::Instant;
use vibe_graph_layout_gpu::{Edge, GpuLayout, LayoutConfig, Position};
fn main() {
tracing_subscriber::fmt::init();
let node_count = 1000;
let edge_count = 2000;
println!(
"Creating random graph with {} nodes and {} edges...",
node_count, edge_count
);
let mut positions: Vec<Position> = Vec::with_capacity(node_count);
for i in 0..node_count {
let angle = (i as f32) * 0.1;
let radius = 100.0 + (i as f32) * 0.5;
positions.push(Position::new(
radius * angle.cos() + (i as f32 * 13.37).sin() * 50.0,
radius * angle.sin() + (i as f32 * 7.13).cos() * 50.0,
));
}
let mut edges: Vec<Edge> = Vec::with_capacity(edge_count);
for i in 1..node_count {
edges.push(Edge::new((i - 1) as u32, i as u32));
}
for i in 0..(edge_count - node_count + 1) {
let source = (i * 17) % node_count;
let target = (i * 31 + 7) % node_count;
if source != target {
edges.push(Edge::new(source as u32, target as u32));
}
}
println!("Initializing GPU layout...");
let config = LayoutConfig {
use_barnes_hut: true,
theta: 0.8,
repulsion: 1000.0,
attraction: 0.01,
gravity: 0.1,
damping: 0.9,
dt: 0.016,
ideal_length: 50.0,
max_tree_depth: 10,
};
let mut layout =
pollster::block_on(GpuLayout::new(config)).expect("Failed to create GPU layout");
layout
.init(positions, edges)
.expect("Failed to initialize layout");
println!("Running layout simulation...");
layout.start();
let iterations = 100;
let start = Instant::now();
for i in 0..iterations {
let positions = layout.step().expect("Layout step failed");
if i % 10 == 0 {
let (min_x, max_x, min_y, max_y) = positions.iter().fold(
(f32::MAX, f32::MIN, f32::MAX, f32::MIN),
|(min_x, max_x, min_y, max_y), p| {
(
min_x.min(p.x),
max_x.max(p.x),
min_y.min(p.y),
max_y.max(p.y),
)
},
);
println!(
"Iteration {}: bounds = ({:.1}, {:.1}) to ({:.1}, {:.1})",
i, min_x, min_y, max_x, max_y
);
}
}
let elapsed = start.elapsed();
let fps = iterations as f64 / elapsed.as_secs_f64();
println!("\nCompleted {} iterations in {:.2?}", iterations, elapsed);
println!(
"Average: {:.1} iterations/sec ({:.1} ms/iteration)",
fps,
1000.0 / fps
);
if fps >= 60.0 {
println!("✅ Performance target met: >= 60 FPS");
} else if fps >= 30.0 {
println!("⚠️ Performance acceptable: 30-60 FPS");
} else {
println!("❌ Performance below target: < 30 FPS");
}
let final_positions = layout.positions();
println!("\nFinal positions (first 5 nodes):");
for (i, pos) in final_positions.iter().take(5).enumerate() {
println!(" Node {}: ({:.2}, {:.2})", i, pos.x, pos.y);
}
}