use e_midi_shared::ipc;
use e_midi_shared::ipc_protocol::MidiNoteEvent;
use iceoryx2::prelude::*;
use std::io::{BufRead, BufReader};
use std::process::{Command, Stdio};
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("\n=== Example 02: Persistent Event Listener Demo ===");
println!("This demo launches e_midi to play song 0 with IPC enabled, then listens for and displays all incoming MIDI note events.\n");
println!("- It will show events from the e_midi it launches, and from any other e_midi process that publishes events with IPC enabled.");
println!("- Useful for debugging and monitoring event flow.\n");
println!("(Press Ctrl+C to exit)\n");
println!("[demo02_event_listener] Spawning e_midi server: e_midi --ipc play 0");
let mut child = Command::new("e_midi")
.arg("--ipc")
.arg("play")
.arg("0")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let stdout = child.stdout.take().unwrap();
let stderr = child.stderr.take().unwrap();
let stdout_reader = BufReader::new(stdout);
let stderr_reader = BufReader::new(stderr);
std::thread::spawn(move || {
for line in stdout_reader.lines().map_while(Result::ok) {
println!("[e_midi stdout] {}", line);
}
});
std::thread::spawn(move || {
for line in stderr_reader.lines().map_while(Result::ok) {
eprintln!("[e_midi stderr] {}", line);
}
});
std::thread::sleep(Duration::from_secs(2));
let node = NodeBuilder::new().create::<iceoryx2::service::ipc::Service>()?;
let event_service = node
.service_builder(&ServiceName::new(ipc::EMIDI_EVENTS_SERVICE)?)
.publish_subscribe::<MidiNoteEvent>()
.open()?;
let event_subscriber = event_service.subscriber_builder().create()?;
println!("[demo02_event_listener] Connected to IPC event stream using shared library (zero-copy MidiNoteEvent)");
loop {
match event_subscriber.receive() {
Ok(samples) => {
if let Some(sample) = samples {
let midi_event: &MidiNoteEvent = sample.payload();
println!(
"[demo02_event_listener] MidiNoteEvent: kind={}, channel={}, pitch={}, velocity={}, timestamp={}",
midi_event.kind, midi_event.channel, midi_event.pitch, midi_event.velocity, midi_event.timestamp
);
}
}
Err(e) => {
eprintln!("[demo02_event_listener] Error receiving events: {}. Will attempt to reconnect...", e);
std::thread::sleep(Duration::from_millis(200));
}
}
std::thread::sleep(Duration::from_millis(10));
}
}