[InputPoller] implementation that receives inputs updates from another thread.
7#[derive(Debug)] 8pub struct ThreadedInputPoller<Inputs> { 9 cached: Inputs, 10 locked: Arc<Mutex<Inputs>>, 11 updated: Arc<AtomicBool>, 12} 13 14#[derive(Debug)] 15pub struct ThreadedInputPollerHandle<Inputs> { 16 cached: Inputs, 17 locked: Arc<Mutex<Inputs>>, 18 updated: Arc<AtomicBool>, 19} 20 21impl<Inputs: Clone + Eq> ThreadedInputPoller<Inputs> { 22 pub fn new(initial_inputs: Inputs) -> Self { 23 Self { 24 cached: initial_inputs.clone(), 25 locked: Arc::new(Mutex::new(initial_inputs)), 26 updated: Arc::new(AtomicBool::new(false)), 27 } 28 } 29 30 pub fn handle(&self) -> ThreadedInputPollerHandle<Inputs> { 31 ThreadedInputPollerHandle { 32 cached: self.cached.clone(), 33 locked: Arc::clone(&self.locked), 34 updated: Arc::clone(&self.updated), 35 } 36 } 37} 38 39impl<Inputs: Clone + Eq> ThreadedInputPollerHandle<Inputs> { 40 pub fn update_inputs(&mut self, inputs: &Inputs) { 41 if inputs == &self.cached { 42 return; 43 } 44 45 self.cached = inputs.clone(); 46 *self.locked.lock().unwrap() = inputs.clone(); 47 self.updated.store(true, Ordering::Release); 48 } 49} 50 51impl<Inputs: Clone + Eq> InputPoller<Inputs> for ThreadedInputPoller<Inputs> { 52 fn poll(&mut self) -> &Inputs { 53 if self.updated.load(Ordering::Relaxed) 54 && self.updated.compare_exchange(true, false, Ordering::AcqRel, Ordering::Relaxed) 55 == Ok(true) 56 { 57 self.cached = self.locked.lock().unwrap().clone(); 58 } 59 60 &self.cached 61 } 62}