1mod clock;
2mod executor;
3mod test_scheduler;
4#[cfg(test)]
5mod tests;
6
7pub use clock::*;
8pub use executor::*;
9pub use test_scheduler::*;
10
11use async_task::Runnable;
12use futures::channel::oneshot;
13use std::{
14 future::Future,
15 panic::Location,
16 pin::Pin,
17 sync::Arc,
18 task::{Context, Poll},
19 time::Duration,
20};
21
22#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
28#[repr(u8)]
29pub enum Priority {
30 RealtimeAudio,
34 High,
36 #[default]
38 Medium,
39 Low,
41}
42
43impl Priority {
44 pub const fn weight(self) -> u32 {
47 match self {
48 Priority::High => 60,
49 Priority::Medium => 30,
50 Priority::Low => 10,
51 Priority::RealtimeAudio => 0,
53 }
54 }
55}
56
57#[derive(Clone)]
59pub struct RunnableMeta {
60 pub location: &'static Location<'static>,
62}
63
64impl std::fmt::Debug for RunnableMeta {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 f.debug_struct("RunnableMeta")
67 .field("location", &self.location)
68 .finish()
69 }
70}
71
72pub trait Scheduler: Send + Sync {
73 fn block(
79 &self,
80 session_id: Option<SessionId>,
81 future: Pin<&mut dyn Future<Output = ()>>,
82 timeout: Option<Duration>,
83 ) -> bool;
84
85 fn schedule_foreground(&self, session_id: SessionId, runnable: Runnable<RunnableMeta>);
86
87 fn schedule_background_with_priority(
89 &self,
90 runnable: Runnable<RunnableMeta>,
91 priority: Priority,
92 );
93
94 fn spawn_realtime(&self, f: Box<dyn FnOnce() + Send>);
96
97 fn schedule_background(&self, runnable: Runnable<RunnableMeta>) {
99 self.schedule_background_with_priority(runnable, Priority::default());
100 }
101
102 #[track_caller]
103 fn timer(&self, timeout: Duration) -> Timer;
104 fn clock(&self) -> Arc<dyn Clock>;
105
106 fn as_test(&self) -> Option<&TestScheduler> {
107 None
108 }
109}
110
111#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
112pub struct SessionId(u16);
113
114impl SessionId {
115 pub fn new(id: u16) -> Self {
116 SessionId(id)
117 }
118}
119
120pub struct Timer(oneshot::Receiver<()>);
121
122impl Timer {
123 pub fn new(rx: oneshot::Receiver<()>) -> Self {
124 Timer(rx)
125 }
126}
127
128impl Future for Timer {
129 type Output = ();
130
131 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<()> {
132 match Pin::new(&mut self.0).poll(cx) {
133 Poll::Ready(_) => Poll::Ready(()),
134 Poll::Pending => Poll::Pending,
135 }
136 }
137}