start ui: implement sending ports to the display thread from a background thread
This commit is contained in:
parent
de6dd59e48
commit
40c08b91fb
3 changed files with 48 additions and 10 deletions
|
@ -15,15 +15,9 @@ fn main() {
|
|||
|
||||
midi_keys::ui::run();
|
||||
|
||||
match run() {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
println!("Ended with error: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
pub fn run() -> Result<()> {
|
||||
let midi_in = MidiInput::new("keyboard")?;
|
||||
|
||||
let midi_device = match find_first_midi_device(&midi_in) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use nom::{
|
||||
bytes::complete::{tag, take, take_till},
|
||||
combinator::opt,
|
||||
IResult,
|
||||
};
|
||||
|
||||
|
|
49
src/ui.rs
49
src/ui.rs
|
@ -1,8 +1,12 @@
|
|||
use std::time::Instant;
|
||||
use std::{sync::Arc, thread::JoinHandle, time::Instant};
|
||||
|
||||
use egui::mutex::Mutex;
|
||||
use midir::{MidiInput, MidiInputPort};
|
||||
|
||||
/// Launches the UI and runs it until it's done executing.
|
||||
pub fn run() {
|
||||
let native_options = eframe::NativeOptions::default();
|
||||
|
||||
// TODO: don't ignore result
|
||||
let _ = eframe::run_native(
|
||||
"Midi Keys",
|
||||
|
@ -13,21 +17,32 @@ pub fn run() {
|
|||
|
||||
struct MidiKeysApp {
|
||||
previous_frame_time: Instant,
|
||||
midi_input_ports: Arc<Mutex<Vec<MidiInputPort>>>,
|
||||
midi_in: MidiInput,
|
||||
}
|
||||
|
||||
impl MidiKeysApp {
|
||||
fn new(_cc: &eframe::CreationContext<'_>) -> Self {
|
||||
// this is where to hook in for customizing eguji, like fonts and visuals.
|
||||
|
||||
let midi_in: MidiInput =
|
||||
MidiInput::new("midi-keys").expect("could not connect to system MIDI");
|
||||
let midi_input_ports = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
// TODO: have a way to shut down the midi daemon?
|
||||
let _ = launch_midi_daemon(midi_input_ports.clone());
|
||||
|
||||
let previous_frame_time = Instant::now();
|
||||
MidiKeysApp {
|
||||
previous_frame_time,
|
||||
midi_input_ports,
|
||||
midi_in,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl eframe::App for MidiKeysApp {
|
||||
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
let duration = self.previous_frame_time.elapsed().as_secs_f32();
|
||||
self.previous_frame_time = Instant::now();
|
||||
|
||||
|
@ -36,6 +51,36 @@ impl eframe::App for MidiKeysApp {
|
|||
|
||||
let framerate = format!("{:>8.2}", 1. / duration);
|
||||
ui.label(framerate);
|
||||
|
||||
for input_port in self.midi_input_ports.lock().iter() {
|
||||
let port_name = self
|
||||
.midi_in
|
||||
.port_name(input_port)
|
||||
.unwrap_or("unknown".to_string());
|
||||
|
||||
ui.label(port_name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn launch_midi_daemon(target_field: Arc<Mutex<Vec<MidiInputPort>>>) -> JoinHandle<()> {
|
||||
let daemon_handle = std::thread::spawn(move || midi_daemon(target_field));
|
||||
|
||||
daemon_handle
|
||||
}
|
||||
|
||||
pub fn midi_daemon(target_field: Arc<Mutex<Vec<MidiInputPort>>>) {
|
||||
let midi_in: MidiInput = MidiInput::new("midi-keys").expect("could not connect to system MIDI");
|
||||
|
||||
loop {
|
||||
let midi_input_ports = get_connnected_midi_devices(&midi_in);
|
||||
*target_field.lock() = midi_input_ports;
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_connnected_midi_devices(midi_in: &MidiInput) -> Vec<MidiInputPort> {
|
||||
midi_in.ports()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue