refactor: implement RoCell to replace OnceCell (#63)

This commit is contained in:
三咲雅 · Misaki Masa 2023-08-15 18:49:47 +08:00 committed by GitHub
parent 8fd3d15918
commit 08a0735dde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 143 additions and 104 deletions

117
Cargo.lock generated
View File

@ -11,7 +11,6 @@ dependencies = [
"color_quant",
"config",
"image",
"once_cell",
"ratatui",
"shared",
"tokio",
@ -35,9 +34,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c"
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
dependencies = [
"memchr",
]
@ -109,9 +108,9 @@ dependencies = [
[[package]]
name = "anstyle-wincon"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c"
dependencies = [
"anstyle",
"windows-sys 0.48.0",
@ -119,9 +118,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.72"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
checksum = "f768393e7fabd388fe8409b13faa4d93ab0fef35db1508438dfdb066918bcf38"
[[package]]
name = "app"
@ -206,9 +205,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.3.3"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "block-buffer"
@ -296,6 +295,7 @@ dependencies = [
"anstream",
"anstyle",
"clap_lex",
"once_cell",
"strsim",
]
@ -349,7 +349,6 @@ dependencies = [
"glob",
"indexmap 2.0.0",
"md-5",
"once_cell",
"ratatui",
"regex",
"serde",
@ -372,7 +371,6 @@ dependencies = [
"futures",
"indexmap 2.0.0",
"notify",
"once_cell",
"parking_lot",
"ratatui",
"serde",
@ -466,7 +464,7 @@ version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
dependencies = [
"bitflags 2.3.3",
"bitflags 2.4.0",
"crossterm_winapi",
"futures-core",
"libc",
@ -596,9 +594,9 @@ dependencies = [
[[package]]
name = "flate2"
version = "1.0.26"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
dependencies = [
"crc32fast",
"miniz_oxide",
@ -1018,9 +1016,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.19"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "malloc_buf"
@ -1241,7 +1239,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.48.1",
"windows-targets 0.48.2",
]
[[package]]
@ -1278,9 +1276,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.11"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c516611246607d0c04186886dbb3a754368ef82c79e9827a802c6d836dd111c"
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
[[package]]
name = "pin-utils"
@ -1387,7 +1385,7 @@ version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8285baa38bdc9f879d92c0e37cb562ef38aa3aeefca22b3200186bc39242d3d5"
dependencies = [
"bitflags 2.3.3",
"bitflags 2.4.0",
"cassowary",
"crossterm 0.26.1",
"indoc",
@ -1464,11 +1462,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustix"
version = "0.38.7"
version = "0.38.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399"
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
dependencies = [
"bitflags 2.3.3",
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys",
@ -1634,12 +1632,12 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "socket2"
version = "0.4.9"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
dependencies = [
"libc",
"winapi",
"windows-sys 0.48.0",
]
[[package]]
@ -1702,18 +1700,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.44"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
checksum = "dedd246497092a89beedfe2c9f176d44c1b672ea6090edc20544ade01fbb7ea0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.44"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
checksum = "7d7b1fadccbbc7e19ea64708629f9d8dccd007c260d66485f20a6d41bc1cf4b3"
dependencies = [
"proc-macro2",
"quote",
@ -1786,11 +1784,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.29.1"
version = "1.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920"
dependencies = [
"autocfg",
"backtrace",
"bytes",
"libc",
@ -2167,7 +2164,7 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets 0.48.1",
"windows-targets 0.48.2",
]
[[package]]
@ -2185,7 +2182,7 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.1",
"windows-targets 0.48.2",
]
[[package]]
@ -2205,17 +2202,17 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.48.1"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
checksum = "d1eeca1c172a285ee6c2c84c341ccea837e7c01b12fbb2d0fe3c9e550ce49ec8"
dependencies = [
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
"windows_i686_gnu 0.48.0",
"windows_i686_msvc 0.48.0",
"windows_x86_64_gnu 0.48.0",
"windows_x86_64_gnullvm 0.48.0",
"windows_x86_64_msvc 0.48.0",
"windows_aarch64_gnullvm 0.48.2",
"windows_aarch64_msvc 0.48.2",
"windows_i686_gnu 0.48.2",
"windows_i686_msvc 0.48.2",
"windows_x86_64_gnu 0.48.2",
"windows_x86_64_gnullvm 0.48.2",
"windows_x86_64_msvc 0.48.2",
]
[[package]]
@ -2226,9 +2223,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
checksum = "b10d0c968ba7f6166195e13d593af609ec2e3d24f916f081690695cf5eaffb2f"
[[package]]
name = "windows_aarch64_msvc"
@ -2238,9 +2235,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
checksum = "571d8d4e62f26d4932099a9efe89660e8bd5087775a2ab5cdd8b747b811f1058"
[[package]]
name = "windows_i686_gnu"
@ -2250,9 +2247,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
checksum = "2229ad223e178db5fbbc8bd8d3835e51e566b8474bfca58d2e6150c48bb723cd"
[[package]]
name = "windows_i686_msvc"
@ -2262,9 +2259,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
checksum = "600956e2d840c194eedfc5d18f8242bc2e17c7775b6684488af3a9fff6fe3287"
[[package]]
name = "windows_x86_64_gnu"
@ -2274,9 +2271,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
checksum = "ea99ff3f8b49fb7a8e0d305e5aec485bd068c2ba691b6e277d29eaeac945868a"
[[package]]
name = "windows_x86_64_gnullvm"
@ -2286,9 +2283,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
checksum = "8f1a05a1ece9a7a0d5a7ccf30ba2c33e3a61a30e042ffd247567d1de1d94120d"
[[package]]
name = "windows_x86_64_msvc"
@ -2298,15 +2295,15 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"
version = "0.48.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
checksum = "d419259aba16b663966e29e6d7c6ecfa0bb8425818bb96f6f1f3c3eb71a6e7b9"
[[package]]
name = "winnow"
version = "0.5.4"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64"
checksum = "5504cc7644f4b593cbc05c4a55bf9bd4e94b867c3c0bd440934174d50482427d"
dependencies = [
"memchr",
]

View File

@ -12,7 +12,6 @@ anyhow = "^1"
base64 = "^0"
color_quant = "^1"
image = "^0"
once_cell = "^1"
ratatui = "^0"
tokio = { version = "^1", features = [ "parking_lot" ] }

View File

@ -2,24 +2,22 @@ use std::{path::{Path, PathBuf}, sync::atomic::{AtomicBool, Ordering}};
use anyhow::Result;
use config::{preview::PreviewAdaptor, BOOT, PREVIEW};
use once_cell::sync::Lazy;
use ratatui::prelude::Rect;
use shared::RoCell;
use tokio::{fs, sync::mpsc::UnboundedSender};
use super::{Iterm2, Kitty, Ueberzug};
use super::{Iterm2, Kitty};
use crate::Sixel;
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
#[allow(clippy::type_complexity)]
static UEBERZUG: Lazy<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> =
Lazy::new(|| if PREVIEW.adaptor.needs_ueberzug() { Ueberzug::start().ok() } else { None });
pub(super) static UEBERZUG: RoCell<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> =
RoCell::new();
pub struct Adaptor;
impl Adaptor {
pub fn init() { Lazy::force(&UEBERZUG); }
pub async fn image_show(mut path: &Path, rect: Rect) -> Result<()> {
if IMAGE_SHOWN.swap(true, Ordering::Relaxed) {
Self::image_hide(rect).ok();

View File

@ -13,3 +13,11 @@ use sixel::*;
use ueberzug::*;
pub use crate::{adaptor::*, image::*};
pub fn init() {
UEBERZUG.init(if config::PREVIEW.adaptor.needs_ueberzug() {
Ueberzug::start().ok()
} else {
None
});
}

View File

@ -27,7 +27,9 @@ async fn main() -> anyhow::Result<()> {
config::init();
adaptor::Adaptor::init();
core::init();
adaptor::init();
App::run().await
}

View File

@ -14,7 +14,6 @@ futures = "^0"
glob = "^0"
indexmap = "^2"
md-5 = "^0"
once_cell = "^1"
ratatui = "^0"
regex = "^1"
serde = { version = "^1", features = [ "derive" ] }

View File

@ -1,6 +1,6 @@
#![allow(clippy::module_inception)]
use once_cell::sync::Lazy;
use shared::RoCell;
mod boot;
pub mod keymap;
@ -17,26 +17,30 @@ mod validation;
pub(crate) use pattern::*;
pub(crate) use preset::*;
static MERGED_KEYMAP: Lazy<String> = Lazy::new(Preset::keymap);
static MERGED_THEME: Lazy<String> = Lazy::new(Preset::theme);
static MERGED_YAZI: Lazy<String> = Lazy::new(Preset::yazi);
static MERGED_KEYMAP: RoCell<String> = RoCell::new();
static MERGED_THEME: RoCell<String> = RoCell::new();
static MERGED_YAZI: RoCell<String> = RoCell::new();
pub static BOOT: Lazy<boot::Boot> = Lazy::new(Default::default);
pub static KEYMAP: Lazy<keymap::Keymap> = Lazy::new(Default::default);
pub static LOG: Lazy<log::Log> = Lazy::new(Default::default);
pub static MANAGER: Lazy<manager::Manager> = Lazy::new(Default::default);
pub static OPEN: Lazy<open::Open> = Lazy::new(Default::default);
pub static PREVIEW: Lazy<preview::Preview> = Lazy::new(Default::default);
pub static TASKS: Lazy<tasks::Tasks> = Lazy::new(Default::default);
pub static THEME: Lazy<theme::Theme> = Lazy::new(Default::default);
pub static BOOT: RoCell<boot::Boot> = RoCell::new();
pub static KEYMAP: RoCell<keymap::Keymap> = RoCell::new();
pub static LOG: RoCell<log::Log> = RoCell::new();
pub static MANAGER: RoCell<manager::Manager> = RoCell::new();
pub static OPEN: RoCell<open::Open> = RoCell::new();
pub static PREVIEW: RoCell<preview::Preview> = RoCell::new();
pub static TASKS: RoCell<tasks::Tasks> = RoCell::new();
pub static THEME: RoCell<theme::Theme> = RoCell::new();
pub fn init() {
Lazy::force(&BOOT);
Lazy::force(&KEYMAP);
Lazy::force(&LOG);
Lazy::force(&MANAGER);
Lazy::force(&OPEN);
Lazy::force(&PREVIEW);
Lazy::force(&TASKS);
Lazy::force(&THEME);
MERGED_KEYMAP.with(Preset::keymap);
MERGED_THEME.with(Preset::theme);
MERGED_YAZI.with(Preset::yazi);
BOOT.with(Default::default);
KEYMAP.with(Default::default);
LOG.with(Default::default);
MANAGER.with(Default::default);
OPEN.with(Default::default);
PREVIEW.with(Default::default);
TASKS.with(Default::default);
THEME.with(Default::default);
}

View File

@ -15,7 +15,6 @@ crossterm = "^0"
futures = "^0"
indexmap = "^2"
notify = { version = "^6", default-features = false, features = [ "macos_fsevent" ] }
once_cell = "^1"
parking_lot = "^0"
ratatui = "^0"
serde = "^1"

View File

@ -1,4 +1,6 @@
use once_cell::sync::Lazy;
use shared::RoCell;
use tokio::sync::Semaphore;
pub static BLOCKER: Lazy<Semaphore> = Lazy::new(|| Semaphore::new(1));
pub static BLOCKER: RoCell<Semaphore> = RoCell::new();
pub(super) fn init_blocker() { BLOCKER.init(Semaphore::new(1)) }

View File

@ -3,11 +3,12 @@ use std::{collections::BTreeMap, ffi::OsString, path::PathBuf};
use anyhow::Result;
use config::{keymap::{Control, KeymapLayer}, open::Opener};
use crossterm::event::KeyEvent;
use shared::RoCell;
use tokio::sync::{mpsc::UnboundedSender, oneshot};
use super::{files::{File, FilesOp}, input::InputOpt, manager::PreviewData, select::SelectOpt};
static mut TX: Option<UnboundedSender<Event>> = None;
static TX: RoCell<UnboundedSender<Event>> = RoCell::new();
pub enum Event {
Quit,
@ -38,21 +39,13 @@ pub enum Event {
impl Event {
#[inline]
pub fn init(tx: UnboundedSender<Event>) {
unsafe {
TX.replace(tx);
}
}
pub fn init(tx: UnboundedSender<Event>) { TX.init(tx); }
#[inline]
pub fn emit(self) {
let tx = unsafe { TX.as_ref().unwrap() };
tx.send(self).ok();
}
pub fn emit(self) { TX.send(self).ok(); }
pub async fn wait<T>(self, rx: oneshot::Receiver<T>) -> T {
let tx = unsafe { TX.as_ref().unwrap() };
tx.send(self).ok();
TX.send(self).ok();
rx.await.unwrap()
}
}

View File

@ -22,3 +22,5 @@ pub use blocker::*;
pub use event::*;
pub use highlighter::*;
pub use position::*;
pub fn init() { init_blocker(); }

View File

@ -4,6 +4,7 @@ mod defer;
mod fns;
mod fs;
mod mime;
mod ro_cell;
mod term;
mod throttle;
mod tty;
@ -14,6 +15,7 @@ pub use defer::*;
pub use fns::*;
pub use fs::*;
pub use mime::*;
pub use ro_cell::*;
pub use term::*;
pub use throttle::*;
pub use tty::*;

34
shared/src/ro_cell.rs Normal file
View File

@ -0,0 +1,34 @@
use std::{cell::UnsafeCell, ops::Deref};
// Read-only cell. It's safe to use this in a static variable, but it's not safe
// to mutate it. This is useful for storing static data that is expensive to
// initialize, but is immutable once.
pub struct RoCell<T>(UnsafeCell<Option<T>>);
unsafe impl<T> Sync for RoCell<T> {}
impl<T> RoCell<T> {
#[inline]
pub const fn new() -> Self { Self(UnsafeCell::new(None)) }
#[inline]
pub fn init(&self, value: T) {
unsafe {
*self.0.get() = Some(value);
}
}
#[inline]
pub fn with<F>(&self, f: F)
where
F: FnOnce() -> T,
{
self.init(f());
}
}
impl<T> Deref for RoCell<T> {
type Target = T;
fn deref(&self) -> &Self::Target { unsafe { (*self.0.get()).as_ref().unwrap() } }
}