From 37fcb7390b3c942fec879691a2cc53ffa0842503 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Tue, 6 Aug 2019 16:39:17 +0200 Subject: [PATCH] Use pre-seeded font caches to avoid mut --- src/backlight.rs | 9 +++--- src/battery.rs | 10 ++++--- src/calendar.rs | 36 ++++++++++++++---------- src/clock.rs | 19 ++++++++----- src/draw.rs | 73 ++++++++++++++++++++++++++++++++++++------------ src/launcher.rs | 8 +++--- src/main.rs | 41 ++++++++++++--------------- src/sound.rs | 8 ++++-- 8 files changed, 126 insertions(+), 78 deletions(-) diff --git a/src/backlight.rs b/src/backlight.rs index 450eb4c..1991021 100644 --- a/src/backlight.rs +++ b/src/backlight.rs @@ -3,7 +3,6 @@ use crate::color::Color; use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; -use std::cell::RefCell; use std::fs::OpenOptions; use std::io::{Error, ErrorKind}; use std::io::{Read, Write}; @@ -15,7 +14,7 @@ pub struct Backlight { device_path: PathBuf, cur_brightness: u64, max_brightness: u64, - font: RefCell, + font: Font, dirty: bool, } @@ -87,10 +86,12 @@ impl Backlight { device_path: first_device.path(), cur_brightness: 0, max_brightness: 0, - font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), + font: Font::new(&ROBOTO_REGULAR, 24.0), dirty: true, }; + dev.font.add_str_to_cache("backlight"); + dev.update()?; Ok(dev) @@ -106,7 +107,7 @@ impl ModuleImpl for Backlight { ) -> Result, Error> { buf.memset(bg); let c = Color::new(1.0, 1.0, 1.0, 1.0); - self.font.borrow_mut().draw_text( + self.font.draw_text( &mut buf.subdimensions((0, 0, 128, 24))?, bg, &c, diff --git a/src/battery.rs b/src/battery.rs index 806c5f2..e5f5851 100644 --- a/src/battery.rs +++ b/src/battery.rs @@ -3,7 +3,6 @@ use crate::color::Color; use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; -use std::cell::RefCell; use std::sync::mpsc::Sender; use std::sync::{Arc, Mutex}; use std::thread; @@ -40,7 +39,7 @@ fn get_upower_property( pub struct UpowerBattery { device_path: String, - font: RefCell, + font: Font, inner: Arc>, } @@ -116,9 +115,12 @@ impl UpowerBattery { } }; + let mut font = Font::new(&ROBOTO_REGULAR, 24.0); + font.add_str_to_cache("battery"); + Ok(UpowerBattery { device_path, - font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), + font: font, inner: Arc::new(Mutex::new(UpowerBatteryInner { capacity: capacity, state: state, @@ -204,7 +206,7 @@ impl ModuleImpl for UpowerBattery { }; let inner = self.inner.lock().unwrap(); - self.font.borrow_mut().draw_text( + self.font.draw_text( &mut buf.subdimensions((0, 0, 128, 24))?, bg, &text_color, diff --git a/src/calendar.rs b/src/calendar.rs index 6ae9dce..392c0d6 100644 --- a/src/calendar.rs +++ b/src/calendar.rs @@ -3,18 +3,16 @@ use crate::color::Color; use crate::draw::{Font, DEJAVUSANS_MONO, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; -use std::cell::RefCell; - use chrono::{Date, DateTime, Datelike, Local}; pub struct Calendar { cur_date: Date, dirty: bool, offset: f64, - calendar_numeral_cache: RefCell, - month_cache: RefCell, - year_cache: RefCell, - day_cache: RefCell, + calendar_cache: Font, + month_cache: Font, + year_cache: Font, + day_cache: Font, } impl Calendar { @@ -49,14 +47,14 @@ impl Calendar { // Draw the of the month // - self.month_cache.borrow_mut().draw_text( + self.month_cache.draw_text( &mut buf.subdimensions((0, 0, 304, 72))?, background_color, &Color::new(1.0, 1.0, 1.0, 1.0), month_str, )?; if time.year() != orig.year() { - self.year_cache.borrow_mut().draw_text( + self.year_cache.draw_text( &mut buf.subdimensions((320, 0, 64, 32))?, background_color, &Color::new(0.8, 0.8, 0.8, 1.0), @@ -80,7 +78,7 @@ impl Calendar { _ => panic!("impossible value"), }; - self.day_cache.borrow_mut().draw_text( + self.day_cache.draw_text( &mut buf.subdimensions((idx * 48 + 4, (y_off * 32) + 64, 32, 16))?, background_color, &Color::new(1.0, 1.0, 1.0, 1.0), @@ -106,7 +104,7 @@ impl Calendar { // Draw the week number // let wk = time.iso_week(); - self.calendar_numeral_cache.borrow_mut().draw_text( + self.calendar_cache.draw_text( &mut buf.subdimensions((0 * 48, (y_off * 32) + 64, 38, 32))?, background_color, &Color::new(0.75, 0.75, 0.75, 1.0), @@ -124,7 +122,7 @@ impl Calendar { Color::new(0.5, 0.5, 0.5, 1.0) }; - self.calendar_numeral_cache.borrow_mut().draw_text( + self.calendar_cache.draw_text( &mut buf.subdimensions((x_pos * 48, (y_off * 32) + 64, 38, 32))?, background_color, &c, @@ -148,14 +146,22 @@ impl Calendar { impl Calendar { pub fn new() -> Calendar { + let mut calendar_cache = Font::new(&DEJAVUSANS_MONO, 32.0); + calendar_cache.add_str_to_cache("0123456789"); + let mut month_cache = Font::new(&ROBOTO_REGULAR, 64.0); + month_cache.add_str_to_cache("JanuryFebMchApilJgstSmOoNvD"); + let mut year_cache = Font::new(&DEJAVUSANS_MONO, 24.0); + year_cache.add_str_to_cache("-0123456789"); + let mut day_cache = Font::new(&DEJAVUSANS_MONO, 16.0); + day_cache.add_str_to_cache("MONTUEWDHFRISA"); Calendar { cur_date: Local::now().date(), dirty: true, offset: 0.0, - calendar_numeral_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 32.0)), - month_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 64.0)), - year_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 24.0)), - day_cache: RefCell::new(Font::new(&DEJAVUSANS_MONO, 16.0)), + calendar_cache: calendar_cache, + month_cache: month_cache, + year_cache: year_cache, + day_cache: day_cache, } } } diff --git a/src/clock.rs b/src/clock.rs index 0c59984..d72c257 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -3,7 +3,6 @@ use crate::color::Color; use crate::draw::{Font, ROBOTO_REGULAR}; use crate::module::{Input, ModuleImpl}; -use std::cell::RefCell; use std::sync::mpsc::Sender; use chrono::{DateTime, Datelike, Duration, Local, Timelike}; @@ -11,8 +10,8 @@ use chrono::{DateTime, Datelike, Duration, Local, Timelike}; pub struct Clock { cur_time: DateTime, first_draw: bool, - clock_cache: RefCell, - date_cache: RefCell, + clock_cache: Font, + date_cache: Font, } impl Clock { @@ -31,11 +30,17 @@ impl Clock { ch.send(true).unwrap(); }); + let mut date_cache = Font::new(&ROBOTO_REGULAR, 64.0); + date_cache + .add_str_to_cache("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,/ "); + let mut clock_cache = Font::new(&ROBOTO_REGULAR, 256.0); + clock_cache.add_str_to_cache("0123456789:"); + Clock { cur_time: Local::now(), first_draw: true, - date_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 64.0)), - clock_cache: RefCell::new(Font::new(&ROBOTO_REGULAR, 256.0)), + date_cache: date_cache, + clock_cache: clock_cache, } } } @@ -49,7 +54,7 @@ impl ModuleImpl for Clock { ) -> Result, ::std::io::Error> { buf.memset(bg); - self.date_cache.borrow_mut().draw_text( + self.date_cache.draw_text( &mut buf.subdimensions((0, 0, 448, 64))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0), @@ -62,7 +67,7 @@ impl ModuleImpl for Clock { ), )?; - self.clock_cache.borrow_mut().draw_text_fixed_width( + self.clock_cache.draw_text_fixed_width( &mut buf.subdimensions((0, 64, 288 * 2 + 64, 256))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0), diff --git a/src/draw.rs b/src/draw.rs index 4dd4203..bc2e0cc 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -97,8 +97,17 @@ impl Font { } } + pub fn add_str_to_cache(&mut self, s: &str) { + for ch in s.chars() { + if self.glyphs.get(&ch).is_none() { + let glyph = CachedGlyph::new(self.font, self.size, ch); + self.glyphs.insert(ch, glyph); + } + } + } + pub fn draw_text( - &mut self, + &self, buf: &mut Buffer, bg: &Color, c: &Color, @@ -106,21 +115,23 @@ impl Font { ) -> Result<(u32, u32), ::std::io::Error> { let mut x_off = 0; let mut off = 0; + let mut glyphs = Vec::with_capacity(s.len()); for ch in s.chars() { let glyph = match self.glyphs.get(&ch) { Some(glyph) => glyph, None => { - let glyph = CachedGlyph::new(self.font, self.size, ch); - self.glyphs.insert(ch, glyph); - self.glyphs.get(&ch).unwrap() + return Err(::std::io::Error::new( + ::std::io::ErrorKind::Other, + format!("glyph for {:} not in cache", ch), + )) } }; + glyphs.push(glyph); if glyph.origin.1 < off { off = glyph.origin.1 } } - for ch in s.chars() { - let glyph = &self.glyphs[&ch]; + for glyph in glyphs { glyph.draw(buf, (x_off, -off), bg, c); x_off += glyph.dimensions.0 as i32 + glyph.origin.0; } @@ -128,31 +139,44 @@ impl Font { Ok((x_off as u32, self.size as u32)) } - pub fn draw_text_fixed_width( + pub fn auto_draw_text( &mut self, buf: &mut Buffer, bg: &Color, c: &Color, + s: &str, + ) -> Result<(u32, u32), ::std::io::Error> { + self.add_str_to_cache(s); + self.draw_text(buf, bg, c, s) + } + + pub fn draw_text_fixed_width( + &self, + buf: &mut Buffer, + bg: &Color, + c: &Color, distances: &[u32], s: &str, ) -> Result<(u32, u32), ::std::io::Error> { let mut x_off = 0; let mut off = 0; + let mut glyphs = Vec::with_capacity(s.len()); for ch in s.chars() { let glyph = match self.glyphs.get(&ch) { Some(glyph) => glyph, None => { - let glyph = CachedGlyph::new(self.font, self.size, ch); - self.glyphs.insert(ch, glyph); - self.glyphs.get(&ch).unwrap() + return Err(::std::io::Error::new( + ::std::io::ErrorKind::Other, + format!("glyph for {:} not in cache", ch), + )) } }; + glyphs.push(glyph); if glyph.origin.1 < off { off = glyph.origin.1 } } - for (idx, ch) in s.chars().enumerate() { - let glyph = &self.glyphs[&ch]; + for (idx, glyph) in glyphs.into_iter().enumerate() { glyph.draw(buf, (x_off, -off), bg, c); x_off += distances[idx] as i32; } @@ -161,7 +185,7 @@ impl Font { } pub fn draw_text_individual_colors( - &mut self, + &self, buf: &mut Buffer, bg: &Color, color: &[Color], @@ -169,27 +193,40 @@ impl Font { ) -> Result<(u32, u32), ::std::io::Error> { let mut x_off = 0; let mut off = 0; + let mut glyphs = Vec::with_capacity(s.len()); for ch in s.chars() { let glyph = match self.glyphs.get(&ch) { Some(glyph) => glyph, None => { - let glyph = CachedGlyph::new(self.font, self.size, ch); - self.glyphs.insert(ch, glyph); - self.glyphs.get(&ch).unwrap() + return Err(::std::io::Error::new( + ::std::io::ErrorKind::Other, + format!("glyph for {:} not in cache", ch), + )) } }; + glyphs.push(glyph); if glyph.origin.1 < off { off = glyph.origin.1 } } - for (idx, ch) in s.chars().enumerate() { - let glyph = &self.glyphs[&ch]; + for (idx, glyph) in glyphs.into_iter().enumerate() { glyph.draw(buf, (x_off, -off), bg, &color[idx]); x_off += glyph.dimensions.0 as i32 + glyph.origin.0; } Ok((x_off as u32, self.size as u32)) } + + pub fn auto_draw_text_individual_colors( + &mut self, + buf: &mut Buffer, + bg: &Color, + color: &[Color], + s: &str, + ) -> Result<(u32, u32), ::std::io::Error> { + self.add_str_to_cache(s); + self.draw_text_individual_colors(buf, bg, color, s) + } } pub fn draw_box(buf: &mut Buffer, c: &Color, dim: (u32, u32)) -> Result<(), ::std::io::Error> { diff --git a/src/launcher.rs b/src/launcher.rs index d4c790b..7656e11 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -58,7 +58,7 @@ impl ModuleImpl for Launcher { ) -> Result, ::std::io::Error> { buf.memset(bg); - self.font.borrow_mut().draw_text( + self.font.borrow_mut().auto_draw_text( &mut buf.subdimensions((0, 0, 128, 32))?, bg, &Color::new(0.75, 0.75, 0.75, 1.0), @@ -68,7 +68,7 @@ impl ModuleImpl for Launcher { let mut x_off: i32 = 0; let mut width_remaining: i32 = 1280 - 64; if self.matches.len() == 0 && self.cur.len() > 0 { - self.font.borrow_mut().draw_text( + self.font.borrow_mut().auto_draw_text( &mut buf .subdimensions((64, 0, width_remaining as u32, 32)) .unwrap(), @@ -96,9 +96,9 @@ impl ModuleImpl for Launcher { } self.font .borrow_mut() - .draw_text_individual_colors(&mut b, bg, &colors, &m)? + .auto_draw_text_individual_colors(&mut b, bg, &colors, &m)? } else { - self.font.borrow_mut().draw_text( + self.font.borrow_mut().auto_draw_text( &mut b, bg, &Color::new(0.5, 0.5, 0.5, 1.0), diff --git a/src/main.rs b/src/main.rs index 7c9730e..dbc29f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,9 +10,7 @@ use os_pipe::pipe; use chrono::Local; -use smithay_client_toolkit::keyboard::{ - keysyms, map_keyboard_auto, Event as KbEvent, KeyState, -}; +use smithay_client_toolkit::keyboard::{keysyms, map_keyboard_auto, Event as KbEvent, KeyState}; use smithay_client_toolkit::utils::DoubleMemPool; use wayland_client::protocol::{wl_compositor, wl_pointer, wl_shm, wl_surface}; @@ -244,29 +242,26 @@ impl App { // Keyboard processing // let kbd_clone = cmd_queue.clone(); - map_keyboard_auto( - &seat, - move |event: KbEvent, _| match event { - KbEvent::Key { - keysym, - utf8, - state, - .. - } => match state { - KeyState::Pressed => match keysym { - keysyms::XKB_KEY_Escape => kbd_clone.lock().unwrap().push_back(Cmd::Exit), - v => kbd_clone.lock().unwrap().push_back(Cmd::KeyboardInput { - input: Input::Keypress { - key: v, - interpreted: utf8, - }, - }), - }, - _ => (), + map_keyboard_auto(&seat, move |event: KbEvent, _| match event { + KbEvent::Key { + keysym, + utf8, + state, + .. + } => match state { + KeyState::Pressed => match keysym { + keysyms::XKB_KEY_Escape => kbd_clone.lock().unwrap().push_back(Cmd::Exit), + v => kbd_clone.lock().unwrap().push_back(Cmd::KeyboardInput { + input: Input::Keypress { + key: v, + interpreted: utf8, + }, + }), }, _ => (), }, - ) + _ => (), + }) .expect("Failed to map keyboard"); // diff --git a/src/sound.rs b/src/sound.rs index a6be51f..cc28c34 100644 --- a/src/sound.rs +++ b/src/sound.rs @@ -399,16 +399,18 @@ impl PulseAudioSoundDevice { pub struct PulseAudio { device: Arc>, - font: RefCell, + font: Font, dirty: Arc>, } impl PulseAudio { pub fn new(listener: Sender) -> Result { let (tx, rx) = channel(); + let mut font = Font::new(&ROBOTO_REGULAR, 24.0); + font.add_str_to_cache("volume"); let pa = PulseAudio { device: PulseAudioSoundDevice::new(tx)?, - font: RefCell::new(Font::new(&ROBOTO_REGULAR, 24.0)), + font: font, dirty: Arc::new(Mutex::new(true)), }; let device = pa.device.clone(); @@ -438,7 +440,7 @@ impl ModuleImpl for PulseAudio { } else { Color::new(1.0, 1.0, 1.0, 1.0) }; - self.font.borrow_mut().draw_text( + self.font.draw_text( &mut buf.subdimensions((0, 0, 128, 24))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0),