diff --git a/src/rustylee/src/brain.rs b/src/rustylee/src/brain.rs index e61eb84..98c0f5f 100644 --- a/src/rustylee/src/brain.rs +++ b/src/rustylee/src/brain.rs @@ -1,24 +1,41 @@ use tracing::{debug, info}; use std::sync::mpsc::{Receiver, Sender}; +use std::thread::JoinHandle; use crate::lifecycle::{LifeState, LifecycleCommand, LifecycleCommandResponse, LifecycleReceipt}; use crate::lifecycle::LifeState::{Dying, Buried, Genisys}; +use crate::organs::organ_factory::OrganFactory; +use crate::organs::organ_socket::OrganSocket; +use crate::protocols::{BrainMessage, OrganCommand, OrganCommandEnvelope}; pub struct Brain { state:LifeState, divine_rx : Receiver, - divine_tx: Sender + divine_tx: Sender, + organ_rx: Receiver, + organ_tx: Sender, + organ_sockets: Vec, } impl Brain { pub fn new(divine_rx: Receiver, divine_tx: Sender) -> Self { + let (organ_tx, organ_rx) = std::sync::mpsc::channel::(); + Self { state: LifeState::Dead, divine_rx, divine_tx, + organ_rx, + organ_tx, + organ_sockets: Vec::new() } } pub fn run(&mut self) { + self.execute_brain_loop(); + self.build_organs(); + } + + fn execute_brain_loop(&mut self) { loop { while let Ok(command) = self.divine_rx.try_recv() { self.handle_divine_command(command) @@ -92,5 +109,12 @@ impl Brain { let _ = self.divine_tx.send(receipt); } + fn build_organs(& mut self) { + info!("Building organs..."); + + let factory = OrganFactory::new(self.organ_tx.clone()); + + info!("{} organs have been built and wired in.", self.organ_sockets.len()); + } } diff --git a/src/rustylee/src/organs.rs b/src/rustylee/src/organs.rs index 6833b1a..161060c 100644 --- a/src/rustylee/src/organs.rs +++ b/src/rustylee/src/organs.rs @@ -1,2 +1,4 @@ pub mod heart; -pub mod organ; \ No newline at end of file +pub mod organ; +pub mod organ_socket; +pub mod organ_factory; \ No newline at end of file diff --git a/src/rustylee/src/organs/heart.rs b/src/rustylee/src/organs/heart.rs index 98f34a8..6c3bcc6 100644 --- a/src/rustylee/src/organs/heart.rs +++ b/src/rustylee/src/organs/heart.rs @@ -1,12 +1,29 @@ use std::sync::mpsc; +use std::sync::mpsc::{Receiver, Sender}; use std::time::{SystemTime, UNIX_EPOCH}; use tracing::{info, instrument}; use crate::protocols::{BrainMessage, OrganCommandEnvelope, OrganResponse}; pub struct Heart { id: u32, - rx: mpsc::Receiver, - tx: mpsc::Sender, + brain_command_rx: mpsc::Receiver, + feedback_to_brain_tx: mpsc::Sender, +} + +impl Heart { + pub(crate) fn run_loop(&mut self) { + todo!() + } +} + +impl Heart { + pub(crate) fn new(id: u32, rx: Receiver, tx: Sender) -> Self { + Self { + id, + brain_command_rx: rx, + feedback_to_brain_tx: tx, + } + } } impl Heart { @@ -14,7 +31,7 @@ impl Heart { pub fn start(self) { info!("Heart listener active"); - while let Ok(envelope) = self.rx.recv() { + while let Ok(envelope) = self.brain_command_rx.recv() { // 1. Process the command (Logic goes here later) let response = OrganResponse::Ok; @@ -33,7 +50,7 @@ impl Heart { // 4. Trace the reply and send info!(?reply, "Sending response to Brain"); - let _ = self.tx.send(reply); + let _ = self.feedback_to_brain_tx.send(reply); } } } \ No newline at end of file diff --git a/src/rustylee/src/organs/organ_factory.rs b/src/rustylee/src/organs/organ_factory.rs new file mode 100644 index 0000000..8775d6e --- /dev/null +++ b/src/rustylee/src/organs/organ_factory.rs @@ -0,0 +1,56 @@ +use std::sync::mpsc::{self, Receiver, Sender}; +use std::thread; +use crate::organs::organ_socket::OrganSocket; +use crate::organs::heart::Heart; // Assuming Heart is our first organ +use crate::protocols::{OrganCommandEnvelope, BrainMessage}; + +pub struct OrganFactory { + brain_tx: Sender, +} + +impl OrganFactory { + pub(crate) fn new(brain_sender: Sender) -> Self { + Self { + brain_tx: brain_sender, + } + } +} + +impl OrganFactory { + pub fn build_organs( + // The Brain's "Inbox" mouth - we'll clone this for each organ + brain_tx: Sender + ) -> Vec { + let mut sockets = Vec::new(); + + // Let's spawn a Heart as an example (ID: 1) + // In a real factory, you might loop through a config list here + let heart_socket = Self::spawn_heart(1, brain_tx.clone()); + sockets.push(heart_socket); + + // Add more organs here... + // let lung_socket = Self::spawn_lung(2, brain_tx.clone()); + + tracing::info!(count = sockets.len(), "Organ collection built and threads spawned"); + + sockets + } + + fn spawn_heart(id: u32, feedback_to_brain_tx: Sender) -> OrganSocket { + let (brain_command_to_organ_tx, brain_command_to_organ_rx) = + Self::get_organ_channels(); + + let socket = OrganSocket::new(id, brain_command_to_organ_tx); + + thread::spawn(move || { + let mut heart = Heart::new(id, brain_command_to_organ_rx, feedback_to_brain_tx); + heart.run_loop(); + }); + + socket + } + + fn get_organ_channels() -> (Sender, Receiver) { + mpsc::channel::() + } +} \ No newline at end of file diff --git a/src/rustylee/src/organs/organ_socket.rs b/src/rustylee/src/organs/organ_socket.rs new file mode 100644 index 0000000..11ee018 --- /dev/null +++ b/src/rustylee/src/organs/organ_socket.rs @@ -0,0 +1,32 @@ +use std::time::{SystemTime, UNIX_EPOCH}; +use std::sync::mpsc::Sender; +use crate::protocols::{OrganCommand, OrganCommandEnvelope}; + +pub struct OrganSocket { + pub id: u32, + tx: Sender, +} + +impl OrganSocket { + pub fn new(id: u32, tx: Sender) -> Self { + Self { id, tx } + } + + pub fn send(&self, command: OrganCommand) { + // Here's the "Stamping" logic. + // The Brain just says "Beat", the Socket adds the "Metadata". + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_millis() as u64; + + let envelope = OrganCommandEnvelope { + command, + issued_at: now, + }; + + if let Err(e) = self.tx.send(envelope) { + tracing::error!(organ_id = self.id, error = %e, "Socket delivery failed"); + } + } +} \ No newline at end of file