perf: cache each file's icon to avoid redundant calculations at rendering (#931)

This commit is contained in:
三咲雅 · Misaki Masa 2024-04-20 15:43:08 +08:00 committed by GitHub
parent 80000cfd86
commit 55da9e342c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 81 additions and 43 deletions

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Deserializer};
use yazi_shared::fs::File;
use yazi_shared::{fs::File, theme::{Color, Style, StyleShadow}};
use super::{Color, Is, Style, StyleShadow};
use super::Is;
use crate::Pattern;
pub struct Filetype {

View File

@ -1,14 +1,20 @@
use serde::{Deserialize, Deserializer};
use yazi_shared::fs::File;
use std::ops::Deref;
use super::Style;
use crate::{preset::Preset, theme::{Color, Is, StyleShadow}, Pattern};
use serde::{Deserialize, Deserializer};
use yazi_shared::{fs::File, theme::{Color, StyleShadow}};
use crate::{preset::Preset, theme::Is, Pattern};
pub struct Icon {
pub is: Is,
pub name: Pattern,
pub text: String,
pub style: Style,
is: Is,
name: Pattern,
inner: yazi_shared::theme::Icon,
}
impl Deref for Icon {
type Target = yazi_shared::theme::Icon;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Icon {
@ -61,8 +67,10 @@ impl Icon {
.map(|r| Icon {
is: r.is,
name: r.name,
text: r.text,
style: StyleShadow { fg: r.fg, ..Default::default() }.into(),
inner: yazi_shared::theme::Icon {
text: r.text,
style: StyleShadow { fg: r.fg, ..Default::default() }.into(),
},
})
.collect(),
)

View File

@ -1,15 +1,11 @@
mod color;
mod filetype;
mod flavor;
mod icon;
mod is;
mod style;
mod theme;
pub use color::*;
pub use filetype::*;
pub use flavor::*;
pub use icon::*;
pub use is::*;
pub use style::*;
pub use theme::*;

View File

@ -2,9 +2,9 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use validator::Validate;
use yazi_shared::{fs::expand_path, Xdg};
use yazi_shared::{fs::expand_path, theme::Style, Xdg};
use super::{Filetype, Flavor, Icon, Style};
use super::{Filetype, Flavor, Icon};
use crate::{validation::check_validation, MERGED_THEME};
#[derive(Deserialize, Serialize)]

View File

@ -58,7 +58,17 @@ impl File {
Some(lua.create_string(p.as_path().as_os_str().as_encoded_bytes())).transpose()
});
reg.add_method("icon", |lua, me, ()| {
THEME.icons.iter().find(|&x| x.matches(me)).map(|x| Icon::cast(lua, x)).transpose()
use yazi_shared::theme::IconCache;
match me.icon.get() {
IconCache::Missing => {
let matched = THEME.icons.iter().find(|&i| i.matches(me));
me.icon.set(matched.map_or(IconCache::Undefined, |i| IconCache::Icon(i)));
matched.map(|i| Icon::cast(lua, i)).transpose()
}
IconCache::Undefined => Ok(None),
IconCache::Icon(cached) => Some(Icon::cast(lua, cached)).transpose(),
}
});
reg.add_method("style", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;

View File

@ -7,7 +7,7 @@ pub struct Icon;
impl Icon {
pub fn register(lua: &Lua) -> mlua::Result<()> {
lua.register_userdata_type::<&yazi_config::theme::Icon>(|reg| {
lua.register_userdata_type::<&yazi_shared::theme::Icon>(|reg| {
reg.add_field_method_get("text", |lua, me| lua.create_string(&me.text));
reg.add_field_method_get("style", |_, me| Ok(Style::from(me.style)));
})?;
@ -16,10 +16,10 @@ impl Icon {
}
}
impl Cast<&'static yazi_config::theme::Icon> for Icon {
impl Cast<&'static yazi_shared::theme::Icon> for Icon {
fn cast<'lua>(
lua: &'lua Lua,
data: &'static yazi_config::theme::Icon,
data: &'static yazi_shared::theme::Icon,
) -> mlua::Result<AnyUserData<'lua>> {
lua.create_any_userdata(data)
}

View File

@ -1,5 +1,5 @@
use mlua::{AnyUserData, ExternalError, FromLua, Lua, Table, UserData, UserDataMethods, Value};
use yazi_config::theme::Color;
use yazi_shared::theme::Color;
use super::Style;

View File

@ -1,7 +1,7 @@
use std::str::FromStr;
use mlua::{AnyUserData, ExternalError, ExternalResult, Lua, Table, UserData, UserDataMethods, Value};
use yazi_config::theme::Color;
use yazi_shared::theme::Color;
#[derive(Clone, Copy, Default)]
pub struct Style(pub(super) ratatui::style::Style);
@ -17,8 +17,8 @@ impl Style {
}
}
impl From<yazi_config::theme::Style> for Style {
fn from(value: yazi_config::theme::Style) -> Self { Self(value.into()) }
impl From<yazi_shared::theme::Style> for Style {
fn from(value: yazi_shared::theme::Style) -> Self { Self(value.into()) }
}
impl<'a> TryFrom<Table<'a>> for Style {

View File

@ -1,15 +1,16 @@
use std::{ffi::OsStr, fs::Metadata, ops::Deref};
use std::{cell::Cell, ffi::OsStr, fs::Metadata, ops::Deref};
use anyhow::Result;
use tokio::fs;
use crate::fs::{Cha, ChaKind, Url};
use crate::{fs::{Cha, ChaKind, Url}, theme::IconCache};
#[derive(Clone, Debug, Default)]
pub struct File {
pub url: Url,
pub cha: Cha,
pub link_to: Option<Url>,
pub icon: Cell<IconCache>,
}
impl Deref for File {
@ -53,7 +54,7 @@ impl File {
}
}
Self { url, cha: Cha::from(meta).with_kind(ck), link_to }
Self { url, cha: Cha::from(meta).with_kind(ck), link_to, icon: Default::default() }
}
#[inline]

View File

@ -13,6 +13,7 @@ mod number;
mod os;
mod ro_cell;
pub mod term;
pub mod theme;
mod throttle;
mod time;
mod xdg;

View File

@ -3,7 +3,7 @@ use std::str::FromStr;
use anyhow::Result;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Deserialize)]
#[derive(Clone, Copy, Debug, Deserialize)]
#[serde(try_from = "String")]
pub struct Color(ratatui::style::Color);

View File

@ -0,0 +1,15 @@
use super::Style;
#[derive(Clone, Debug)]
pub struct Icon {
pub text: String,
pub style: Style,
}
#[derive(Clone, Copy, Debug, Default)]
pub enum IconCache {
#[default]
Missing,
Undefined,
Icon(&'static Icon),
}

View File

@ -0,0 +1,7 @@
mod color;
mod icon;
mod style;
pub use color::*;
pub use icon::*;
pub use style::*;

View File

@ -3,7 +3,7 @@ use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
use super::Color;
#[derive(Clone, Copy, Deserialize)]
#[derive(Clone, Copy, Debug, Deserialize)]
#[serde(from = "StyleShadow")]
pub struct Style {
pub fg: Option<Color>,
@ -37,29 +37,29 @@ impl From<Style> for ratatui::style::Style {
}
#[derive(Default, Deserialize)]
pub(super) struct StyleShadow {
pub struct StyleShadow {
#[serde(default)]
pub(super) fg: Option<Color>,
pub fg: Option<Color>,
#[serde(default)]
pub(super) bg: Option<Color>,
pub bg: Option<Color>,
#[serde(default)]
pub(super) bold: bool,
pub bold: bool,
#[serde(default)]
pub(super) dim: bool,
pub dim: bool,
#[serde(default)]
pub(super) italic: bool,
pub italic: bool,
#[serde(default)]
pub(super) underline: bool,
pub underline: bool,
#[serde(default)]
pub(super) blink: bool,
pub blink: bool,
#[serde(default)]
pub(super) blink_rapid: bool,
pub blink_rapid: bool,
#[serde(default)]
pub(super) reversed: bool,
pub reversed: bool,
#[serde(default)]
pub(super) hidden: bool,
pub hidden: bool,
#[serde(default)]
pub(super) crossed: bool,
pub crossed: bool,
}
impl From<StyleShadow> for Style {