aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/display/meter.rs
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2021-01-24 21:45:36 +0000
committerGitHub <noreply@github.com>2021-01-24 21:45:36 +0000
commit530de00049c2afcc562d36ccdb3e6afa2fe396a5 (patch)
tree3dabbcef3fc4a2041f9027d82243aa0d70928153 /alacritty/src/display/meter.rs
parent7291702f6b4fff10f2470f084abe0785b95659a0 (diff)
downloadr-alacritty-530de00049c2afcc562d36ccdb3e6afa2fe396a5.tar.gz
r-alacritty-530de00049c2afcc562d36ccdb3e6afa2fe396a5.tar.bz2
r-alacritty-530de00049c2afcc562d36ccdb3e6afa2fe396a5.zip
Move renderable cell transformation to alacritty
This refactors a large chunk of the alacritty_terminal API to expose all data necessary for rendering uniformly through the `renderable_content` call. This also no longer transforms the cells for rendering by a GUI but instead just reports the content from a terminal emulation perspective. The transformation into renderable cells is now done inside the alacritty crate. Since the terminal itself only ever needs to know about modified color RGB values, the configuration for colors was moved to the alacritty UI code.
Diffstat (limited to 'alacritty/src/display/meter.rs')
-rw-r--r--alacritty/src/display/meter.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/alacritty/src/display/meter.rs b/alacritty/src/display/meter.rs
new file mode 100644
index 00000000..c07d901f
--- /dev/null
+++ b/alacritty/src/display/meter.rs
@@ -0,0 +1,97 @@
+//! 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;
+ }
+}