1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
use crate::bins::{ BinBuildEnvironment, BinDescription, Calculator, DataSource, FetchItem, Iteration, SinkOnlyBin, SinkOnlyBinDescription, SinkOnlyBinProcessor, SourceBin, SourceId, SourceOnlyBin, SourceOnlyBinDescription, SourceOnlyBinProcessor, SourceSinkBin, SourceSinkBinDescription, SourceSinkBinProcessor, }; use crate::{ CalibrationSource, GetCalibration, Proceed, Result, Scope, R64, }; use indexmap::IndexMap; use std::rc::{Rc, Weak}; use std::sync::RwLock; #[derive(Clone)] struct NoCalibration {} impl GetCalibration for NoCalibration { fn calibration( &mut self, _mode: &CalibrationSource, ) -> Result<IndexMap<R64, R64>> { unimplemented!() } } struct BuildEnvironment<T: SourceBin, U: GetCalibration> { input: Weak<RwLock<T>>, calibration: U, } impl<T: SourceBin, U: GetCalibration> GetCalibration for BuildEnvironment<T, U> { fn calibration( &mut self, mode: &CalibrationSource, ) -> Result<IndexMap<R64, R64>> { self.calibration.calibration(mode) } } impl<T: 'static + SourceBin, U: GetCalibration> BinBuildEnvironment for BuildEnvironment<T, U> { fn resolve(&mut self, id: &str) -> Result<Box<FetchItem>> { let data_provider = self.input.clone(); let ds = DataSource { data_provider, source: SourceId::new(id), }; let b = Box::new(ds); Ok(b as Box<FetchItem>) } } pub fn run_bin_with_calibration< IB: 'static + SourceOnlyBin, I: SourceOnlyBinDescription + BinDescription<Bin = IB>, DB: 'static + SourceSinkBin, D: SourceSinkBinDescription + BinDescription<Bin = DB>, OB: 'static + SinkOnlyBin, O: SinkOnlyBinDescription + BinDescription<Bin = OB>, C: GetCalibration + Clone, >( input: &I, description: &D, output: &O, calibration: &C, ) -> Result<()> { let scope = Scope::default(); let input: Box<SourceOnlyBin> = Box::new(input.build_bin(&scope)?); let input: Rc<RwLock<Box<SourceOnlyBinProcessor>>> = Rc::new(RwLock::new(Box::new(SourceOnlyBinProcessor::new(input)))); let bin = { let mut env = BuildEnvironment { input: Rc::downgrade(&input), calibration: calibration.clone(), }; let bin: Box<SourceSinkBin> = Box::new(description.build_bin(&scope, &mut env)?); Rc::new(RwLock::new(Box::new(SourceSinkBinProcessor::new(bin)))) }; let output = { let mut env = BuildEnvironment { input: Rc::downgrade(&bin), calibration: calibration.clone(), }; let bin: Box<SinkOnlyBin> = Box::new(output.build_bin(&scope, &mut env)?); Rc::new(RwLock::new(Box::new(SinkOnlyBinProcessor::new(bin)))) }; let mut iteration = Iteration::default(); { while input.write().unwrap().fetch_next(&iteration)? == Proceed::Continue { bin.write().unwrap().calculate(&iteration)?; output.write().unwrap().calculate(&iteration)?; iteration.iterate(); } } Ok(()) } pub fn run_bin< IB: 'static + SourceOnlyBin, I: SourceOnlyBinDescription + BinDescription<Bin = IB>, DB: 'static + SourceSinkBin, D: SourceSinkBinDescription + BinDescription<Bin = DB>, OB: 'static + SinkOnlyBin, O: SinkOnlyBinDescription + BinDescription<Bin = OB>, >( input: &I, description: &D, output: &O, ) -> Result<()> { run_bin_with_calibration(input, description, output, &NoCalibration {}) }