use std::cell::RefCell;
use std::pin::Pin;
use std::rc::Rc;
use std::task::{Context, Poll};
use crate::prelude::add_timer;
#[derive(Default, Clone, PartialEq, PartialOrd)]
pub struct Timer(pub Rc<RefCell<TimerData>>);
#[derive(Default, Clone, Copy, PartialEq, PartialOrd)]
pub struct TimerData {
original_time: f32,
pub time_left: f32,
pub paused: bool,
pub is_active: bool,
pub repeating: bool,
}
impl Future for Timer {
type Output = ();
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.completed() {
Poll::Ready(())
} else {
Poll::Pending
}
}
}
impl Timer {
pub fn new(seconds: f32) -> Self {
Self(Rc::new(RefCell::new(TimerData {
original_time: seconds,
time_left: seconds,
paused: false,
is_active: false,
repeating: false,
})))
}
pub fn new_repeating(seconds: f32) -> Self {
Self(Rc::new(RefCell::new(TimerData {
time_left: seconds,
paused: false,
is_active: false,
repeating: true,
original_time: seconds,
})))
}
pub fn tick(&mut self, dt: f32) {
if !self.0.borrow().paused {
self.0.borrow_mut().time_left -= dt;
}
}
pub fn reset(&self) {
let mut t = self.0.borrow_mut();
t.time_left = t.original_time;
}
pub fn finish(&self) {
self.0.borrow_mut().time_left = 0.0;
}
pub fn pause(&self) {
self.0.borrow_mut().paused = true;
}
pub fn unpause(&self) {
self.0.borrow_mut().paused = false;
}
pub fn set_paused(&self, paused: bool) {
self.0.borrow_mut().paused = paused;
}
pub fn toggle_paused(&self) {
let mut t = self.0.borrow_mut();
t.paused = !t.paused;
}
pub fn extend(&self, seconds: f32) {
self.0.borrow_mut().time_left += seconds;
}
pub fn ongoing(&self) -> bool {
self.0.borrow().time_left > 0.0
}
pub fn is_active(&self) -> bool {
self.0.borrow().is_active
}
pub fn on_completion(&self, mut action: impl FnMut()) {
if !self.ongoing() && self.0.borrow().is_active {
action()
}
}
pub fn completed(&self) -> bool {
!self.ongoing() && self.0.borrow().is_active
}
pub fn restart(&self) -> Timer {
self.reset();
self.start()
}
pub fn completed_and_restart(&self) -> bool {
let completed = self.completed();
if completed {
self.restart();
}
completed
}
pub fn start(&self) -> Timer {
add_timer(self.clone())
}
pub async fn wait(&self) {
self.clone().await
}
}