mod error;
mod filter;
pub use error::GainError;
pub use filter::{DeviceTransducerMask, TransducerMask};
use crate::{
datagram::DeviceMask,
environment::Environment,
firmware::Drive,
firmware::{Segment, transition_mode::TransitionModeParams},
geometry::{Device, Geometry, Transducer},
};
pub trait GainCalculator<'a>: Send + Sync {
#[must_use]
fn calc(&self, tr: &'a Transducer) -> Drive;
}
impl<'a> GainCalculator<'a> for Box<dyn GainCalculator<'a>> {
fn calc(&self, tr: &'a Transducer) -> Drive {
self.as_ref().calc(tr)
}
}
pub trait GainCalculatorGenerator<'a> {
type Calculator: GainCalculator<'a>;
#[must_use]
fn generate(&mut self, device: &'a Device) -> Self::Calculator;
}
pub trait Gain<'a>: Sized {
type G: GainCalculatorGenerator<'a>;
fn init(
self,
geometry: &'a Geometry,
env: &Environment,
filter: &TransducerMask,
) -> Result<Self::G, GainError>;
}
#[doc(hidden)]
pub struct GainOperationGenerator<'a, G> {
pub generator: G,
pub segment: Segment,
pub transition_params: TransitionModeParams,
pub __phantom: core::marker::PhantomData<&'a ()>,
}
impl<'a, C: GainCalculatorGenerator<'a>> GainOperationGenerator<'a, C> {
pub fn new<G: Gain<'a, G = C>>(
gain: G,
geometry: &'a Geometry,
env: &Environment,
filter: &DeviceMask,
segment: Segment,
transition_params: TransitionModeParams,
) -> Result<Self, GainError> {
Ok(Self {
generator: gain.init(geometry, env, &TransducerMask::from(filter))?,
segment,
transition_params,
__phantom: core::marker::PhantomData,
})
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct GainInspectionResult {
pub data: Vec<Drive>,
}