use std::collections::BTreeSet;
use concinnity_core::components::{procedural_mesh, sdf_volume};
use concinnity_core::ecs::PipelineContext;
use concinnity_core::resource::AudioClipTable;
pub(super) fn retained_blobs(ctx: &PipelineContext) -> BTreeSet<u32> {
let mut retained = ctx
.resource::<AudioClipTable>()
.map(|table| table.blob_indices())
.unwrap_or_default();
retained.extend(sdf_volume::sdf_volume_blob_indices(ctx));
retained.extend(procedural_mesh::heightfield_blob_indices(ctx));
retained
}
pub(super) fn blobs_to_release(
consumed: impl IntoIterator<Item = u32>,
retained: &BTreeSet<u32>,
) -> Vec<u32> {
let mut seen = BTreeSet::new();
consumed
.into_iter()
.filter(|idx| !retained.contains(idx) && seen.insert(*idx))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_duplicate_blob_is_released_once_in_first_seen_order() {
let released = blobs_to_release([3, 1, 3, 2, 1], &BTreeSet::new());
assert_eq!(released, vec![3, 1, 2]);
}
#[test]
fn a_retained_blob_is_never_released() {
let retained = BTreeSet::from([1, 4]);
let released = blobs_to_release([1, 2, 4, 2, 5], &retained);
assert_eq!(released, vec![2, 5]);
}
}