Make main loop delay conditional.

This commit is contained in:
shy 2021-04-10 12:52:37 +02:00
parent 0b40242baa
commit f5490eb96b
2 changed files with 27 additions and 21 deletions

View file

@ -1,6 +1,6 @@
extern crate termion; extern crate termion;
use std::{time, thread}; use std::{process, thread, time};
use std::io::Write; use std::io::Write;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
@ -9,6 +9,7 @@ use termion::{clear, color, cursor, style};
use termion::raw::{IntoRawMode, RawTerminal}; use termion::raw::{IntoRawMode, RawTerminal};
use termion::event::Key; use termion::event::Key;
use termion::input::TermRead; use termion::input::TermRead;
//use termion::cursor::DetectCursorPos;
use crate::clock::Clock; use crate::clock::Clock;
use crate::alarm::{Countdown, AlarmRoster, exec_command}; use crate::alarm::{Countdown, AlarmRoster, exec_command};
use crate::layout::Layout; use crate::layout::Layout;
@ -21,27 +22,29 @@ pub fn kitchentimer(
mut alarm_roster: AlarmRoster, mut alarm_roster: AlarmRoster,
signal: Arc<AtomicUsize>, signal: Arc<AtomicUsize>,
sigwinch: Arc<AtomicBool>, sigwinch: Arc<AtomicBool>,
spawned: &mut Option<std::process::Child>, spawned: &mut Option<process::Child>,
) -> Result<(), std::io::Error> { ) -> Result<(), std::io::Error>
{
let mut layout = Layout::new(&config); let mut layout = Layout::new(&config);
layout.force_recalc = sigwinch; layout.force_recalc = sigwinch;
// Initialise roster_width. // Initialise roster_width.
layout.set_roster_width(alarm_roster.width()); layout.set_roster_width(alarm_roster.width());
let mut clock = Clock::new(); let mut clock = Clock::new();
let mut countdown = Countdown::new(); let mut countdown = Countdown::new();
let mut buffer = String::new(); let mut buffer = String::new();
let mut input_keys = termion::async_stdin().keys();
// State variables. // State variables.
let mut update_buffer = false; let mut update_buffer = false;
let mut update_menu = false; let mut update_menu = false;
let mut insert_mode = false; let mut insert_mode = false;
let mut stdout = std::io::stdout().into_raw_mode() let async_stdin = termion::async_stdin();
let mut input_keys = async_stdin.keys();
let stdout = std::io::stdout();
let mut stdout = stdout.lock().into_raw_mode()
.unwrap_or_else(|error| { .unwrap_or_else(|error| {
eprintln!("Error opening stdout: {}", error); eprintln!("Error opening stdout: {}", error);
std::process::exit(1); process::exit(1);
}); });
// Clear window and hide cursor. // Clear window and hide cursor.
@ -51,7 +54,7 @@ pub fn kitchentimer(
cursor::Hide) cursor::Hide)
.unwrap_or_else(|error| { .unwrap_or_else(|error| {
eprintln!("Error writing to stdout: {}", error); eprintln!("Error writing to stdout: {}", error);
std::process::exit(1); process::exit(1);
}); });
// Enter main loop. // Enter main loop.
@ -190,6 +193,9 @@ pub fn kitchentimer(
// Any other key. // Any other key.
_ => (), _ => (),
} }
} else {
// Main loop delay.
thread::sleep(time::Duration::from_millis(200));
} }
// Update input buffer display. // Update input buffer display.
@ -316,9 +322,6 @@ pub fn kitchentimer(
layout.force_redraw = false; layout.force_redraw = false;
stdout.flush()?; stdout.flush()?;
} }
// Main loop delay.
thread::sleep(time::Duration::from_millis(100));
} }
// Main loop exited. Clear window and restore cursor. // Main loop exited. Clear window and restore cursor.
@ -346,6 +349,9 @@ fn draw_buffer<W: Write>(
cursor::Show, cursor::Show,
buffer)?; buffer)?;
layout.cursor.col = layout.buffer.col + 11 + unicode_length(buffer); layout.cursor.col = layout.buffer.col + 11 + unicode_length(buffer);
// TODO: This would be a much better alternative, but panics because
// of interference with async_reader.
//layout.cursor.col = stdout.cursor_pos()?.0;
} else { } else {
// Clear buffer display. // Clear buffer display.
write!(stdout, write!(stdout,
@ -402,7 +408,7 @@ fn restore_after_suspend<W: Write>(stdout: &mut RawTerminal<W>) {
stdout.activate_raw_mode() stdout.activate_raw_mode()
.unwrap_or_else(|error| { .unwrap_or_else(|error| {
eprintln!("Failed to re-enter raw terminal mode after suspend: {}", error); eprintln!("Failed to re-enter raw terminal mode after suspend: {}", error);
std::process::exit(1); process::exit(1);
}); });
write!(stdout, write!(stdout,
"{}{}", "{}{}",
@ -410,7 +416,7 @@ fn restore_after_suspend<W: Write>(stdout: &mut RawTerminal<W>) {
cursor::Hide) cursor::Hide)
.unwrap_or_else(|error| { .unwrap_or_else(|error| {
eprintln!("Error writing to stdout: {}", error); eprintln!("Error writing to stdout: {}", error);
std::process::exit(1); process::exit(1);
}); });
} }

View file

@ -8,7 +8,7 @@ mod utils;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
use std::env; use std::{env, process};
use std::io::Write; use std::io::Write;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::sync::atomic::{AtomicBool, AtomicUsize};
@ -42,7 +42,7 @@ fn main() {
let sigwinch = Arc::new(AtomicBool::new(true)); let sigwinch = Arc::new(AtomicBool::new(true));
register_signal_handlers(&signal, &sigwinch); register_signal_handlers(&signal, &sigwinch);
// Spawned child process if any. // Spawned child process if any.
let mut spawned: Option<std::process::Child> = None; let mut spawned: Option<process::Child> = None;
// Runs main loop. // Runs main loop.
match kitchentimer( match kitchentimer(
@ -53,7 +53,7 @@ fn main() {
&mut spawned, &mut spawned,
) { ) {
Ok(_) => (), Ok(_) => (),
Err(e) => eprintln!("Error: {}", e), Err(e) => eprintln!("Main loop exited with error: {}", e),
} }
// Wait for remaining spawned processes to exit. // Wait for remaining spawned processes to exit.
@ -71,7 +71,7 @@ fn main() {
// Print usage information and exit. // Print usage information and exit.
fn usage() { fn usage() {
println!("{}", USAGE); println!("{}", USAGE);
std::process::exit(0); process::exit(0);
} }
// Parse command line arguments into "config". // Parse command line arguments into "config".
@ -84,7 +84,7 @@ fn parse_args(config: &mut Config, alarm_roster: &mut AlarmRoster) {
"-h" | "--help" => usage(), "-h" | "--help" => usage(),
"-v" | "--version" => { "-v" | "--version" => {
println!("{} {}", NAME, VERSION); println!("{} {}", NAME, VERSION);
std::process::exit(0); process::exit(0);
}, },
"-p" | "--plain" => config.plain = true, "-p" | "--plain" => config.plain = true,
"-q" | "--quit" => config.quit = true, "-q" | "--quit" => config.quit = true,
@ -93,20 +93,20 @@ fn parse_args(config: &mut Config, alarm_roster: &mut AlarmRoster) {
config.command = Some(parse_to_command(&e)); config.command = Some(parse_to_command(&e));
} else { } else {
println!("Missing parameter to \"{}\".", arg); println!("Missing parameter to \"{}\".", arg);
std::process::exit(1); process::exit(1);
} }
}, },
any if any.starts_with('-') => { any if any.starts_with('-') => {
// Unrecognized flag. // Unrecognized flag.
println!("Unrecognized option: \"{}\"", any); println!("Unrecognized option: \"{}\"", any);
println!("Use \"-h\" or \"--help\" for a list of valid command line options"); println!("Use \"-h\" or \"--help\" for a list of valid command line options");
std::process::exit(1); process::exit(1);
}, },
any => { any => {
// Alarm to add. // Alarm to add.
if let Err(error) = alarm_roster.add(&String::from(any)) { if let Err(error) = alarm_roster.add(&String::from(any)) {
println!("Error adding \"{}\" as alarm. ({})", any, error); println!("Error adding \"{}\" as alarm. ({})", any, error);
std::process::exit(1); process::exit(1);
} }
}, },
} }