diff --git a/src/alarm.rs b/src/alarm.rs index 6dde088..363ddc4 100644 --- a/src/alarm.rs +++ b/src/alarm.rs @@ -76,8 +76,8 @@ impl Countdown { } pub struct Alarm { - time: u32, - label: String, + pub time: u32, + pub label: String, color_index: usize, exceeded: bool, } @@ -178,27 +178,28 @@ impl AlarmRoster { !self.list.iter().any(|a| !a.exceeded) } - // Check for exceeded alarms. + // Find and process exceeded alarms. pub fn check(&mut self, clock: &mut Clock, layout: &Layout, countdown: &mut Countdown, force_redraw: bool, - ) -> Option<(u32, &String)> + ) -> Option<&Alarm> { let mut ret = None; let size = self.list.len() as u16; - for (index, alarm) in self.list.iter_mut().enumerate() + for (index, alarm) in self.list.iter_mut() + .enumerate() // Ignore alarms marked exceeded. .filter(|(_, a)| !a.exceeded) { if alarm.time <= clock.elapsed { // Found alarm to raise. - ret = Some((alarm.time, &alarm.label)); alarm.exceeded = true; clock.color_index = Some(alarm.color_index); countdown.reset(); + ret = Some(&*alarm); // Skip ahead to the next one. continue; } @@ -332,9 +333,16 @@ impl AlarmRoster { } // Call when time jumps backwards. - pub fn time_travel(&mut self, time: u32) { + pub fn time_travel(&mut self, clock: &mut Clock) { + clock.color_index = None; + for alarm in self.list.iter_mut() { - alarm.exceeded = alarm.time <= time; + if alarm.time <= clock.elapsed { + alarm.exceeded = true; + clock.color_index = Some(alarm.color_index); + } else { + alarm.exceeded = false; + } } } @@ -344,21 +352,22 @@ impl AlarmRoster { { let mut buffer = String::new(); loop { + buffer.clear(); match stdin.read_line(&mut buffer) { Ok(0) => break, // EOF. Ok(1) => continue, // Empty (newline only). + Ok(_) if buffer.starts_with('#') => continue, Ok(_) => (), Err(e) => return Err(e.to_string()), } // Strip newline. - buffer.retain(|c| c != '\n'); + if buffer.ends_with('\n') { buffer.pop(); } // Ignore lines containing only white spaces. if buffer.contains(|c: char| !c.is_whitespace()) { if let Err(e) = self.add(&buffer) { - return Err(e.to_string()); + return Err(format!("Value \"{}\": {}",buffer, e)); } } - buffer.clear(); } Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index c7574cc..8a61680 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -119,8 +119,29 @@ pub fn run( Err(e) => return Err(e), } + // Check on last spawned child process prior to processing the + // alarm roster and possibly starting a new one. + if let Some(ref mut child) = spawned { + match child.try_wait() { + // Process exited successfully. + Ok(Some(status)) if status.success() => *spawned = None, + // Abnormal exit. + Ok(Some(status)) => { + eprintln!("Spawned process terminated with non-zero exit status. ({})", status); + *spawned = None; + }, + // Process is still running. + Ok(None) => (), + // Other error. + Err(error) => { + eprintln!("Error executing command. ({})", error); + *spawned = None; + }, + } + } + // Check for exceeded alarms. - if let Some((time, label)) = alarm_roster.check( + if let Some(alarm) = alarm_roster.check( &mut clock, &layout, &mut countdown, @@ -136,7 +157,7 @@ pub fn run( match config.command { // Run command if configured and no command is running. Some(ref command) if spawned.is_none() => { - *spawned = exec_command(command, time, &label); + *spawned = exec_command(command, alarm.time, &alarm.label); }, // Last command is still running. Some(_) => eprintln!("Not executing command, as its predecessor is still running"), @@ -184,26 +205,6 @@ pub fn run( countdown.draw(&mut stdout)?; } - // Check any spawned child process. - if let Some(ref mut child) = spawned { - match child.try_wait() { - // Process exited successfully. - Ok(Some(status)) if status.success() => *spawned = None, - // Abnormal exit. - Ok(Some(status)) => { - eprintln!("Spawned process terminated with non-zero exit status. ({})", status); - *spawned = None; - }, - // Process is still running. - Ok(None) => (), - // Other error. - Err(error) => { - eprintln!("Error executing command. ({})", error); - *spawned = None; - }, - } - } - // End of conditional inner loop. // Reset redraw_all and flush stdout. force_redraw = false; @@ -269,7 +270,7 @@ pub fn run( }, Key::Down if clock.paused => { clock.shift(-10); - alarm_roster.time_travel(clock.elapsed); + alarm_roster.time_travel(&mut clock); layout.schedule_recalc(); force_redraw = true; }, diff --git a/src/main.rs b/src/main.rs index cfc47e1..f5048a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,7 @@ fn main() { // Wait for remaining spawned processes to exit. if let Some(ref mut child) = spawned { - eprint!("Waiting for spawned process (PID {}) to exit ...", child.id()); + eprint!("Waiting for spawned process (PID {}) to finish ...", child.id()); match child.wait() { Ok(status) => eprintln!(" ok ({})", status),