use std::thread; use std::sync::{mpsc,Arc}; use parking_lot::{Mutex,Condvar}; //The goal here is to have a worker thread that parks itself when it runs out of work. //The worker thread publishes the result of its work back to the worker object for every item in the work queue. //The physics (target use case) knows when it has not changed the body, so not updating the value is also an option. struct Worker { sender: mpsc::Sender, receiver: Arc<(Mutex>,Condvar)>, value:Arc>, } impl Worker { fn newValue+Send+'static>(value:Value,f:F) -> Self { let (sender, receiver) = mpsc::channel::(); let ret=Self { sender, receiver:Arc::new((Mutex::new(receiver),Condvar::new())), value:Arc::new(Mutex::new(value)), }; let receiver=ret.receiver.clone(); let value=ret.value.clone(); thread::spawn(move || { loop{ loop { match receiver.0.lock().recv() { Ok(task) => { println!("Worker got a task"); // Process the task *value.lock()=f(task); } Err(_) => { println!("Worker stopping.",); break; } } } receiver.1.wait(&mut receiver.0.lock()); } }); ret } fn send(&self,task:Task)->Result<(), mpsc::SendError>{ let ret=self.sender.send(task); self.receiver.1.notify_one(); ret } fn grab_clone(&self)->Value{ self.value.lock().clone() } } #[test] fn test_worker() { println!("hiiiii"); // Create the worker thread let worker = Worker::new(crate::body::Body::with_pva(glam::Vec3::ZERO,glam::Vec3::ZERO,glam::Vec3::ZERO), |_|crate::body::Body::with_pva(glam::Vec3::ONE,glam::Vec3::ONE,glam::Vec3::ONE) ); // Send tasks to the worker for i in 0..5 { let task = crate::instruction::TimedInstruction{ time:0, instruction:crate::body::PhysicsInstruction::StrafeTick, }; worker.send(task).unwrap(); } // Optional: Signal the worker to stop (in a real-world scenario) // sender.send("STOP".to_string()).unwrap(); // Sleep to allow the worker thread to finish processing thread::sleep(std::time::Duration::from_secs(2)); // Send a new task let task = crate::instruction::TimedInstruction{ time:0, instruction:crate::body::PhysicsInstruction::StrafeTick, }; worker.send(task).unwrap(); println!("value={:?}",worker.grab_clone()); }