use fibertract::{FiberBundle, FiberTractKind};
use crate::pipeline::HeartHandle;
use crate::vitals::BeatEvent;
pub struct AutonomicBridge {
pub sympathetic: FiberBundle,
pub vagus: FiberBundle,
}
impl AutonomicBridge {
pub fn new(sympathetic: FiberBundle, vagus: FiberBundle) -> Self {
Self {
sympathetic,
vagus,
}
}
pub fn from_profiles() -> Self {
use fibertract::LimbProfile;
Self {
sympathetic: LimbProfile::sympathetic_cardiac().build(),
vagus: LimbProfile::vagus_nerve().build(),
}
}
pub fn push_chemicals(&self, heart: &HeartHandle) {
let ne = self
.sympathetic
.tract(FiberTractKind::AutonomicEfferent)
.map(|t| t.autonomic_concentration(0))
.unwrap_or(0);
let ach = self
.vagus
.tract(FiberTractKind::AutonomicEfferent)
.map(|t| t.autonomic_concentration(0))
.unwrap_or(0);
if ne > 0 {
heart.inject_ne(ne);
}
if ach > 0 {
heart.inject_ach(ach);
}
}
pub fn push_cortisol(&self, heart: &HeartHandle, cortisol: u8) {
if cortisol > 0 {
heart.inject_cortisol(cortisol);
}
}
pub fn write_interoception(&mut self, beat: &BeatEvent) {
if let Some(afferent) = self.vagus.tract_mut(FiberTractKind::Interoceptive) {
let ibi_signal = beat.ibi_us.min(i32::MAX as u64) as i32;
let pressure_signal = beat.stroke_force as i32 * 100;
let input = vec![ibi_signal, pressure_signal];
afferent.transmit_sensory(&input, beat.beat_number);
}
}
pub fn write_silence(&mut self) {
if let Some(afferent) = self.vagus.tract_mut(FiberTractKind::Interoceptive) {
let input = vec![0i32, 0i32];
afferent.transmit_sensory(&input, 0);
}
}
pub fn set_sympathetic_drive(&mut self, ne_concentration: u8) {
if let Some(tract) = self.sympathetic.tract_mut(FiberTractKind::AutonomicEfferent) {
tract.transmit_autonomic(&[ne_concentration]);
}
}
pub fn set_vagal_drive(&mut self, ach_concentration: u8) {
if let Some(tract) = self.vagus.tract_mut(FiberTractKind::AutonomicEfferent) {
tract.transmit_autonomic(&[ach_concentration]);
}
}
pub fn read_interoception(&self) -> (i32, i32) {
self.vagus
.tract(FiberTractKind::Interoceptive)
.map(|t| {
let beat = t.sensory_signals.first().copied().unwrap_or(0);
let pressure = t.sensory_signals.get(1).copied().unwrap_or(0);
(beat, pressure)
})
.unwrap_or((0, 0))
}
pub fn delivered_ne(&self) -> u8 {
self.sympathetic
.tract(FiberTractKind::AutonomicEfferent)
.map(|t| t.autonomic_concentration(0))
.unwrap_or(0)
}
pub fn delivered_ach(&self) -> u8 {
self.vagus
.tract(FiberTractKind::AutonomicEfferent)
.map(|t| t.autonomic_concentration(0))
.unwrap_or(0)
}
}