dramatically simplify alarm handling
This commit is contained in:
parent
b347386e99
commit
628a8e73d6
3 changed files with 23 additions and 53 deletions
|
@ -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),
|
||||
}
|
||||
|
|
10
src/timer.rs
10
src/timer.rs
|
@ -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
|
||||
};
|
||||
|
|
58
src/util.rs
58
src/util.rs
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue