font_family_cache.rs

 1use std::sync::Arc;
 2use std::time::Instant;
 3
 4use gpui::{AppContext, Global, ReadGlobal, SharedString};
 5use parking_lot::RwLock;
 6
 7#[derive(Default)]
 8struct FontFamilyCacheState {
 9    loaded_at: Option<Instant>,
10    font_families: Vec<SharedString>,
11}
12
13/// A cache for the list of font families.
14///
15/// Listing the available font families from the text system is expensive,
16/// so we do it once and then use the cached values each render.
17#[derive(Default)]
18pub struct FontFamilyCache {
19    state: RwLock<FontFamilyCacheState>,
20}
21
22#[derive(Default)]
23struct GlobalFontFamilyCache(Arc<FontFamilyCache>);
24
25impl Global for GlobalFontFamilyCache {}
26
27impl FontFamilyCache {
28    pub fn init_global(cx: &mut AppContext) {
29        cx.default_global::<GlobalFontFamilyCache>();
30    }
31
32    pub fn global(cx: &AppContext) -> Arc<Self> {
33        GlobalFontFamilyCache::global(cx).0.clone()
34    }
35
36    pub fn list_font_families(&self, cx: &AppContext) -> Vec<SharedString> {
37        if self.state.read().loaded_at.is_some() {
38            return self.state.read().font_families.clone();
39        }
40
41        let mut lock = self.state.write();
42        lock.font_families = cx
43            .text_system()
44            .all_font_names()
45            .into_iter()
46            .map(SharedString::from)
47            .collect();
48        lock.loaded_at = Some(Instant::now());
49
50        lock.font_families.clone()
51    }
52}