chalkydri/
subsystem.rs

1use std::{fmt::Debug, sync::Arc};
2
3use tokio::sync::{broadcast, watch};
4
5pub type Buffer = Arc<Vec<u8>>;
6
7/// A processing subsystem
8///
9/// Subsystems implement different computer vision tasks, such as AprilTags or object detection.
10///
11/// A subsystem should be generic, not something that is only used for some specific aspect of a
12/// game.
13/// For example, note detection for the 2024 game, Crescendo, would go under the object detection
14/// subsystem, rather than a brand new subsystem.
15///
16/// Make sure to pay attention to and respect each subsystem's documentation and structure.
17pub trait Subsystem<'fr>: Sized {
18    type Output: Send + 'static;
19    type Error: Debug + Send + 'static;
20
21    /// Initialize the subsystem
22    async fn init() -> Result<Self, Self::Error>;
23    /// Process a frame
24    fn process(&mut self, buf: Buffer) -> Result<Self::Output, Self::Error>;
25}
26
27/// Run a [`subsystem`](Subsystem)
28async fn run<'fr, S: Subsystem<'fr>>(mut rx: watch::Receiver<Arc<Vec<u8>>>) {
29    let mut subsys = S::init().await.unwrap();
30
31    while let Ok(()) = rx.changed().await {
32        let buf = rx.borrow_and_update();
33        S::process(&mut subsys, buf.clone()).unwrap();
34    }
35}
36
37pub struct SubsysHandle<T: Sized> {
38    tx: watch::Sender<Buffer>,
39    rx: broadcast::Receiver<T>,
40}