com_croftsoft_lib_animation/metronome/
updater.rs

1// =============================================================================
2//! - An Updater of implementations of the Metronome trait
3//!
4//! # Metadata
5//! - Copyright: © 2023 [`CroftSoft Inc`]
6//! - Author: [`David Wallace Croft`]
7//! - Created: 2023-02-21
8//! - Updated: 2023-09-02
9//!
10//! [`CroftSoft Inc`]: https://www.croftsoft.com/
11//! [`David Wallace Croft`]: https://www.croftsoft.com/people/david/
12// =============================================================================
13
14use super::Metronome;
15use com_croftsoft_lib_role::Updater;
16use core::cell::{Ref, RefCell, RefMut};
17use std::rc::Rc;
18
19pub trait MetronomeUpdaterEvents {
20  fn set_period_millis_changed(
21    &mut self,
22    period_millis: f64,
23  );
24  fn set_tick(&mut self);
25}
26
27pub trait MetronomeUpdaterInputs {
28  fn get_current_time_millis(&self) -> f64;
29  fn get_period_millis_change_requested(&self) -> Option<f64>;
30  fn get_reset_requested(&self) -> bool;
31}
32
33pub struct MetronomeUpdater {
34  events: Rc<RefCell<dyn MetronomeUpdaterEvents>>,
35  inputs: Rc<RefCell<dyn MetronomeUpdaterInputs>>,
36  metronome: Rc<RefCell<dyn Metronome>>,
37}
38
39impl MetronomeUpdater {
40  pub fn new(
41    events: Rc<RefCell<dyn MetronomeUpdaterEvents>>,
42    inputs: Rc<RefCell<dyn MetronomeUpdaterInputs>>,
43    metronome: Rc<RefCell<dyn Metronome>>,
44  ) -> Self {
45    Self {
46      events,
47      inputs,
48      metronome,
49    }
50  }
51}
52
53impl Updater for MetronomeUpdater {
54  fn update(&self) {
55    let inputs: Ref<dyn MetronomeUpdaterInputs> = self.inputs.borrow();
56    if let Some(period_millis) = inputs.get_period_millis_change_requested() {
57      let mut metronome: RefMut<dyn Metronome> = self.metronome.borrow_mut();
58      metronome.set_period_millis(period_millis);
59      self.events.borrow_mut().set_period_millis_changed(period_millis);
60      metronome.set_time_millis_next_tick(0.);
61    }
62    let current_time_millis: f64 =
63      self.inputs.borrow().get_current_time_millis();
64    if inputs.get_reset_requested() {
65      self.metronome.borrow_mut().reset(current_time_millis);
66    }
67    if self.metronome.borrow_mut().tick(current_time_millis) {
68      self.events.borrow_mut().set_tick();
69    }
70  }
71}