1use num_traits::float::FloatCore;
2
3use super::{Error, InitialiseRunner, Runner};
4use crate::{
5 watchers::{Frequency, Observable, Observer, ObserverVec},
6 Calculation, Control, Problem, State, UserState,
7};
8
9pub trait GenerateBuilder<P, S>: Sized + Calculation<P, S>
10where
11 S: UserState,
12{
13 fn build_for(self, problem: P) -> Builder<Self, P, S, ()>;
14}
15
16impl<C, P, S> GenerateBuilder<P, S> for C
17where
18 C: Calculation<P, S>,
19 S: UserState,
20 <S as UserState>::Float: FloatCore,
21{
22 fn build_for(self, problem: P) -> Builder<Self, P, S, ()> {
23 Builder {
24 problem,
25 calculation: self,
26 state: State::new(),
27 time: true,
28 cancellation_token: (),
29 observers: ObserverVec::default(),
30 }
31 }
32}
33
34pub struct Builder<C, P, S, T>
35where
36 C: Calculation<P, S>,
37 S: UserState,
38{
39 calculation: C,
40 problem: P,
41 state: State<S>,
42 time: bool,
43 cancellation_token: T,
44 observers: ObserverVec<State<S>>,
45}
46impl<C, P, S, R> Builder<C, P, S, R>
47where
48 C: Calculation<P, S>,
49 S: UserState,
50{
51 #[must_use]
52 pub fn time(mut self, time: bool) -> Self {
53 self.time = time;
54 self
55 }
56
57 #[must_use]
61 pub fn configure<F: FnOnce(State<S>) -> State<S>>(mut self, configure: F) -> Self {
62 let state = configure(self.state);
63 self.state = state;
64 self
65 }
66
67 #[must_use]
68 pub fn attach_observer<OBS: Observer<State<S>> + 'static>(
69 mut self,
70 observer: OBS,
71 frequency: Frequency,
72 ) -> Self {
73 self.observers.attach(
74 std::sync::Arc::new(std::sync::Mutex::new(observer)),
75 frequency,
76 );
77 self
78 }
79}
80
81impl<C, P, S> Builder<C, P, S, ()>
82where
83 C: Calculation<P, S>,
84 S: UserState,
85{
86 #[must_use]
87 pub fn with_cancellation_token<T>(self, cancellation_token: T) -> Builder<C, P, S, T> {
88 Builder {
89 calculation: self.calculation,
90 problem: self.problem,
91 state: self.state,
92 time: self.time,
93 cancellation_token,
94 observers: self.observers,
95 }
96 }
97
98 pub fn finalise(self) -> Result<Runner<C, P, S, ()>, Error>
99 where
100 C: Calculation<P, S>,
101 S: UserState,
102 {
103 let mut runner = Runner {
104 problem: Problem::new(self.problem),
105 calculation: self.calculation,
106 state: Some(self.state),
107 time: self.time,
108 cancellation_token: None,
109 signals: vec![],
110 observers: self.observers,
111 };
112 runner.initialise_controllers()?;
113 Ok(runner)
114 }
115}
116
117impl<C, P, S, T> Builder<C, P, S, T>
118where
119 T: Control + 'static,
120 C: Calculation<P, S>,
121 S: UserState,
122{
123 pub fn finalise(self) -> Result<Runner<C, P, S, T>, Error> {
124 let mut runner = Runner {
125 problem: Problem::new(self.problem),
126 calculation: self.calculation,
127 state: Some(self.state),
128 time: self.time,
129 cancellation_token: Some(self.cancellation_token),
130 signals: vec![],
131 observers: self.observers,
132 };
133 runner.initialise_controllers()?;
134 Ok(runner)
135 }
136}