From 6bf5809ed87030d3e86d090f6f22c2296f98c279 Mon Sep 17 00:00:00 2001 From: Russell Gilbert Date: Sat, 14 Mar 2026 09:04:42 +0000 Subject: [PATCH] RustyLee: Implements initial system wake-up protocol The Brain now broadcasts a 'Waken' command to all connected organs during its startup phase. Organs, like the Heart, transition to an 'Awake' state upon receiving this command and provide feedback. The Brain then updates its own 'LifeState' to 'Awake' once organs acknowledge the wake-up. This change establishes a fundamental handshake, ensuring that core system functions only activate once the components are initialized and responsive. It introduces the `LifeState::Awake` and `OrganCommand::Waken` states for this purpose. --- src/rustylee/src/brain.rs | 23 ++++++++++++++++++- src/rustylee/src/lifecycle.rs | 4 ++-- src/rustylee/src/organs/heart.rs | 38 ++++++++++++++++++++++---------- src/rustylee/src/protocols.rs | 5 +++-- 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/rustylee/src/brain.rs b/src/rustylee/src/brain.rs index 8201c87..63b9b5d 100644 --- a/src/rustylee/src/brain.rs +++ b/src/rustylee/src/brain.rs @@ -36,6 +36,8 @@ impl Brain { } fn execute_brain_loop(&mut self) { + self.broadcast_to_organs(OrganCommand::Waken); + loop { while let Ok(command) = self.divine_rx.try_recv() { self.handle_divine_command(command) @@ -50,7 +52,7 @@ impl Brain { } while let Ok(message) = self.organ_rx.try_recv() { - + self.process_organ_message(message); } self.rest(); @@ -133,10 +135,29 @@ impl Brain { } } + fn broadcast_to_organs(&self, command: OrganCommand) { + for OrganSocket { tx, id } in &self.organ_sockets { + let envelope = OrganCommandEnvelope{ + command: command.clone(), + issued_at: Time::time_stamp_millis(), + }; + + debug!("sending command to organ {:?}.", id); + _ = tx.send(envelope); + } + } + fn is_ready(&self) -> bool { self.state != LifeState::Dead && self.state != Genisys && self.state != Buried } + + fn process_organ_message(&mut self, message: BrainMessage) { + debug!("organ message received: {:?}", message); + if let OrganCommand::Waken = message.organ_command.command { + self.state = LifeState::Awake; + } + } } diff --git a/src/rustylee/src/lifecycle.rs b/src/rustylee/src/lifecycle.rs index 99c05dc..fac54dd 100644 --- a/src/rustylee/src/lifecycle.rs +++ b/src/rustylee/src/lifecycle.rs @@ -7,7 +7,7 @@ pub enum LifeState { Genisys, // Sleeping, // Wakening, - // Awake, + Awake, // DeepThought, // ActionFocused, // Flight, @@ -23,7 +23,7 @@ impl fmt::Display for LifeState { LifeState::Genisys => "In Genesis", // LifeState::Sleeping => "Sleeping", // LifeState::Wakening => "Wakening", - // LifeState::Awake => "Fully Awake", + LifeState::Awake => "Fully Awake", // LifeState::DeepThought => "In Deep Thought", // LifeState::ActionFocused => "Action Focused", // LifeState::Flight => "In Flight", diff --git a/src/rustylee/src/organs/heart.rs b/src/rustylee/src/organs/heart.rs index 8cf1afd..8f5699d 100644 --- a/src/rustylee/src/organs/heart.rs +++ b/src/rustylee/src/organs/heart.rs @@ -1,6 +1,7 @@ use std::sync::mpsc; use std::sync::mpsc::{Receiver, Sender}; use tracing::{debug, info, instrument}; +use crate::lifecycle::LifeState; use crate::protocols::{BrainMessage, OrganCommand, OrganCommandEnvelope, OrganResponse}; use crate::system::time::Time; @@ -10,6 +11,7 @@ pub struct Heart { feedback_to_brain_tx: mpsc::Sender, last_beat_time: u64, timestamp: u64, + life_state: LifeState, } impl Heart { @@ -20,6 +22,7 @@ impl Heart { feedback_to_brain_tx: tx, last_beat_time: 0, timestamp: 0, + life_state: LifeState::Dead, } } @@ -32,36 +35,47 @@ impl Heart { debug!("Received brain command: {:?}", envelope); match envelope.command { + OrganCommand::Waken => { + self.wake_up(envelope); + } + OrganCommand::Beat(_) => { if self.ready_to_beat() { - self.beat(); + self.beat(envelope); } } _ => { - + self.send_response_brain(envelope, OrganResponse::Ignored) } } - - let response = OrganResponse::Ok; - - self.send_response_brain(envelope, response); } } fn ready_to_beat(&self) -> bool { - self.timestamp >= self.last_beat_time + 500 + self.is_ready_state() && self.timestamp >= self.last_beat_time + 500 } - fn beat(&mut self) { + fn is_ready_state(&self) -> bool { + self.life_state == LifeState::Awake + } + + fn beat(&mut self, command_envelope: OrganCommandEnvelope) { self.last_beat_time = self.timestamp; - info!("Beat time: {}", self.last_beat_time); + debug!("Beat time: {}", self.last_beat_time); + self.send_response_brain(command_envelope, OrganResponse::Ok); } - fn send_response_brain(&self, envelope: OrganCommandEnvelope, response: OrganResponse) { + fn wake_up(&mut self, command_envelope: OrganCommandEnvelope) { + self.life_state = LifeState::Awake; + debug!("Awake"); + self.send_response_brain(command_envelope, OrganResponse::Ok); + } + + fn send_response_brain(&self, command_envelope: OrganCommandEnvelope, response: OrganResponse) { let reply = BrainMessage { - organ_command: envelope, - responded_at: self.timestamp, + organ_command: command_envelope, + responded_at: Time::time_stamp_millis(), response, }; diff --git a/src/rustylee/src/protocols.rs b/src/rustylee/src/protocols.rs index 5e3bc9b..86b8e89 100644 --- a/src/rustylee/src/protocols.rs +++ b/src/rustylee/src/protocols.rs @@ -1,9 +1,9 @@ use crate::coordinates::Point3D; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum OrganCommand { // Sleep, - // Waken, + Waken, // Pause, // Resume, Beat (u32), @@ -19,6 +19,7 @@ pub enum OrganCommand { #[derive(Debug)] pub enum OrganResponse { Ok, + Ignored, Rejected }