use crate::task::{Priority, TaskHandle};
use crate::utils::timer_init;
use crate::utils::{VibeRng, elapsed_ns};
use crate::vibe_code::UltraVibeSystem;
use std::sync::{Arc, mpsc};
thread_local! {
static LOCAL_RNG: std::cell::RefCell<VibeRng> = std::cell::RefCell::new(VibeRng::new(elapsed_ns()));
}
pub struct Job<T> {
handle: TaskHandle<T>,
}
impl<T> Job<T> {
pub fn get(self) -> T {
match self.handle.recv_result() {
Ok(Ok(result)) => result,
Ok(Err(_)) => panic!("❌ Your job failed! Check your function for bugs."),
Err(_) => panic!("❌ Job was cancelled - did you shut down the system?"),
}
}
pub fn peek(self) -> Option<T> {
match self.handle.try_recv_result() {
Ok(Ok(result)) => Some(result),
Ok(Err(_)) => panic!("❌ Your job failed! Check your function for bugs."),
Err(mpsc::TryRecvError::Empty) => None,
Err(mpsc::TryRecvError::Disconnected) => panic!("❌ Job was cancelled"),
}
}
pub fn is_done(&self) -> bool {
matches!(
self.handle.try_recv_result(),
Ok(_) | Err(mpsc::TryRecvError::Disconnected)
)
}
}
pub struct VibeSystem {
inner: Arc<UltraVibeSystem>,
}
impl VibeSystem {
pub fn new() -> Self {
let _ = timer_init();
Self {
inner: Arc::new(
UltraVibeSystem::builder()
.with_nodes(80)
.with_super_nodes(40)
.build(),
),
}
}
pub fn run<F, T, R>(&self, func: F, data: T) -> Job<R>
where
F: FnOnce(T) -> R + Send + 'static,
T: Send + 'static,
R: Send + 'static,
{
LOCAL_RNG.with(|rng| {
let work = move || Ok(func(data));
match self
.inner
.submit_cpu_task(Priority::Normal, 10, work, &mut rng.borrow_mut())
{
Ok(handle) => Job { handle },
Err(_) => panic!("🔥 System overloaded! Too many jobs running at once."),
}
})
}
pub fn go<F, R>(&self, func: F) -> Job<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
self.run(|_| func(), ())
}
}
impl Default for VibeSystem {
fn default() -> Self {
Self::new()
}
}
pub fn collect<T>(jobs: Vec<Job<T>>) -> Vec<T> {
jobs.into_iter().map(|job| job.get()).collect()
}