diff --git a/src/rustylee/build_number.txt b/src/rustylee/build_number.txt index bc768da..4701cc7 100644 --- a/src/rustylee/build_number.txt +++ b/src/rustylee/build_number.txt @@ -1 +1 @@ -146 \ No newline at end of file +150 \ No newline at end of file diff --git a/src/rustylee/src/brain.rs b/src/rustylee/src/brain.rs index 98c0f5f..89408f4 100644 --- a/src/rustylee/src/brain.rs +++ b/src/rustylee/src/brain.rs @@ -6,6 +6,7 @@ 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}; +use crate::system::time::Time; pub struct Brain { state:LifeState, @@ -31,8 +32,8 @@ impl Brain { } pub fn run(&mut self) { - self.execute_brain_loop(); self.build_organs(); + self.execute_brain_loop(); } fn execute_brain_loop(&mut self) { @@ -41,12 +42,13 @@ impl Brain { self.handle_divine_command(command) } - if self.state == LifeState::Buried { + if self.state == Buried { break; } - // TODO: Drain the Organ Feedback Mailbox - // (We will add this once we define the Organ channels) + if self.is_ready() { + self.request_heart_beat(); + } Self::rest() } @@ -95,6 +97,7 @@ impl Brain { false } + fn set_lifecycle_state(&mut self, command: &LifecycleCommand, new_state: LifeState) { self.state = new_state; self.report_to_god(LifecycleReceipt{ @@ -112,9 +115,26 @@ impl Brain { fn build_organs(& mut self) { info!("Building organs..."); - let factory = OrganFactory::new(self.organ_tx.clone()); + self.organ_sockets = OrganFactory::build_organs(self.organ_tx.clone()); info!("{} organs have been built and wired in.", self.organ_sockets.len()); } + + fn request_heart_beat(&self) { + if let Some(socket) = self.organ_sockets.first() { + let envelope = OrganCommandEnvelope { + command: OrganCommand::Beat(0), + issued_at: Time::time_stamp_millis(), + }; + + _ = socket.tx.send(envelope); + } + } + + fn is_ready(&self) -> bool { + self.state != LifeState::Dead && + self.state != Genisys && + self.state != Buried + } } diff --git a/src/rustylee/src/main.rs b/src/rustylee/src/main.rs index 510a735..93471a8 100644 --- a/src/rustylee/src/main.rs +++ b/src/rustylee/src/main.rs @@ -3,9 +3,10 @@ pub mod brain; pub mod organs; pub mod coordinates; pub mod protocols; +pub mod system; use std::fmt::Alignment::Left; -use tracing::{info, debug}; +use tracing::{debug, info}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::sync::mpsc; diff --git a/src/rustylee/src/organs.rs b/src/rustylee/src/organs.rs index 161060c..22f903c 100644 --- a/src/rustylee/src/organs.rs +++ b/src/rustylee/src/organs.rs @@ -1,4 +1,4 @@ pub mod heart; pub mod organ; pub mod organ_socket; -pub mod organ_factory; \ No newline at end of file +pub mod organ_factory; diff --git a/src/rustylee/src/organs/heart.rs b/src/rustylee/src/organs/heart.rs index c4aaae4..f071ef5 100644 --- a/src/rustylee/src/organs/heart.rs +++ b/src/rustylee/src/organs/heart.rs @@ -1,13 +1,15 @@ 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}; +use tracing::{debug, info, instrument}; +use crate::protocols::{BrainMessage, OrganCommand, OrganCommandEnvelope, OrganResponse}; +use crate::system::time::Time; pub struct Heart { id: u32, brain_command_rx: mpsc::Receiver, feedback_to_brain_tx: mpsc::Sender, + last_beat_time: u64, + timestamp: u64, } impl Heart { @@ -16,33 +18,56 @@ impl Heart { id, brain_command_rx: rx, feedback_to_brain_tx: tx, + last_beat_time: 0, + timestamp: 0, } } - + #[instrument(skip(self), fields(heart_id = self.id))] pub fn start(&mut self) { info!("Heart listener active"); while let Ok(envelope) = self.brain_command_rx.recv() { - // 1. Process the command (Logic goes here later) + self.timestamp = Time::time_stamp_millis(); + debug!("Received brain command: {:?}", envelope); + + match envelope.command { + OrganCommand::Beat(_) => { + if (self.ready_to_beat()) { + self.beat(); + } + } + _ => { + + } + } + let response = OrganResponse::Ok; - // 2. Capture the "now" timestamp - let now = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_millis() as u64; - - // 3. Package the reply - let reply = BrainMessage { - organ_command: envelope, // Move the original envelope back - responded_at: now, - response, - }; - - // 4. Trace the reply and send - info!(?reply, "Sending response to Brain"); - let _ = self.feedback_to_brain_tx.send(reply); + self.send_response_brain(envelope, response); } } + + fn ready_to_beat(&self) -> bool { + self.timestamp >= self.last_beat_time + 500 + } + + fn beat(&mut self) { + self.last_beat_time = self.timestamp; + info!("Beat time: {}", self.last_beat_time); + } + + fn send_response_brain(&self, envelope: OrganCommandEnvelope, response: OrganResponse) { + + let reply = BrainMessage { + organ_command: envelope, + responded_at: self.timestamp, + response, + }; + + info!(?reply, "Sending response to Brain"); + let _ = self.feedback_to_brain_tx.send(reply); + } } + + diff --git a/src/rustylee/src/organs/organ_socket.rs b/src/rustylee/src/organs/organ_socket.rs index 11ee018..0af5b89 100644 --- a/src/rustylee/src/organs/organ_socket.rs +++ b/src/rustylee/src/organs/organ_socket.rs @@ -4,7 +4,7 @@ use crate::protocols::{OrganCommand, OrganCommandEnvelope}; pub struct OrganSocket { pub id: u32, - tx: Sender, + pub tx: Sender, } impl OrganSocket { diff --git a/src/rustylee/src/system.rs b/src/rustylee/src/system.rs new file mode 100644 index 0000000..c25ca52 --- /dev/null +++ b/src/rustylee/src/system.rs @@ -0,0 +1 @@ +pub mod time; \ No newline at end of file diff --git a/src/rustylee/src/system/time.rs b/src/rustylee/src/system/time.rs new file mode 100644 index 0000000..2527c46 --- /dev/null +++ b/src/rustylee/src/system/time.rs @@ -0,0 +1,15 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + +pub struct Time { + +} + +impl Time { + + pub fn time_stamp_millis() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_millis() as u64 + } +} \ No newline at end of file