Limit set of active audio cells to only those enabled

main
Elijah Voigt 3 hours ago
parent 2665ffb3c5
commit e89886382d

@ -56,7 +56,6 @@ fn main() {
load_audio_tones, load_audio_tones,
load_materials, load_materials,
load_meshes, load_meshes,
spawn_audio_players.after(load_audio_tones),
), ),
) )
.configure_sets( .configure_sets(
@ -111,7 +110,14 @@ fn main() {
.add_systems( .add_systems(
Update, Update,
( (
control_audio_players.run_if(any_component_changed::<Cell>.or_else(state_changed::<SimulationPlayback>).or_else(state_changed::<AudioPlayback>)).in_set(GameSet::React), control_audio_players
.run_if(
on_message::<Lifecycle>
.or_else(state_changed::<SimulationPlayback>)
.or_else(state_changed::<AudioPlayback>),
)
.in_set(GameSet::React),
manage_audio_players.run_if(resource_changed::<PitchMap>),
update_pitch_map_resource_ui.run_if(resource_changed::<PitchMap>), update_pitch_map_resource_ui.run_if(resource_changed::<PitchMap>),
), ),
) )
@ -122,6 +128,7 @@ fn main() {
grid_gizmo, grid_gizmo,
update_debug_info_coordinates, update_debug_info_coordinates,
( (
#[cfg(debug_assertions)]
assert_cell_uniqueness assert_cell_uniqueness
.run_if(any_with_component::<Cell>) .run_if(any_with_component::<Cell>)
.after(update_material), .after(update_material),
@ -784,6 +791,7 @@ fn is_ui_hovered(hovered: Query<&Hovered>) -> bool {
hovered.iter().any(|Hovered(h)| *h) hovered.iter().any(|Hovered(h)| *h)
} }
#[cfg(debug_assertions)]
fn assert_cell_uniqueness(q: Query<(Entity, &Coordinates), With<Cell>>) { fn assert_cell_uniqueness(q: Query<(Entity, &Coordinates), With<Cell>>) {
q.iter().for_each(|(e1, c1)| { q.iter().for_each(|(e1, c1)| {
q.iter().for_each(|(e2, c2)| { q.iter().for_each(|(e2, c2)| {
@ -1231,6 +1239,18 @@ impl PitchMap {
// always ensure the notes list is sorted // always ensure the notes list is sorted
self.notes.sort(); self.notes.sort();
} }
// Return an iterator over all enabled CellPitch values
fn iter_enabled_cell_pitches(&self) -> impl Iterator<Item = CellPitch> {
self.notes.iter().flat_map(|n| {
(0..=self.octaves)
.map(|o| o as isize)
.map(|o| o - (o / 2))
.map(|o| {
CellPitch { note: n.clone(), octave: o }
})
})
}
} }
#[test] #[test]
@ -1383,15 +1403,35 @@ fn update_camera_position(mut query: Query<(&Coordinates, &mut Transform), With<
}); });
} }
// Ordering: first, once, after(load_audio_tones) // Run when PitchMap changes to ensure we have just the audio sinks we need
fn spawn_audio_players(mut commands: Commands, cell_assets: Res<CellAssets>) { fn manage_audio_players(
mut commands: Commands,
cell_assets: Res<CellAssets>,
pitch_map: Res<PitchMap>,
current: Query<(Entity, &CellPitch), With<AudioSink>>,
mut active: Local<HashSet<CellPitch>>,
) {
*active = pitch_map.iter_enabled_cell_pitches().collect();
CellPitch::iter_all().for_each(|cp| { CellPitch::iter_all().for_each(|cp| {
let h = cell_assets.pitches.get(&cp).unwrap().clone(); // The cell is active, ensure it has an audio entity
commands.spawn((AudioPlayer(h), cp, PlaybackSettings::default().muted())); if active.contains(&cp) {
}); if !current.iter().any(|(_this_e, this_cp)| *this_cp == cp) {
let h = cell_assets.pitches.get(&cp).unwrap().clone();
commands.spawn((AudioPlayer(h), cp, PlaybackSettings::default().muted()));
}
}
// The cell is inactive, ensure it does not have an audio entity
else {
if let Some(e) = current
.iter()
.find_map(|(this_e, this_cp)| (*this_cp == cp).then_some(this_e))
{
commands.entity(e).despawn();
}
}
})
} }
// Ordering: React
fn control_audio_players( fn control_audio_players(
audio_state: Res<State<AudioPlayback>>, audio_state: Res<State<AudioPlayback>>,
simulation_state: Res<State<SimulationPlayback>>, simulation_state: Res<State<SimulationPlayback>>,

Loading…
Cancel
Save