use super::message::*; use crate::{ events::{EventStore, GlobalEvents, TrackEvent}, tracks::{TrackHandle, TrackState}, }; use flume::Receiver; use tracing::{debug, info, instrument, trace}; #[instrument(skip(_interconnect, evt_rx))] pub(crate) async fn runner(_interconnect: Interconnect, evt_rx: Receiver) { let mut global = GlobalEvents::default(); let mut events: Vec = vec![]; let mut states: Vec = vec![]; let mut handles: Vec = vec![]; loop { use EventMessage::*; match evt_rx.recv_async().await { Ok(AddGlobalEvent(data)) => { info!("Global event added."); global.add_event(data); }, Ok(AddTrackEvent(i, data)) => { info!("Adding event to track {}.", i); let event_store = events .get_mut(i) .expect("Event thread was given an illegal store index for AddTrackEvent."); let state = states .get_mut(i) .expect("Event thread was given an illegal state index for AddTrackEvent."); event_store.add_event(data, state.position); }, Ok(FireCoreEvent(ctx)) => { let ctx = ctx.to_user_context(); let evt = ctx .to_core_event() .expect("Event thread was passed a non-core event in FireCoreEvent."); trace!("Firing core event {:?}.", evt); global.fire_core_event(evt, ctx).await; }, Ok(RemoveGlobalEvents) => { global.remove_handlers(); }, Ok(AddTrack(store, state, handle)) => { events.push(store); states.push(state); handles.push(handle); info!("Event state for track {} added", events.len()); }, Ok(ChangeState(i, change)) => { use TrackStateChange::*; let max_states = states.len(); debug!( "Changing state for track {} of {}: {:?}", i, max_states, change ); let state = states .get_mut(i) .expect("Event thread was given an illegal state index for ChangeState."); match change { Mode(mode) => { let old = state.playing; state.playing = mode; if old != mode { global.fire_track_event(mode.as_track_event(), i); } }, Volume(vol) => { state.volume = vol; }, Position(pos) => { // Currently, only Tick should fire time events. state.position = pos; }, Loops(loops, user_set) => { state.loops = loops; if !user_set { global.fire_track_event(TrackEvent::Loop, i); } }, Total(new) => { // Massive, unprecedented state changes. *state = new; }, } }, Ok(RemoveTrack(i)) => { info!("Event state for track {} of {} removed.", i, events.len()); events.swap_remove(i); states.swap_remove(i); handles.swap_remove(i); }, Ok(RemoveAllTracks) => { info!("Event state for all tracks removed."); events.clear(); states.clear(); handles.clear(); }, Ok(Tick) => { // NOTE: this should fire saved up blocks of state change evts. global.tick(&mut events, &mut states, &mut handles).await; }, Err(_) | Ok(Poison) => { break; }, } } trace!("Event thread exited."); }