dramatically simplify alarm handling

This commit is contained in:
Joe Ardent 2022-10-22 12:01:53 -07:00
parent b347386e99
commit 628a8e73d6
3 changed files with 23 additions and 53 deletions

View file

@ -1,14 +1,6 @@
use std::ffi::OsString;
pub const AIRHORN: &[u8] = include_bytes!("../airhorn_alarm.mp3");
pub const PREDATOR_FONT: &[u8] = include_bytes!("../Predator.ttf");
pub mod cli;
pub mod timer;
mod util;
#[derive(Debug, Clone)]
pub(crate) enum Alarm {
Airhon,
User(OsString),
}

View file

@ -5,7 +5,7 @@ use eframe::{App, CreationContext};
use egui::{Color32, Direction, FontId, Layout, RichText, Ui};
use egui_extras::{Size, StripBuilder};
use crate::{cli::Cli, util::*, Alarm, PREDATOR_FONT};
use crate::{cli::Cli, util::*, AIRHORN, PREDATOR_FONT};
const MIN_REPAINT: Duration = Duration::from_millis(100);
const MAX_REPAINT: Duration = Duration::from_millis(250);
@ -25,7 +25,7 @@ pub struct Timer {
duration: Duration,
state: TimerState,
tstart: Instant, // so we can blink
alarm: Option<Alarm>,
alarm: Option<Vec<u8>>,
}
#[derive(Debug, Clone, Copy)]
@ -96,9 +96,11 @@ impl Timer {
};
let alarm = if let Some(path) = cli.alarm {
Some(Alarm::User(path))
let buffer = std::fs::read(&path)
.unwrap_or_else(|_| panic!("Could not open {:?} for reading.", path));
Some(buffer)
} else if cli.airhorn {
Some(Alarm::Airhon)
Some(AIRHORN.to_owned())
} else {
None
};

View file

@ -1,55 +1,15 @@
use std::{
ffi::OsStr,
fs::File,
io::{Cursor, Read, Seek},
time::Duration,
};
use std::{io::Cursor, time::Duration};
use egui::{Color32, Direction, FontId, Layout, RichText};
use egui_extras::{Size, Strip};
use rodio::{source::Source, Decoder, OutputStream};
use crate::{Alarm, AIRHORN};
fn format_digits(digits: u64, size: f32, color: Color32) -> RichText {
RichText::new(format!("{:02}", digits))
.font(FontId::monospace(size))
.color(color)
}
pub(crate) fn alarm(source: Alarm) {
if let Alarm::User(path) = source {
play_user(&path)
} else {
let source = Cursor::new(AIRHORN.to_owned());
let decoder = Decoder::new(source).unwrap();
play_alarm(decoder);
}
}
fn play_user(path: &OsStr) {
let mut f = File::open(path).unwrap_or_else(|_| panic!("Could not open file {:?}", path));
let metadata = std::fs::metadata(path).expect("unable to read metadata");
let mut buffer = vec![0; metadata.len() as usize];
f.read_exact(&mut buffer).expect("buffer overflow");
let file = Cursor::new(buffer);
let source = Decoder::new(file).unwrap();
play_alarm(source);
}
fn play_alarm<S: Read + Seek + Send + 'static>(source: Decoder<S>) {
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let dur = if let Some(dur) = source.total_duration() {
dur
} else {
Duration::from_secs(10)
};
let _ = stream_handle.play_raw(source.convert_samples());
std::thread::sleep(dur);
}
pub(crate) fn display_digits(strip: &mut Strip, dur: Duration, color: Color32, size: f32) {
let hours = dur.as_secs() / 3600;
let minutes = (dur.as_secs() / 60) % 60;
@ -75,3 +35,19 @@ pub(crate) fn display_digits(strip: &mut Strip, dur: Duration, color: Color32, s
});
});
}
pub(crate) fn alarm(source: Vec<u8>) {
let source = Cursor::new(source);
let source = Decoder::new(source).unwrap();
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let dur = if let Some(dur) = source.total_duration() {
dur
} else {
Duration::from_secs(10)
};
let _ = stream_handle.play_raw(source.convert_samples());
std::thread::sleep(dur);
}