use std::time::Duration;
use crate::{
cell::{Cell, CellImmutable, CellMutable},
platform::{self, Instant},
signal::Signal,
source::Source,
};
pub fn interval(duration: Duration) -> Cell<u64, CellImmutable> {
let cell = Cell::<u64, CellMutable>::new(0);
let weak = cell.downgrade();
platform::spawn_interval(duration, false, move |count| {
let Some(c) = weak.upgrade() else {
return false;
};
c.notify(Signal::value(count));
true
});
cell.lock()
}
pub fn interval_source(duration: Duration) -> Source<u64> {
let source = Source::<u64>::new();
let weak = source.downgrade();
platform::spawn_interval(duration, false, move |count| {
let Some(s) = weak.upgrade() else {
return false;
};
s.emit(count);
true
});
source
}
pub fn interval_precise(duration: Duration) -> Cell<u64, CellImmutable> {
let cell = Cell::<u64, CellMutable>::new(0);
let weak = cell.downgrade();
platform::spawn_interval(duration, true, move |count| {
let Some(c) = weak.upgrade() else {
return false;
};
c.notify(Signal::value(count));
true
});
cell.lock()
}
pub fn interval_precise_source(duration: Duration) -> Source<u64> {
let source = Source::<u64>::new();
let weak = source.downgrade();
platform::spawn_interval(duration, true, move |count| {
let Some(s) = weak.upgrade() else {
return false;
};
s.emit(count);
true
});
source
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct IntervalTick {
pub tick: u64,
pub elapsed: Duration,
}
impl Default for IntervalTick {
fn default() -> Self {
Self {
tick: 0,
elapsed: Duration::ZERO,
}
}
}
pub fn interval_precise_with_elapsed(duration: Duration) -> Cell<IntervalTick, CellImmutable> {
let cell = Cell::<IntervalTick, CellMutable>::new(IntervalTick::default());
let weak = cell.downgrade();
let start = Instant::now();
platform::spawn_interval(duration, true, move |count| {
let Some(c) = weak.upgrade() else {
return false;
};
c.notify(Signal::value(IntervalTick {
tick: count,
elapsed: start.elapsed(),
}));
true
});
cell.lock()
}
pub fn interval_precise_with_elapsed_source(duration: Duration) -> Source<IntervalTick> {
let source = Source::<IntervalTick>::new();
let weak = source.downgrade();
let start = Instant::now();
platform::spawn_interval(duration, true, move |count| {
let Some(s) = weak.upgrade() else {
return false;
};
s.emit(IntervalTick {
tick: count,
elapsed: start.elapsed(),
});
true
});
source
}