1mod drive;
2mod emit_intensity;
3mod error;
4mod phase;
5
6use std::collections::HashMap;
7
8pub type BitVec = bit_vec::BitVec<u32>;
10
11pub use drive::Drive;
12pub use emit_intensity::EmitIntensity;
13pub use error::GainError;
14pub use phase::Phase;
15
16use crate::{
17 datagram::{Segment, TransitionMode},
18 geometry::{Device, Geometry, Transducer},
19};
20
21pub trait GainCalculator: Send + Sync {
25 #[must_use]
27 fn calc(&self, tr: &Transducer) -> Drive;
28}
29
30impl GainCalculator for Box<dyn GainCalculator> {
31 fn calc(&self, tr: &Transducer) -> Drive {
32 self.as_ref().calc(tr)
33 }
34}
35
36pub trait GainCalculatorGenerator {
38 type Calculator: GainCalculator;
40
41 #[must_use]
43 fn generate(&mut self, device: &Device) -> Self::Calculator;
44}
45
46pub trait Gain: std::fmt::Debug + Sized {
52 type G: GainCalculatorGenerator;
54
55 fn init(self) -> Result<Self::G, GainError>;
57
58 fn init_full(
63 self,
64 _: &Geometry,
65 _filter: Option<&HashMap<usize, BitVec>>,
66 _parallel: bool,
67 ) -> Result<Self::G, GainError> {
68 self.init()
69 }
70}
71
72#[doc(hidden)]
73pub struct GainOperationGenerator<G: GainCalculatorGenerator> {
74 pub generator: G,
75 pub segment: Segment,
76 pub transition: Option<TransitionMode>,
77}
78
79impl<G: GainCalculatorGenerator> GainOperationGenerator<G> {
80 pub fn new<T: Gain<G = G>>(
81 gain: T,
82 geometry: &Geometry,
83 segment: Segment,
84 transition: Option<TransitionMode>,
85 parallel: bool,
86 ) -> Result<Self, GainError> {
87 Ok(Self {
88 generator: gain.init_full(geometry, None, parallel)?,
89 segment,
90 transition,
91 })
92 }
93}