use super::*;
impl<T: Clone + PartialEq + Default + 'static> ThrottledValue<T> {
pub fn set(&self, next: T, now_ms: u64) {
if *self.get_interval_ms() == 0 {
self.get_value().set(next);
self.get_pending().set(None);
self.get_state().set(ThrottleState::Idle);
return;
}
match self.get_state().get() {
ThrottleState::Idle => {
self.get_value().set(next);
self.get_state().set(ThrottleState::Cooldown(now_ms));
}
ThrottleState::Cooldown(_) => {
self.get_pending().set(Some(next));
}
}
}
pub fn tick(&self, now_ms: u64) -> bool {
match self.get_state().get() {
ThrottleState::Idle => false,
ThrottleState::Cooldown(start) => {
if now_ms.saturating_sub(start) < u64::from(*self.get_interval_ms()) {
return false;
}
let committed: bool = match self.get_pending().get() {
Some(pending) => {
self.get_value().set(pending);
self.get_pending().set(None);
true
}
None => false,
};
self.get_state().set(ThrottleState::Idle);
committed
}
}
}
pub fn cancel(&self) {
self.get_pending().set(None);
self.get_state().set(ThrottleState::Idle);
}
pub fn get(&self) -> T {
self.get_value().get()
}
pub fn is_throttling(&self) -> bool {
matches!(self.get_state().get(), ThrottleState::Cooldown(_))
}
}
impl<T: Clone + PartialEq + Debug + Default + 'static> Display for ThrottledValue<T> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match &self.get_state().get() {
ThrottleState::Idle => {
write!(formatter, "ThrottledValue({:?})", self.get_value().get())
}
ThrottleState::Cooldown(_) => {
write!(
formatter,
"ThrottledValue(cooldown={:?})",
self.get_value().get()
)
}
}
}
}