use rill_core::traits::{NodeId, ParameterId, PortId};
use std::fmt;
use std::sync::Arc;
use std::time::{Duration, Instant};
#[derive(Debug, Clone, Copy)]
pub struct WorldTime {
pub absolute: f64,
pub delta: f64,
pub tick: u64,
}
impl WorldTime {
pub fn new() -> Self {
Self {
absolute: 0.0,
delta: 0.0,
tick: 0,
}
}
pub fn advance(&mut self, delta_seconds: f64) {
self.delta = delta_seconds;
self.absolute += delta_seconds;
self.tick += 1;
}
}
#[derive(Debug, Clone)]
pub enum SignalOrigin {
Automaton(String),
Sensor(String),
Servo(String),
External(String),
}
impl fmt::Display for SignalOrigin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SignalOrigin::Automaton(name) => write!(f, "⚙️ {}", name),
SignalOrigin::Sensor(name) => write!(f, "👁️ {}", name),
SignalOrigin::Servo(name) => write!(f, "🦾 {}", name),
SignalOrigin::External(name) => write!(f, "🌍 {}", name),
}
}
}
#[derive(Debug, Clone)]
pub struct WorldSignal {
pub origin: SignalOrigin,
pub target: Option<SignalTarget>,
pub value: f32,
pub time: WorldTime,
}
impl WorldSignal {
pub fn new(origin: SignalOrigin, value: f32) -> Self {
Self {
origin,
target: None,
value: value.clamp(0.0, 1.0),
time: WorldTime::new(), }
}
pub fn with_target(mut self, target: SignalTarget) -> Self {
self.target = Some(target);
self
}
}
#[derive(Debug, Clone)]
pub enum SignalTarget {
Parameter(PortId, ParameterId),
Automaton(String),
Bus(String),
}
#[derive(Clone)]
pub struct AutomatonContext {
pub time: WorldTime,
pub inputs: Vec<WorldSignal>,
pub memory: Arc<parking_lot::RwLock<Vec<f32>>>,
}
impl AutomatonContext {
pub fn new() -> Self {
Self {
time: WorldTime::new(),
inputs: Vec::new(),
memory: Arc::new(parking_lot::RwLock::new(Vec::with_capacity(16))),
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum WorldError {
#[error("Sensor {0} not found")]
SensorNotFound(String),
#[error("Automaton {0} not found")]
AutomatonNotFound(String),
#[error("Servo {0} not found")]
ServoNotFound(String),
#[error("Signal target not found")]
TargetNotFound,
#[error("Channel error")]
ChannelError,
}