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}