mirror of
https://github.com/sxyazi/yazi.git
synced 2026-05-13 08:16:40 +00:00
perf: use AnyUserData::type_id() to reduce stack pushes (#2834)
This commit is contained in:
parent
d5038eeed5
commit
2d95221f59
13 changed files with 68 additions and 102 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -407,9 +407,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.51"
|
||||
version = "4.5.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d2267df7f3c8e74e38268887ea5235d4dfadd39bfff2d56ab82d61776be355e"
|
||||
checksum = "1a554639e42d0c838336fc4fbedb9e2df3ad1fa4acda149f9126b4ccfcd7900f"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ Yazi is currently in heavy development, expect breaking changes.
|
|||
| [Ghostty](https://github.com/ghostty-org/ghostty) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
|
||||
| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.10352.0) | [Sixel graphics format][sixel] | ✅ Built-in |
|
||||
| [st with Sixel patch](https://github.com/bakkeby/st-flexipatch) | [Sixel graphics format][sixel] | ✅ Built-in |
|
||||
| [Warp](https://www.warp.dev) | [Inline images protocol][iip] | ✅ Built-in |
|
||||
| [Warp](https://www.warp.dev) (macOS/Linux only) | [Inline images protocol][iip] | ✅ Built-in |
|
||||
| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol][iip] | ✅ Built-in |
|
||||
| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol][iip] | ✅ Built-in |
|
||||
| [Rio](https://github.com/raphamorim/rio) | [Inline images protocol][iip] | ❌ Rio doesn't correctly clear images [#709][rio-bug] |
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ yazi-shared = { path = "../yazi-shared", version = "25.5.31" }
|
|||
|
||||
# External dependencies
|
||||
clap = { workspace = true }
|
||||
clap_complete = "4.5.51"
|
||||
clap_complete = "4.5.52"
|
||||
clap_complete_fig = "4.5.2"
|
||||
clap_complete_nushell = "4.5.6"
|
||||
vergen-gitcl = { version = "1.0.8", features = [ "build", "rustc" ] }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ yazi-shared = { path = "../yazi-shared", version = "25.5.31" }
|
|||
# External build dependencies
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
clap_complete = "4.5.51"
|
||||
clap_complete = "4.5.52"
|
||||
clap_complete_fig = "4.5.2"
|
||||
clap_complete_nushell = "4.5.6"
|
||||
serde_json = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{borrow::Cow, collections::HashMap};
|
||||
use std::{any::TypeId, borrow::Cow, collections::HashMap};
|
||||
|
||||
use mlua::{ExternalError, IntoLua, Lua, MultiValue, Table, Value};
|
||||
use yazi_shared::{OrderedFloat, event::{Data, DataKey}, replace_cow};
|
||||
|
|
@ -40,21 +40,24 @@ impl Sendable {
|
|||
}
|
||||
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
||||
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
||||
Value::UserData(ud) => {
|
||||
if let Ok(t) = ud.take::<yazi_binding::Url>() {
|
||||
Data::Url(t.into())
|
||||
} else if let Ok(t) = ud.take::<yazi_binding::Urn>() {
|
||||
Data::Urn(t.into())
|
||||
} else if let Ok(t) = ud.borrow::<yazi_binding::Id>() {
|
||||
Data::Id(**t)
|
||||
} else if let Ok(t) = ud.take::<yazi_fs::FilesOp>() {
|
||||
Data::Any(Box::new(t))
|
||||
} else if let Ok(t) = ud.take::<super::body::BodyYankIter>() {
|
||||
Data::Any(Box::new(t))
|
||||
} else {
|
||||
Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?
|
||||
Value::UserData(ud) => match ud.type_id() {
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Url>() => {
|
||||
Data::Url(ud.take::<yazi_binding::Url>()?.into())
|
||||
}
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Urn>() => {
|
||||
Data::Urn(ud.take::<yazi_binding::Urn>()?.into())
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Id>() => {
|
||||
Data::Id(**ud.borrow::<yazi_binding::Id>()?)
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_fs::FilesOp>() => {
|
||||
Data::Any(Box::new(ud.take::<yazi_fs::FilesOp>()?))
|
||||
}
|
||||
Some(t) if t == TypeId::of::<super::body::BodyYankIter>() => {
|
||||
Data::Any(Box::new(ud.take::<super::body::BodyYankIter>()?))
|
||||
}
|
||||
_ => Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?,
|
||||
},
|
||||
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
||||
Value::Other(..) => Err("unknown data is not supported".into_lua_err())?,
|
||||
})
|
||||
|
|
@ -195,17 +198,18 @@ impl Sendable {
|
|||
Value::Table(_) => Err("table is not supported".into_lua_err())?,
|
||||
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
||||
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
||||
Value::UserData(ud) => {
|
||||
if let Ok(t) = ud.take::<yazi_binding::Url>() {
|
||||
DataKey::Url(t.into())
|
||||
} else if let Ok(t) = ud.take::<yazi_binding::Urn>() {
|
||||
DataKey::Urn(t.into())
|
||||
} else if let Ok(t) = ud.borrow::<yazi_binding::Id>() {
|
||||
DataKey::Id(**t)
|
||||
} else {
|
||||
Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?
|
||||
Value::UserData(ud) => match ud.type_id() {
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Url>() => {
|
||||
DataKey::Url(ud.take::<yazi_binding::Url>()?.into())
|
||||
}
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Urn>() => {
|
||||
DataKey::Urn(ud.take::<yazi_binding::Urn>()?.into())
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Id>() => {
|
||||
DataKey::Id(**ud.borrow::<yazi_binding::Id>()?)
|
||||
}
|
||||
_ => Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?,
|
||||
},
|
||||
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
||||
Value::Other(..) => Err("unknown data is not supported".into_lua_err())?,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ mlua = { workspace = true }
|
|||
paste = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
scopeguard = { workspace = true }
|
||||
textwrap = "0.16.2"
|
||||
tokio = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
|
||||
|
|
@ -47,7 +48,6 @@ tokio-stream = { workspace = true }
|
|||
tracing = { workspace = true }
|
||||
tracing-appender = "0.2.3"
|
||||
tracing-subscriber = { version = "0.3.19", features = [ "env-filter" ] }
|
||||
textwrap = "0.16.2"
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -17,16 +17,7 @@ impl Bar {
|
|||
let new =
|
||||
lua.create_function(|_, (_, edge): (Table, Edge)| Ok(Self { edge, ..Default::default() }))?;
|
||||
|
||||
let bar = lua.create_table_from([
|
||||
// TODO: remove these constants
|
||||
("NONE", Borders::NONE.bits()),
|
||||
("TOP", Borders::TOP.bits()),
|
||||
("RIGHT", Borders::RIGHT.bits()),
|
||||
("BOTTOM", Borders::BOTTOM.bits()),
|
||||
("LEFT", Borders::LEFT.bits()),
|
||||
("ALL", Borders::ALL.bits()),
|
||||
])?;
|
||||
|
||||
let bar = lua.create_table()?;
|
||||
bar.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
|
||||
bar.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,13 +29,6 @@ impl Border {
|
|||
.create_function(|_, (_, edge): (Table, Edge)| Ok(Border { edge, ..Default::default() }))?;
|
||||
|
||||
let border = lua.create_table_from([
|
||||
// TODO: remove these constants
|
||||
("NONE", Borders::NONE.bits()),
|
||||
("TOP", Borders::TOP.bits()),
|
||||
("RIGHT", Borders::RIGHT.bits()),
|
||||
("BOTTOM", Borders::BOTTOM.bits()),
|
||||
("LEFT", Borders::LEFT.bits()),
|
||||
("ALL", Borders::ALL.bits()),
|
||||
// Type
|
||||
("PLAIN", PLAIN),
|
||||
("ROUNDED", ROUNDED),
|
||||
|
|
|
|||
|
|
@ -35,14 +35,7 @@ impl Line {
|
|||
Ok(Line { inner: mem::take(&mut lines[0]), ..Default::default() })
|
||||
})?;
|
||||
|
||||
let line = lua.create_table_from([
|
||||
("parse", parse.into_lua(lua)?),
|
||||
// TODO: remove these constants
|
||||
("LEFT", 0.into_lua(lua)?),
|
||||
("CENTER", 1.into_lua(lua)?),
|
||||
("RIGHT", 2.into_lua(lua)?),
|
||||
])?;
|
||||
|
||||
let line = lua.create_table_from([("parse", parse)])?;
|
||||
line.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
|
||||
line.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::any::TypeId;
|
||||
|
||||
use mlua::{AnyUserData, ExternalError};
|
||||
|
||||
use super::{Bar, Border, Clear, Gauge, Line, List, Table, Text};
|
||||
|
|
@ -6,12 +8,12 @@ use super::{Bar, Border, Clear, Gauge, Line, List, Table, Text};
|
|||
pub enum Renderable {
|
||||
Line(Line),
|
||||
Text(Text),
|
||||
List(List),
|
||||
List(Box<List>),
|
||||
Bar(Bar),
|
||||
Clear(Clear),
|
||||
Border(Border),
|
||||
Gauge(Gauge),
|
||||
Table(Table),
|
||||
Gauge(Box<Gauge>),
|
||||
Table(Box<Table>),
|
||||
}
|
||||
|
||||
impl Renderable {
|
||||
|
|
@ -37,26 +39,16 @@ impl TryFrom<AnyUserData> for Renderable {
|
|||
type Error = mlua::Error;
|
||||
|
||||
fn try_from(ud: AnyUserData) -> Result<Self, Self::Error> {
|
||||
Ok(if let Ok(c) = ud.take::<crate::elements::Line>() {
|
||||
Self::Line(c)
|
||||
} else if let Ok(c) = ud.take::<crate::elements::Text>() {
|
||||
Self::Text(c)
|
||||
} else if let Ok(c) = ud.take::<crate::elements::List>() {
|
||||
Self::List(c)
|
||||
} else if let Ok(c) = ud.take::<crate::elements::Bar>() {
|
||||
Self::Bar(c)
|
||||
} else if let Ok(c) = ud.take::<crate::elements::Clear>() {
|
||||
Self::Clear(c)
|
||||
} else if let Ok(c) = ud.take::<crate::elements::Border>() {
|
||||
Self::Border(c)
|
||||
} else if let Ok(c) = ud.take::<crate::elements::Gauge>() {
|
||||
Self::Gauge(c)
|
||||
} else if let Ok(c) = ud.take::<crate::elements::Table>() {
|
||||
Self::Table(c)
|
||||
} else {
|
||||
return Err(
|
||||
format!("expected a UserData of renderable element, not: {ud:#?}").into_lua_err(),
|
||||
);
|
||||
Ok(match ud.type_id() {
|
||||
Some(t) if t == TypeId::of::<Line>() => Self::Line(ud.take()?),
|
||||
Some(t) if t == TypeId::of::<Text>() => Self::Text(ud.take()?),
|
||||
Some(t) if t == TypeId::of::<List>() => Self::List(Box::new(ud.take()?)),
|
||||
Some(t) if t == TypeId::of::<Bar>() => Self::Bar(ud.take()?),
|
||||
Some(t) if t == TypeId::of::<Clear>() => Self::Clear(ud.take()?),
|
||||
Some(t) if t == TypeId::of::<Border>() => Self::Border(ud.take()?),
|
||||
Some(t) if t == TypeId::of::<Gauge>() => Self::Gauge(Box::new(ud.take()?)),
|
||||
Some(t) if t == TypeId::of::<Table>() => Self::Table(Box::new(ud.take()?)),
|
||||
_ => Err(format!("expected a UserData of renderable element, not: {ud:#?}").into_lua_err())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,17 +27,7 @@ impl Text {
|
|||
Ok(Text { inner: code.as_bytes().into_text().into_lua_err()?, ..Default::default() })
|
||||
})?;
|
||||
|
||||
let text = lua.create_table_from([
|
||||
("parse", parse.into_lua(lua)?),
|
||||
// TODO: remove these constants
|
||||
("LEFT", 0.into_lua(lua)?),
|
||||
("CENTER", 1.into_lua(lua)?),
|
||||
("RIGHT", 2.into_lua(lua)?),
|
||||
("WRAP_NO", 0.into_lua(lua)?),
|
||||
("WRAP", 1.into_lua(lua)?),
|
||||
("WRAP_TRIM", 2.into_lua(lua)?),
|
||||
])?;
|
||||
|
||||
let text = lua.create_table_from([("parse", parse)])?;
|
||||
text.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
|
||||
text.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{io, process::Stdio};
|
||||
use std::{any::TypeId, io, process::Stdio};
|
||||
|
||||
use mlua::{AnyUserData, ExternalError, IntoLuaMulti, Lua, MetaMethod, Table, UserData, Value};
|
||||
use tokio::process::{ChildStderr, ChildStdin, ChildStdout};
|
||||
|
|
@ -118,15 +118,18 @@ impl UserData for Command {
|
|||
_ => Stdio::null(),
|
||||
});
|
||||
}
|
||||
Value::UserData(ud) => {
|
||||
if let Ok(stdin) = ud.take::<ChildStdin>() {
|
||||
return Ok(stdin.try_into()?);
|
||||
} else if let Ok(stdout) = ud.take::<ChildStdout>() {
|
||||
return Ok(stdout.try_into()?);
|
||||
} else if let Ok(stderr) = ud.take::<ChildStderr>() {
|
||||
return Ok(stderr.try_into()?);
|
||||
Value::UserData(ud) => match ud.type_id() {
|
||||
Some(t) if t == TypeId::of::<ChildStdin>() => {
|
||||
return Ok(ud.take::<ChildStdin>()?.try_into()?);
|
||||
}
|
||||
}
|
||||
Some(t) if t == TypeId::of::<ChildStdout>() => {
|
||||
return Ok(ud.take::<ChildStdout>()?.try_into()?);
|
||||
}
|
||||
Some(t) if t == TypeId::of::<ChildStderr>() => {
|
||||
return Ok(ud.take::<ChildStderr>()?.try_into()?);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,14 +47,14 @@ impl SpotLock {
|
|||
|
||||
pub fn table(&self) -> Option<&crate::elements::Table> {
|
||||
self.data.iter().rev().find_map(|r| match r {
|
||||
Renderable::Table(t) => Some(t),
|
||||
Renderable::Table(t) => Some(t.as_ref()),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn table_mut(&mut self) -> Option<&mut crate::elements::Table> {
|
||||
self.data.iter_mut().rev().find_map(|r| match r {
|
||||
Renderable::Table(t) => Some(t),
|
||||
Renderable::Table(t) => Some(t.as_mut()),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ impl Utils {
|
|||
.style(THEME.spot.title),
|
||||
)],
|
||||
}),
|
||||
Renderable::Table(table),
|
||||
Renderable::Table(Box::new(table)),
|
||||
];
|
||||
emit!(Call(Cmd::new("mgr:update_spotted").with_any("lock", lock)));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue