use std::{
fmt::{Display, Formatter}, fmt,
time::Duration
};
use sync_wait_object::WaitObjectError;
use crate::{TimerQueue, Timer};
#[derive(Copy, Clone, Debug)]
pub enum CallbackHint {
QuickFunction,
SlowFunction(Duration)
}
#[derive(Debug)]
pub enum TimerError {
OsError(isize, String),
SynchronizationBroken
}
pub type Result<T> = std::result::Result<T, TimerError>;
pub const DEFAULT_ACCEPTABLE_EXECUTION_TIME: Duration = Duration::from_secs(1);
pub fn schedule_interval<'h, F>(interval: Duration, hint: Option<CallbackHint>, handler: F) -> Result<Timer<'h>> where F: FnMut() + Send + 'h {
TimerQueue::default().schedule_timer(interval, interval, hint, handler)
}
pub fn schedule_oneshot<'h, F>(due: Duration, hint: Option<CallbackHint>, handler: F) -> Result<Timer<'h>> where F: FnOnce() + Send + 'h {
TimerQueue::default().schedule_oneshot(due, hint, handler)
}
#[inline]
pub fn fire_oneshot<F>(due: Duration, hint: Option<CallbackHint>, handler: F) -> Result<()> where F: FnOnce() + Send + 'static {
TimerQueue::default().fire_oneshot(due, hint, handler)
}
impl<'h> Drop for Timer<'h> {
fn drop(&mut self) {
if let Err(e) = self.close() {
println!("WARNING: an error occurred during timer destruction. Memory might leak. Error = {e:?}");
}
}
}
impl Display for TimerError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
TimerError::OsError(code, msg) => write!(f, "OS error {code}: {msg}"),
TimerError::SynchronizationBroken => write!(f, "A sync object is broken from a thread's panic!")
}
}
}
impl<T> From<std::sync::PoisonError<T>> for TimerError {
fn from(_value: std::sync::PoisonError<T>) -> Self {
Self::SynchronizationBroken
}
}
impl From<WaitObjectError> for TimerError {
fn from(value: WaitObjectError) -> Self {
match value {
WaitObjectError::OsError(v, s) => TimerError::OsError(v, s),
WaitObjectError::SynchronizationBroken => TimerError::SynchronizationBroken,
WaitObjectError::Timeout => TimerError::SynchronizationBroken
}
}
}
impl std::error::Error for TimerError {}