diff options
author | Theodore Dubois <tblodt@icloud.com> | 2019-04-28 06:24:58 -0700 |
---|---|---|
committer | Christian Duerr <chrisduerr@users.noreply.github.com> | 2019-04-28 13:24:58 +0000 |
commit | dbd8538762ef8968a493e1bf996e8693479ca783 (patch) | |
tree | 32ac2a6a5e01238a272d4ba534551d2e42903c7a /alacritty_terminal/src/meter.rs | |
parent | 9c6d12ea2c863ba76015bdedc00db13b7307725a (diff) | |
download | alacritty-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.rs | 110 |
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; + } +} |