1use std::sync::Arc;
2use std::time::Instant;
3
4use gpui::{App, 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 /// Initializes the global font family cache.
29 pub fn init_global(cx: &mut App) {
30 cx.default_global::<GlobalFontFamilyCache>();
31 }
32
33 /// Returns the global font family cache.
34 pub fn global(cx: &App) -> Arc<Self> {
35 GlobalFontFamilyCache::global(cx).0.clone()
36 }
37
38 /// Returns the list of font families.
39 pub fn list_font_families(&self, cx: &App) -> Vec<SharedString> {
40 if self.state.read().loaded_at.is_some() {
41 return self.state.read().font_families.clone();
42 }
43
44 let mut lock = self.state.write();
45 lock.font_families = cx
46 .text_system()
47 .all_font_names()
48 .into_iter()
49 .map(SharedString::from)
50 .collect();
51 lock.loaded_at = Some(Instant::now());
52
53 lock.font_families.clone()
54 }
55}