use std::marker::PhantomData;
use bevy::prelude::{Component, Entity};
const DECAY_RATE: f32 = 0.8;
#[derive(Component)]
pub(crate) struct DecayingCache<M> {
entities: Vec<Entity>,
capacity: f32,
_m: PhantomData<M>,
}
impl<M> DecayingCache<M> {
pub(crate) fn entities(&self) -> &[Entity] {
self.entities.as_slice()
}
pub(crate) fn clear(&mut self) {
self.entities.clear()
}
pub(crate) fn extend<I>(&mut self, entities: I)
where
I: IntoIterator<Item = Entity>,
{
self.entities.extend(entities);
}
pub(crate) fn decay(&mut self, delta_seconds: f32) {
debug_assert!(delta_seconds >= 0.);
let factor = DECAY_RATE.powf(delta_seconds);
self.capacity = (self.capacity * factor).max(self.entities.len() as f32);
let desired = self.capacity.ceil() as usize;
debug_assert!(desired >= self.entities.len());
if desired <= (self.entities.capacity() / 2) {
self.entities.shrink_to(desired);
}
}
}
impl<M> Default for DecayingCache<M> {
fn default() -> Self {
DecayingCache {
entities: Vec::new(),
capacity: 0.,
_m: PhantomData,
}
}
}