Mercurial > templog
comparison rust/src/types.rs @ 610:af0dac00d40b rust
untested step integrator
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 23 Feb 2017 23:27:09 +0800 |
parents | 7bda01659426 |
children | f3e39e2107fd |
comparison
equal
deleted
inserted
replaced
609:7bda01659426 | 610:af0dac00d40b |
---|---|
1 use std::collections::HashMap; | 1 use std::collections::HashMap; |
2 use std::time::{Duration,Instant}; | 2 use std::time::{Duration,Instant}; |
3 use std::error::Error; | 3 use std::error::Error; |
4 use std::fmt; | 4 use std::fmt; |
5 use std::cmp; | |
5 use std::cell::Cell; | 6 use std::cell::Cell; |
7 use std::iter::FromIterator; | |
6 | 8 |
7 use serde::{Deserialize,Serialize}; | 9 use serde::{Deserialize,Serialize}; |
8 | 10 |
9 #[derive(Deserialize, Serialize, Debug)] | 11 #[derive(Deserialize, Serialize, Debug)] |
10 pub struct Params { | 12 pub struct Params { |
124 op(); | 126 op(); |
125 } | 127 } |
126 } | 128 } |
127 } | 129 } |
128 | 130 |
129 | 131 struct Period { |
132 start: Instant, | |
133 end: Option<Instant>, | |
134 } | |
135 | |
136 pub struct StepIntegrator { | |
137 on_periods: Vec<Period>, | |
138 limit: Duration, | |
139 } | |
140 | |
141 impl StepIntegrator { | |
142 pub fn new(limit: Duration) -> Self { | |
143 StepIntegrator { | |
144 on_periods: Vec::new(), | |
145 limit: limit, | |
146 } | |
147 } | |
148 | |
149 pub fn turn(&mut self, on: bool) { | |
150 self.trim(); | |
151 | |
152 if self.on_periods.is_empty() { | |
153 self.on_periods.push( Period { start: Instant::now(), end: None }); | |
154 return; | |
155 } | |
156 | |
157 let current_on = self.on_periods.last().unwrap().end.is_none(); | |
158 if on == current_on { | |
159 // state is unchanged | |
160 return; | |
161 } | |
162 | |
163 if on { | |
164 self.on_periods.push( Period { start: Instant::now(), end: None }); | |
165 } else { | |
166 self.on_periods.last_mut().unwrap().end = Some(Instant::now()); | |
167 } | |
168 } | |
169 | |
170 pub fn set_limit(&mut self, limit: Duration) { | |
171 self.limit = limit; | |
172 self.trim(); | |
173 } | |
174 | |
175 fn integrate(&self) -> Duration { | |
176 let durs = self.on_periods.iter().map(|p| { | |
177 let end = p.end.unwrap_or_else(|| Instant::now()); | |
178 end - p.start | |
179 }); | |
180 // TODO rust 1.16: impl Sum for Duration | |
181 // durs.sum() | |
182 durs.fold(Duration::new(0,0), |acc, d| acc + d) | |
183 } | |
184 | |
185 fn trim(&mut self) { | |
186 let begin = Instant::now() - self.limit; | |
187 | |
188 self.on_periods.retain(|p| { | |
189 // remove expired endtimes | |
190 if let Some(e) = p.end { | |
191 e >= begin && e != p.start | |
192 } else { | |
193 true | |
194 } | |
195 }); | |
196 | |
197 for p in &mut self.on_periods { | |
198 p.start = cmp::max(p.start, begin); | |
199 } | |
200 } | |
201 } | |
202 |