#[cfg(any(test, feature = "bench"))]
pub mod bench;
#[cfg(test)]
mod tests;
use crate::{
edge::EdgeOccupancy,
graph::GraphApi,
prelude::{PlatformClock, Telemetry},
};
#[cfg(feature = "std")]
#[derive(Clone)]
pub struct RuntimeStopHandle {
flag: std::sync::Arc<core::sync::atomic::AtomicBool>,
}
#[cfg(feature = "std")]
impl RuntimeStopHandle {
pub fn new(flag: std::sync::Arc<core::sync::atomic::AtomicBool>) -> Self {
Self { flag }
}
pub fn request_stop(&self) {
self.flag.store(true, core::sync::atomic::Ordering::Relaxed);
}
pub fn is_stopping(&self) -> bool {
self.flag.load(core::sync::atomic::Ordering::Relaxed)
}
}
pub trait LimenRuntime<Graph, const NODE_COUNT: usize, const EDGE_COUNT: usize>
where
Graph: GraphApi<NODE_COUNT, EDGE_COUNT>,
Self::Clock: PlatformClock + Sized,
Self::Telemetry: Telemetry + Sized,
{
type Clock;
type Telemetry;
type Error;
#[cfg(feature = "std")]
type StopHandle: Clone + Send + Sync + 'static;
fn init(
&mut self,
graph: &mut Graph,
clock: Self::Clock,
telemetry: Self::Telemetry,
) -> Result<(), Self::Error>;
fn reset(&mut self, graph: &Graph) -> Result<(), Self::Error>;
fn request_stop(&mut self);
#[cfg(feature = "std")]
fn stop_handle(&self) -> Option<Self::StopHandle> {
None
}
fn is_stopping(&self) -> bool;
fn occupancies(&self) -> &[EdgeOccupancy; EDGE_COUNT];
fn step(&mut self, graph: &mut Graph) -> Result<bool, Self::Error>;
#[inline]
fn run(&mut self, graph: &mut Graph) -> Result<(), Self::Error> {
while !self.is_stopping() {
if !self.step(graph)? {
break;
}
}
Ok(())
}
}