use super::super::simulation::{SharedSources, SourceWithInputs};
use super::super::step::{
AsReflectionsReverbInput, ReflectionsReverbInput, ReflectionsReverbOutput,
};
use super::{Allocate, Clear, Resolve, Shrink, SourcesGuard};
use crate::effect::ReflectionEffectType;
use crate::simulation::{ReflectionEffectCompatible, Reflections, SimulationSharedInputs};
use std::collections::HashMap;
use std::hash::Hash;
#[cfg(doc)]
use super::super::simulation::Simulation;
pub struct ReflectionsReverbFrame<SourceId, D, R, P, RE, LD = D, LP = P>
where
RE: ReflectionEffectCompatible<R, RE>,
{
pub sources: SharedSources<SourceId, D, R, P, RE>,
pub listener: Option<SourceWithInputs<LD, R, LP, RE>>,
pub shared_inputs: SimulationSharedInputs<D, R, P>,
}
impl<SourceId, RE> Clear for ReflectionsReverbOutput<SourceId, RE>
where
SourceId: Hash + Eq,
RE: ReflectionEffectType,
{
fn clear(&mut self) {
self.sources.clear();
self.listener = None;
}
}
impl<SourceId, RE> Shrink for ReflectionsReverbOutput<SourceId, RE>
where
SourceId: Hash + Eq,
RE: ReflectionEffectType,
{
fn shrink(&mut self) {
if self.sources.capacity() > self.sources.len() * 3 {
self.sources.shrink_to_fit();
}
}
}
impl<SourceId, D, R, P, RE, LD, LP> Resolve
for ReflectionsReverbFrame<SourceId, D, R, P, RE, LD, LP>
where
RE: ReflectionEffectCompatible<R, RE>,
{
type Resolved<'a>
= ResolvedReflectionsReverbFrame<'a, SourceId, D, R, P, RE, LD, LP>
where
Self: 'a;
fn resolve(&self) -> Self::Resolved<'_> {
ResolvedReflectionsReverbFrame {
guard: self.sources.load(),
listener: self.listener.as_ref(),
shared_inputs: &self.shared_inputs,
}
}
}
pub struct ResolvedReflectionsReverbFrame<'a, SourceId, D, R, P, RE, LD, LP> {
guard: SourcesGuard<SourceId, D, R, P, RE>,
listener: Option<&'a SourceWithInputs<LD, R, LP, RE>>,
shared_inputs: &'a SimulationSharedInputs<D, R, P>,
}
impl<SourceId, D, R, P, RE, LD, LP> AsReflectionsReverbInput<SourceId, D, R, P, RE>
for ResolvedReflectionsReverbFrame<'_, SourceId, D, R, P, RE, LD, LP>
where
RE: ReflectionEffectCompatible<R, RE>,
{
type LD = LD;
type LP = LP;
fn as_reflections_reverb_input(
&self,
) -> ReflectionsReverbInput<'_, SourceId, D, R, P, RE, LD, LP> {
ReflectionsReverbInput {
sources: &self.guard,
listener: self.listener,
shared_inputs: self.shared_inputs,
}
}
}
impl<SourceId, D, P, RE, LD, LP>
Allocate<ResolvedReflectionsReverbFrame<'_, SourceId, D, Reflections, P, RE, LD, LP>>
for ReflectionsReverbOutput<SourceId, RE>
where
SourceId: Hash + Eq,
RE: ReflectionEffectType + ReflectionEffectCompatible<Reflections, RE>,
{
fn allocate(
input: &ResolvedReflectionsReverbFrame<'_, SourceId, D, Reflections, P, RE, LD, LP>,
) -> Self {
Self {
sources: HashMap::with_capacity(input.guard.len()),
listener: None,
}
}
}