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();
|
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_in = MidiInput::new("keyboard")?;
|
||||||
|
|
||||||
let midi_device = match find_first_midi_device(&midi_in) {
|
let midi_device = match find_first_midi_device(&midi_in) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use nom::{
|
use nom::{
|
||||||
bytes::complete::{tag, take, take_till},
|
bytes::complete::{tag, take, take_till},
|
||||||
combinator::opt,
|
|
||||||
IResult,
|
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.
|
/// Launches the UI and runs it until it's done executing.
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let native_options = eframe::NativeOptions::default();
|
let native_options = eframe::NativeOptions::default();
|
||||||
|
|
||||||
// TODO: don't ignore result
|
// TODO: don't ignore result
|
||||||
let _ = eframe::run_native(
|
let _ = eframe::run_native(
|
||||||
"Midi Keys",
|
"Midi Keys",
|
||||||
|
@ -13,21 +17,32 @@ pub fn run() {
|
||||||
|
|
||||||
struct MidiKeysApp {
|
struct MidiKeysApp {
|
||||||
previous_frame_time: Instant,
|
previous_frame_time: Instant,
|
||||||
|
midi_input_ports: Arc<Mutex<Vec<MidiInputPort>>>,
|
||||||
|
midi_in: MidiInput,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MidiKeysApp {
|
impl MidiKeysApp {
|
||||||
fn new(_cc: &eframe::CreationContext<'_>) -> Self {
|
fn new(_cc: &eframe::CreationContext<'_>) -> Self {
|
||||||
// this is where to hook in for customizing eguji, like fonts and visuals.
|
// 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();
|
let previous_frame_time = Instant::now();
|
||||||
MidiKeysApp {
|
MidiKeysApp {
|
||||||
previous_frame_time,
|
previous_frame_time,
|
||||||
|
midi_input_ports,
|
||||||
|
midi_in,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl eframe::App for MidiKeysApp {
|
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();
|
let duration = self.previous_frame_time.elapsed().as_secs_f32();
|
||||||
self.previous_frame_time = Instant::now();
|
self.previous_frame_time = Instant::now();
|
||||||
|
|
||||||
|
@ -36,6 +51,36 @@ impl eframe::App for MidiKeysApp {
|
||||||
|
|
||||||
let framerate = format!("{:>8.2}", 1. / duration);
|
let framerate = format!("{:>8.2}", 1. / duration);
|
||||||
ui.label(framerate);
|
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