aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/meter.rs
diff options
context:
space:
mode:
authorTheodore Dubois <tblodt@icloud.com>2019-04-28 06:24:58 -0700
committerChristian Duerr <chrisduerr@users.noreply.github.com>2019-04-28 13:24:58 +0000
commitdbd8538762ef8968a493e1bf996e8693479ca783 (patch)
tree32ac2a6a5e01238a272d4ba534551d2e42903c7a /alacritty_terminal/src/meter.rs
parent9c6d12ea2c863ba76015bdedc00db13b7307725a (diff)
downloadalacritty-dbd8538762ef8968a493e1bf996e8693479ca783.tar.gz
alacritty-dbd8538762ef8968a493e1bf996e8693479ca783.zip
Split alacritty into a separate crates
The crate containing the entry point is called alacritty, and the crate containing everything else is called alacritty_terminal.
Diffstat (limited to 'alacritty_terminal/src/meter.rs')
-rw-r--r--alacritty_terminal/src/meter.rs110
1 files changed, 110 insertions, 0 deletions
diff --git a/alacritty_terminal/src/meter.rs b/alacritty_terminal/src/meter.rs
new file mode 100644
index 00000000..19d7fe70
--- /dev/null
+++ b/alacritty_terminal/src/meter.rs
@@ -0,0 +1,110 @@
+// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//! Rendering time meter
+//!
+//! Used to track rendering times and provide moving averages.
+//!
+//! # Examples
+//!
+//! ```rust
+//! // create a meter
+//! let mut meter = alacritty_terminal::meter::Meter::new();
+//!
+//! // Sample something.
+//! {
+//! let _sampler = meter.sampler();
+//! }
+//!
+//! // Get the moving average. The meter tracks a fixed number of samples, and
+//! // the average won't mean much until it's filled up at least once.
+//! println!("Average time: {}", meter.average());
+
+use std::time::{Duration, Instant};
+
+const NUM_SAMPLES: usize = 10;
+
+/// The meter
+#[derive(Default)]
+pub struct Meter {
+ /// Track last 60 timestamps
+ times: [f64; NUM_SAMPLES],
+
+ /// Average sample time in microseconds
+ avg: f64,
+
+ /// Index of next time to update.
+ index: usize,
+}
+
+/// Sampler
+///
+/// Samplers record how long they are "alive" for and update the meter on drop.
+pub struct Sampler<'a> {
+ /// Reference to meter that created the sampler
+ meter: &'a mut Meter,
+
+ // When the sampler was created
+ created_at: Instant,
+}
+
+impl<'a> Sampler<'a> {
+ fn new(meter: &'a mut Meter) -> Sampler<'a> {
+ Sampler { meter, created_at: Instant::now() }
+ }
+
+ #[inline]
+ fn alive_duration(&self) -> Duration {
+ self.created_at.elapsed()
+ }
+}
+
+impl<'a> Drop for Sampler<'a> {
+ fn drop(&mut self) {
+ self.meter.add_sample(self.alive_duration());
+ }
+}
+
+impl Meter {
+ /// Create a meter
+ pub fn new() -> Meter {
+ Default::default()
+ }
+
+ /// Get a sampler
+ pub fn sampler(&mut self) -> Sampler<'_> {
+ Sampler::new(self)
+ }
+
+ /// Get the current average sample duration in microseconds
+ pub fn average(&self) -> f64 {
+ self.avg
+ }
+
+ /// Add a sample
+ ///
+ /// Used by Sampler::drop.
+ fn add_sample(&mut self, sample: Duration) {
+ let mut usec = 0f64;
+
+ usec += f64::from(sample.subsec_nanos()) / 1e3;
+ usec += (sample.as_secs() as f64) * 1e6;
+
+ let prev = self.times[self.index];
+ self.times[self.index] = usec;
+ self.avg -= prev / NUM_SAMPLES as f64;
+ self.avg += usec / NUM_SAMPLES as f64;
+ self.index = (self.index + 1) % NUM_SAMPLES;
+ }
+}