trellis_runner/runner/
builder.rs

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
126
127
128
129
130
131
132
133
134
135
136
use num_traits::float::FloatCore;

use super::{Error, InitialiseRunner, Runner};
use crate::{
    watchers::{Frequency, Observable, Observer, ObserverVec},
    Calculation, Control, Problem, State, UserState,
};

pub trait GenerateBuilder<P, S>: Sized + Calculation<P, S>
where
    S: UserState,
{
    fn build_for(self, problem: P) -> Builder<Self, P, S, ()>;
}

impl<C, P, S> GenerateBuilder<P, S> for C
where
    C: Calculation<P, S>,
    S: UserState,
    <S as UserState>::Float: FloatCore,
{
    fn build_for(self, problem: P) -> Builder<Self, P, S, ()> {
        Builder {
            problem,
            calculation: self,
            state: State::new(),
            time: true,
            cancellation_token: (),
            observers: ObserverVec::default(),
        }
    }
}

pub struct Builder<C, P, S, T>
where
    C: Calculation<P, S>,
    S: UserState,
{
    calculation: C,
    problem: P,
    state: State<S>,
    time: bool,
    cancellation_token: T,
    observers: ObserverVec<State<S>>,
}
impl<C, P, S, R> Builder<C, P, S, R>
where
    C: Calculation<P, S>,
    S: UserState,
{
    #[must_use]
    pub fn time(mut self, time: bool) -> Self {
        self.time = time;
        self
    }

    /// Configure the attached state.
    ///
    /// Apply any runtime configuration option to the attached state.
    #[must_use]
    pub fn configure<F: FnOnce(State<S>) -> State<S>>(mut self, configure: F) -> Self {
        let state = configure(self.state);
        self.state = state;
        self
    }

    #[must_use]
    pub fn attach_observer<OBS: Observer<State<S>> + 'static>(
        mut self,
        observer: OBS,
        frequency: Frequency,
    ) -> Self {
        self.observers.attach(
            std::sync::Arc::new(std::sync::Mutex::new(observer)),
            frequency,
        );
        self
    }
}

impl<C, P, S> Builder<C, P, S, ()>
where
    C: Calculation<P, S>,
    S: UserState,
{
    #[must_use]
    pub fn with_cancellation_token<T>(self, cancellation_token: T) -> Builder<C, P, S, T> {
        Builder {
            calculation: self.calculation,
            problem: self.problem,
            state: self.state,
            time: self.time,
            cancellation_token,
            observers: self.observers,
        }
    }

    pub fn finalise(self) -> Result<Runner<C, P, S, ()>, Error>
    where
        C: Calculation<P, S>,
        S: UserState,
    {
        let mut runner = Runner {
            problem: Problem::new(self.problem),
            calculation: self.calculation,
            state: Some(self.state),
            time: self.time,
            cancellation_token: None,
            signals: vec![],
            observers: self.observers,
        };
        runner.initialise_controllers()?;
        Ok(runner)
    }
}

impl<C, P, S, T> Builder<C, P, S, T>
where
    T: Control + 'static,
    C: Calculation<P, S>,
    S: UserState,
{
    pub fn finalise(self) -> Result<Runner<C, P, S, T>, Error> {
        let mut runner = Runner {
            problem: Problem::new(self.problem),
            calculation: self.calculation,
            state: Some(self.state),
            time: self.time,
            cancellation_token: Some(self.cancellation_token),
            signals: vec![],
            observers: self.observers,
        };
        runner.initialise_controllers()?;
        Ok(runner)
    }
}