1mod error;
2mod filter;
3
4pub use error::GainError;
5pub use filter::{DeviceTransducerMask, TransducerMask};
6
7use crate::{
8 datagram::DeviceMask,
9 environment::Environment,
10 firmware::Drive,
11 firmware::{Segment, transition_mode::TransitionModeParams},
12 geometry::{Device, Geometry, Transducer},
13};
14
15pub trait GainCalculator<'a>: Send + Sync {
19 #[must_use]
21 fn calc(&self, tr: &'a Transducer) -> Drive;
22}
23
24impl<'a> GainCalculator<'a> for Box<dyn GainCalculator<'a>> {
25 fn calc(&self, tr: &'a Transducer) -> Drive {
26 self.as_ref().calc(tr)
27 }
28}
29
30pub trait GainCalculatorGenerator<'a> {
32 type Calculator: GainCalculator<'a>;
34
35 #[must_use]
37 fn generate(&mut self, device: &'a Device) -> Self::Calculator;
38}
39
40pub trait Gain<'a>: Sized {
46 type G: GainCalculatorGenerator<'a>;
48
49 fn init(
53 self,
54 geometry: &'a Geometry,
55 env: &Environment,
56 filter: &TransducerMask,
57 ) -> Result<Self::G, GainError>;
58}
59
60#[doc(hidden)]
61pub struct GainOperationGenerator<'a, G> {
62 pub generator: G,
63 pub segment: Segment,
64 pub transition_params: TransitionModeParams,
65 pub __phantom: core::marker::PhantomData<&'a ()>,
66}
67
68impl<'a, C: GainCalculatorGenerator<'a>> GainOperationGenerator<'a, C> {
69 pub fn new<G: Gain<'a, G = C>>(
70 gain: G,
71 geometry: &'a Geometry,
72 env: &Environment,
73 filter: &DeviceMask,
74 segment: Segment,
75 transition_params: TransitionModeParams,
76 ) -> Result<Self, GainError> {
77 Ok(Self {
78 generator: gain.init(geometry, env, &TransducerMask::from(filter))?,
79 segment,
80 transition_params,
81 __phantom: core::marker::PhantomData,
82 })
83 }
84}
85
86#[derive(Debug, Clone, PartialEq)]
87pub struct GainInspectionResult {
89 pub data: Vec<Drive>,
91}