From 63cfcbe7a7745b276de58ec92e0141b958c44feb Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Sat, 10 Aug 2024 19:06:46 +0200 Subject: use unsafe blocks instead of mutexes --- src/app.rs | 10 ++++---- src/config/constants.rs | 23 ----------------- src/config/env.rs | 22 ++++++++++++++++ src/config/keymap/template.rs | 8 +++--- src/config/mod.rs | 18 ++++--------- src/config/theme/bar.rs | 8 +++--- src/config/theme/editor/bar.rs | 3 +-- src/config/theme/editor/mod.rs | 18 +++++-------- src/config/theme/view/bar.rs | 3 +-- src/config/theme/view/mod.rs | 16 ++++-------- src/lua/mod.rs | 57 ++++++++++++++++++------------------------ src/lua/runtime.rs | 8 +++--- src/sheet/cell.rs | 38 ++++++++-------------------- src/sheet/loader.rs | 19 +++++--------- src/sheet/luaref.rs | 53 +++++++++++++++++++-------------------- src/sheet/map.rs | 15 +++++------ src/sheet/register.rs | 31 ++++++++--------------- src/sheet/tablized.rs | 3 +-- src/state/bar.rs | 8 +++--- src/state/editor/bar.rs | 3 +-- src/state/editor/mod.rs | 24 ++++++------------ src/state/log.rs | 4 +-- src/state/mod.rs | 18 ++++++------- src/state/view/bar.rs | 3 +-- src/state/view/mod.rs | 37 +++++++++------------------ src/widgets/luaeditor/mod.rs | 12 ++++----- src/widgets/sheetview/mod.rs | 15 ++++++----- 27 files changed, 189 insertions(+), 288 deletions(-) delete mode 100644 src/config/constants.rs create mode 100644 src/config/env.rs (limited to 'src') diff --git a/src/app.rs b/src/app.rs index 87da612..3e21cf7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -29,7 +29,7 @@ pub struct App { impl App { pub fn new() -> Self { let sheet_id = Register::create(10, 50); - GlobalState::instance_mut() + GlobalState::get() .view .set_active_sheet(Some(sheet_id)); @@ -42,13 +42,13 @@ impl App { } pub fn run(mut self, terminal: &mut tui::Tui) -> io::Result<()> { - if let Err(e) = lua::source(&config::constants::USER_RC_PATH) { + if let Err(e) = lua::source(&config::env::USER_RC_PATH) { tui::restore()?; println!("{}", e); return Ok(()); } - while !{ GlobalState::instance().exit } { + while !{ GlobalState::get().exit } { terminal.draw(|frame| { self.render_frame(frame); @@ -84,7 +84,7 @@ impl App { } fn handle_key_event(&mut self, event: KeyEvent) { - let focus = { GlobalState::instance().active_window }; + let focus = { GlobalState::get().active_window }; let populate = GlobalKeyMap::handle(event); if populate { @@ -98,7 +98,7 @@ impl App { } fn area(&self, area: Rect) -> (Rect, Option, Option) { - let state = GlobalState::instance(); + let state = GlobalState::get(); let mut view = area; let mut editor = None; let mut log = None; diff --git a/src/config/constants.rs b/src/config/constants.rs deleted file mode 100644 index 5a8283a..0000000 --- a/src/config/constants.rs +++ /dev/null @@ -1,23 +0,0 @@ -use lazy_static::lazy_static; - -lazy_static! { - pub static ref USER_CONFIG_DIR: String = { - match dirs::config_local_dir() { - Some(mut d) => { - d.push("neosheet"); - d.as_path().to_str().unwrap_or("").to_string() - } - None => String::new(), - } - }; - pub static ref USER_RC_PATH: String = { - match dirs::config_local_dir() { - Some(mut d) => { - d.push("neosheet"); - d.push("init.lua"); - d.as_path().to_str().unwrap_or("").to_string() - } - None => String::new(), - } - }; -} diff --git a/src/config/env.rs b/src/config/env.rs new file mode 100644 index 0000000..5d53cc5 --- /dev/null +++ b/src/config/env.rs @@ -0,0 +1,22 @@ +use once_cell::sync::Lazy; + +pub static USER_CONFIG_DIR: Lazy = Lazy::new(|| { + match dirs::config_local_dir() { + Some(mut d) => { + d.push("neosheet"); + d.as_path().to_str().unwrap_or("").to_string() + } + None => String::new(), + } +}); + +pub static USER_RC_PATH: Lazy = Lazy::new(|| { + match dirs::config_local_dir() { + Some(mut d) => { + d.push("neosheet"); + d.push("init.lua"); + d.as_path().to_str().unwrap_or("").to_string() + } + None => String::new(), + } +}); diff --git a/src/config/keymap/template.rs b/src/config/keymap/template.rs index cf68f80..37ebedf 100644 --- a/src/config/keymap/template.rs +++ b/src/config/keymap/template.rs @@ -17,7 +17,7 @@ macro_rules! KeyMapSections { pub fn handle(event: KeyEvent) -> bool { let (def, func) = { - let mut config = GlobalConfig::instance_mut(); + let config = GlobalConfig::get(); (config.keymap.$key.default_return, config.keymap.$key.store.get(event)) }; @@ -33,7 +33,7 @@ macro_rules! KeyMapSections { } pub fn map(event: KeyEvent, func: impl Runnable<(), bool> + 'static) { - GlobalConfig::instance_mut() + GlobalConfig::get() .keymap .$key .store @@ -44,11 +44,11 @@ macro_rules! KeyMapSections { impl UserData for $name { fn add_fields<'lua, M: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut M) { fields.add_field_function_get("default", |_, _| { - Ok(GlobalConfig::instance().keymap.$key.default_return) + Ok(GlobalConfig::get().keymap.$key.default_return) }); fields.add_field_function_set("default", |_, _, def: bool| { - GlobalConfig::instance_mut().keymap.$key.default_return = def; + GlobalConfig::get().keymap.$key.default_return = def; Ok(()) }) } diff --git a/src/config/mod.rs b/src/config/mod.rs index cc4154c..4aac0cf 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,11 +1,10 @@ -use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::ptr::addr_of_mut; -use lazy_static::lazy_static; use mlua::{UserData, UserDataFields}; use self::{keymap::KeyMap, theme::Theme}; -pub mod constants; +pub mod env; pub mod theme; pub mod keymap; @@ -15,10 +14,6 @@ pub struct GlobalConfig { pub keymap: KeyMap, } -lazy_static! { - static ref GLOBAL_CONFIG: RwLock = RwLock::new(GlobalConfig::new()); -} - const DUMMY_CONFIG: GlobalConfig = GlobalConfig::new(); impl GlobalConfig { @@ -29,12 +24,9 @@ impl GlobalConfig { } } - pub fn instance() -> RwLockReadGuard<'static, Self> { - GLOBAL_CONFIG.read().unwrap() - } - - pub fn instance_mut() -> RwLockWriteGuard<'static, Self> { - GLOBAL_CONFIG.write().unwrap() + pub fn get() -> &'static mut Self { + static mut GLOBAL_CONFIG: GlobalConfig = GlobalConfig::new(); + unsafe { &mut *addr_of_mut!(GLOBAL_CONFIG) } } } diff --git a/src/config/theme/bar.rs b/src/config/theme/bar.rs index a28bede..59b6c00 100644 --- a/src/config/theme/bar.rs +++ b/src/config/theme/bar.rs @@ -1,5 +1,5 @@ macro_rules! BarTheme { - ($name:ident, $type:ty, $cfg:expr, $cfg_mut:expr) => { + ($name:ident, $type:ty, $cfg:expr) => { use crate::config::theme::style::Style; use crate::lua::evalsto::EvalTo; use crate::widgets::statusbar::StatusBar; @@ -38,19 +38,19 @@ macro_rules! BarTheme { fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_function_get("left", |_, _| Ok($cfg.left.clone())); fields.add_field_function_set("left", |_, _, style: EvalTo| { - $cfg_mut.left = style; + $cfg.left = style; Ok(()) }); fields.add_field_function_get("middle", |_, _| Ok($cfg.middle.clone())); fields.add_field_function_set("middle", |_, _, style: EvalTo| { - $cfg_mut.middle = style; + $cfg.middle = style; Ok(()) }); fields.add_field_function_get("right", |_, _| Ok($cfg.right.clone())); fields.add_field_function_set("right", |_, _, style: EvalTo| { - $cfg_mut.right = style; + $cfg.right = style; Ok(()) }); } diff --git a/src/config/theme/editor/bar.rs b/src/config/theme/editor/bar.rs index 62be7b0..e0ff0a7 100644 --- a/src/config/theme/editor/bar.rs +++ b/src/config/theme/editor/bar.rs @@ -3,6 +3,5 @@ use crate::config::{theme::bar::BarTheme, GlobalConfig}; BarTheme!( EditorBarTheme, (), - GlobalConfig::instance().theme.editor.bar, - GlobalConfig::instance_mut().theme.editor.bar + GlobalConfig::get().theme.editor.bar ); diff --git a/src/config/theme/editor/mod.rs b/src/config/theme/editor/mod.rs index 662dacc..33ab600 100644 --- a/src/config/theme/editor/mod.rs +++ b/src/config/theme/editor/mod.rs @@ -36,13 +36,7 @@ impl EditorTheme { macro_rules! cfg { () => { - GlobalConfig::instance().theme.editor - }; -} - -macro_rules! cfg_mut { - () => { - GlobalConfig::instance_mut().theme.editor + GlobalConfig::get().theme.editor }; } @@ -50,25 +44,25 @@ impl UserData for EditorTheme { fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_function_get("background", |_, _| Ok(cfg!().background.clone())); fields.add_field_function_set("background", |_, _, background: EvalTo| { - cfg_mut!().background = background; + cfg!().background = background; Ok(()) }); fields.add_field_function_get("highlight", |_, _| Ok(cfg!().highlight.clone())); fields.add_field_function_set("highlight", |_, _, highlight: HighlightTheme| { - cfg_mut!().highlight = highlight; + cfg!().highlight = highlight; Ok(()) }); fields.add_field_function_get("cursor_line", |_, _| Ok(cfg!().cursor_line.clone())); fields.add_field_function_set("cursor_line", |_, _, cursor_line: EvalTo| { - cfg_mut!().cursor_line = cursor_line; + cfg!().cursor_line = cursor_line; Ok(()) }); fields.add_field_function_get("line_number", |_, _| Ok(cfg!().line_number.clone())); fields.add_field_function_set("line_number", |_, _, line_number: EvalTo| { - cfg_mut!().line_number = line_number; + cfg!().line_number = line_number; Ok(()) }); @@ -78,7 +72,7 @@ impl UserData for EditorTheme { fields.add_field_function_set( "active_line_number", |_, _, active_line_number: EvalTo| { - cfg_mut!().active_line_number = active_line_number; + cfg!().active_line_number = active_line_number; Ok(()) }, ); diff --git a/src/config/theme/view/bar.rs b/src/config/theme/view/bar.rs index 7fab31a..c2d759b 100644 --- a/src/config/theme/view/bar.rs +++ b/src/config/theme/view/bar.rs @@ -4,6 +4,5 @@ use crate::{config::GlobalConfig, state::view::mode::Mode}; BarTheme!( SheetViewBarTheme, Mode, - GlobalConfig::instance().theme.view.bar, - GlobalConfig::instance_mut().theme.view.bar + GlobalConfig::get().theme.view.bar ); diff --git a/src/config/theme/view/mod.rs b/src/config/theme/view/mod.rs index e88e9ad..931e7dd 100644 --- a/src/config/theme/view/mod.rs +++ b/src/config/theme/view/mod.rs @@ -32,13 +32,7 @@ impl SheetViewTheme { macro_rules! cfg { () => { - GlobalConfig::instance().theme.view - }; -} - -macro_rules! cfg_mut { - () => { - GlobalConfig::instance_mut().theme.view + GlobalConfig::get().theme.view }; } @@ -47,25 +41,25 @@ impl UserData for SheetViewTheme { fields.add_field_function_get("cursor", |_, _| Ok(cfg!().cursor.clone())); fields.add_field_function_set("cursor", |_, _, pair: EvalTo| { - cfg_mut!().cursor = pair; + cfg!().cursor = pair; Ok(()) }); fields.add_field_function_get("selection", |_, _| Ok(cfg!().selection.clone())); fields.add_field_function_set("selection", |_, _, pair: EvalTo| { - cfg_mut!().selection = pair; + cfg!().selection = pair; Ok(()) }); fields.add_field_function_get("cell", |_, _| Ok(cfg!().cell.clone())); fields.add_field_function_set("cell", |_, _, cell: EvalTo| { - cfg_mut!().cell = cell; + cfg!().cell = cell; Ok(()) }); fields.add_field_function_get("background", |_, _| Ok(cfg!().background.clone())); fields.add_field_function_set("background", |_, _, background: EvalTo| { - cfg_mut!().background = background; + cfg!().background = background; Ok(()) }); diff --git a/src/lua/mod.rs b/src/lua/mod.rs index afa6171..e7c3352 100644 --- a/src/lua/mod.rs +++ b/src/lua/mod.rs @@ -1,10 +1,6 @@ -use std::{ - path::Path, - sync::{Mutex, MutexGuard}, -}; - -use lazy_static::lazy_static; use mlua::prelude::*; +use once_cell::sync::Lazy; +use std::{path::Path, ptr::addr_of_mut}; use crate::{ config::{ @@ -18,27 +14,8 @@ use crate::{ pub mod evalsto; pub mod iobuffer; pub mod ownedfunction; -pub mod runtime; pub mod runnable; - -lazy_static! { - static ref LUA: Mutex = { - let lock = Mutex::new(Lua::new()); - - { - let lua = lock.lock().unwrap(); - - let print_binding = lua.create_function(print).unwrap(); - lua.globals().set("print", print_binding).unwrap(); - - runtime::math(&lua).unwrap(); - runtime::neosheet(&lua).unwrap(); - runtime::package(&lua).unwrap(); - } - - lock - }; -} +pub mod runtime; macro_rules! ud_is_type { ($writer:ident, $ud:ident, $f:ty => $fe:expr $(, $($r:ty => $e:expr),+)? $(,)?) => { @@ -61,11 +38,11 @@ fn print(_: &Lua, args: LuaMultiValue) -> LuaResult<()> { writer, ud, CellRef => ud.borrow::(), - GlobalConfig => GlobalConfig::instance(), - Theme => GlobalConfig::instance().theme, - SheetViewTheme => GlobalConfig::instance().theme.view, - GlobalState => GlobalState::instance(), - SheetViewState => GlobalState::instance().view, + GlobalConfig => GlobalConfig::get(), + Theme => GlobalConfig::get().theme, + SheetViewTheme => GlobalConfig::get().theme.view, + GlobalState => GlobalState::get(), + SheetViewState => GlobalState::get().view, ); } else { writer.write(format!("{:#?}", arg)); @@ -79,8 +56,22 @@ fn print(_: &Lua, args: LuaMultiValue) -> LuaResult<()> { Ok(()) } -pub fn get() -> MutexGuard<'static, Lua> { - LUA.lock().unwrap() +pub fn get() -> &'static mut Lazy { + static mut LUA: Lazy = Lazy::new(|| { + let lua = Lua::new(); + + let print_binding = lua.create_function(print).unwrap(); + lua.globals().set("print", print_binding).unwrap(); + + runtime::math(&lua).unwrap(); + runtime::neosheet(&lua).unwrap(); + runtime::package(&lua).unwrap(); + + lua + }); + + + unsafe { &mut *addr_of_mut!(LUA) } } pub fn source(path: &str) -> LuaResult<()> { diff --git a/src/lua/runtime.rs b/src/lua/runtime.rs index 6a0a230..71bf21a 100644 --- a/src/lua/runtime.rs +++ b/src/lua/runtime.rs @@ -50,10 +50,10 @@ pub fn package(lua: &Lua) -> Result<()> { "path", format!( "{}/?.lua;{}/?/init.lua;{}/lib/?.lua;{}/lib/?/init.lua;{};./?.lua", - config::constants::USER_CONFIG_DIR.as_str(), - config::constants::USER_CONFIG_DIR.as_str(), - config::constants::USER_CONFIG_DIR.as_str(), - config::constants::USER_CONFIG_DIR.as_str(), + config::env::USER_CONFIG_DIR.as_str(), + config::env::USER_CONFIG_DIR.as_str(), + config::env::USER_CONFIG_DIR.as_str(), + config::env::USER_CONFIG_DIR.as_str(), path.split(';') .filter(|s| s.starts_with('/')) .collect::>() diff --git a/src/sheet/cell.rs b/src/sheet/cell.rs index b46b7d4..d723732 100644 --- a/src/sheet/cell.rs +++ b/src/sheet/cell.rs @@ -98,14 +98,14 @@ impl CellRef { sheet_id, row, column, - value: cell + value: cell, } } pub fn fetch_new(sheet_id: SheetId, row: usize, column: usize) -> Option { Register::get(sheet_id) .map(|sheet| { - sheet.read().unwrap().get_cell(row, column).map(|cell| Self { + sheet.get_cell(row, column).map(|cell| Self { sheet_id, row, column, @@ -120,12 +120,10 @@ impl CellRef { } pub fn set_value(&mut self, cell: Cell) { - self.value = cell.clone(); - Register::get(self.sheet_id) - .unwrap() - .write() - .unwrap() - .set_cell(self.row, self.column, cell); + if let Some(sheet) = Register::get(self.sheet_id) { + self.value = cell.clone(); + sheet.set_cell(self.row, self.column, cell); + } } pub fn left(&self) -> Option { @@ -157,16 +155,8 @@ impl CellRef { } pub fn end(&self) -> Option { - Self::fetch_new( - self.sheet_id, - self.row, - Register::get(self.sheet_id) - .unwrap() - .read() - .unwrap() - .width() - - 1, - ) + Register::get(self.sheet_id) + .map(|sheet| Self::fetch_new(self.sheet_id, self.row, sheet.width() - 1))? } pub fn top(&self) -> Option { @@ -174,16 +164,8 @@ impl CellRef { } pub fn bottom(&self) -> Option { - Self::fetch_new( - self.sheet_id, - Register::get(self.sheet_id) - .unwrap() - .read() - .unwrap() - .height() - - 1, - self.column, - ) + Register::get(self.sheet_id) + .map(|sheet| Self::fetch_new(self.sheet_id, sheet.height() - 1, self.column))? } } diff --git a/src/sheet/loader.rs b/src/sheet/loader.rs index 613d2a5..35b6da2 100644 --- a/src/sheet/loader.rs +++ b/src/sheet/loader.rs @@ -1,20 +1,12 @@ -use std::{ - collections::HashMap, - path::Path, - sync::{Mutex, MutexGuard}, -}; +use std::{collections::HashMap, path::Path, ptr::addr_of_mut}; -use lazy_static::lazy_static; use mlua::{Lua, UserData}; +use once_cell::sync::Lazy; use crate::lua::{ownedfunction::OwnedFunction, runnable::Runnable}; use super::{register::SheetId, tablized::Tablized}; -lazy_static! { - static ref GLOBAL_LOADER: Mutex = Mutex::new(Loader::new()); -} - #[derive(Default)] pub struct Loader { loaders: HashMap>>, @@ -40,15 +32,16 @@ impl Loader { self.loaders.insert(extension, func); } - pub fn get() -> MutexGuard<'static, Loader> { - GLOBAL_LOADER.lock().unwrap() + pub fn get() -> &'static mut Self { + static mut GLOBAL_LOADER: Lazy = Lazy::new(|| Loader::new()); + unsafe { &mut *addr_of_mut!(GLOBAL_LOADER) } } } impl UserData for Loader { fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_function("add", |_, (extension, func): (String, OwnedFunction)| { - GLOBAL_LOADER.lock().unwrap().add(extension, Box::new(func)); + Loader::get().add(extension, Box::new(func)); Ok(()) }); } diff --git a/src/sheet/luaref.rs b/src/sheet/luaref.rs index 1a2fd5f..f587f37 100644 --- a/src/sheet/luaref.rs +++ b/src/sheet/luaref.rs @@ -1,9 +1,6 @@ use crate::state::GlobalState; -use super::{ - map::LuaMap, - register::{Register, SheetId}, -}; +use super::{map::LuaMap, register::{Register, SheetId}}; use mlua::prelude::*; pub struct SheetLuaRef { @@ -23,18 +20,17 @@ impl SheetLuaRef { impl LuaUserData for SheetLuaRef { fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_method_get("width", |_, luaref| { - Ok(Register::get(luaref.id).unwrap().read().unwrap().width()) + Ok(Register::get(luaref.id).map(|s| s.width())) }); fields.add_field_method_get("height", |_, luaref| { - Ok(Register::get(luaref.id).unwrap().read().unwrap().height()) + Ok(Register::get(luaref.id).map(|s| s.height())) }); } fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_method_mut("cell", |lua, luaref, (row, column): (usize, usize)| { - if let Some(rw) = Register::get(luaref.id) { - let sheet = rw.read().unwrap(); + if let Some(sheet) = Register::get(luaref.id) { Ok(sheet.get_ref(row, column).into_lua(lua).unwrap()) } else { Ok(LuaValue::Nil) @@ -42,31 +38,34 @@ impl LuaUserData for SheetLuaRef { }); methods.add_method_mut("map", |_, luaref, func: LuaFunction| { - let range: Vec<_> = { - let state = GlobalState::instance(); - let lock = state.view.active_sheet().unwrap(); - let sheet = lock.read().unwrap(); + if let Some(sheet) = Register::get(luaref.id) { + let range: Vec<_> = { + let state = GlobalState::get(); + let sheet = state.view.active_sheet().unwrap(); - if sheet.id() != luaref.id() { - return Ok(()); - } + if sheet.id() != luaref.id() { + return Ok(()); + } - let (width, height) = (sheet.width(), sheet.height()); + let (width, height) = (sheet.width(), sheet.height()); - if state.view.selection_anchor.is_some() { - state.view.selection() - } else { - let mut cells = Vec::new(); - for row in 0..height { - for column in 0..width { - cells.push((row, column)); + if state.view.selection_anchor.is_some() { + state.view.selection() + } else { + let mut cells = Vec::new(); + for row in 0..height { + for column in 0..width { + cells.push((row, column)); + } } + cells } - cells - } - }; + }; - Register::get(luaref.id).unwrap().lua_map(func, range) + sheet.lua_map(func, range) + } else { + Err(mlua::Error::runtime("unvalid sheet")) + } }) } } diff --git a/src/sheet/map.rs b/src/sheet/map.rs index b2cdbf2..8d3fecc 100644 --- a/src/sheet/map.rs +++ b/src/sheet/map.rs @@ -1,28 +1,25 @@ -use std::sync::{Arc, RwLock}; - use mlua::prelude::*; use super::{cell::Cell, Sheet}; pub trait LuaMap { fn lua_map( - &self, + &mut self, func: LuaFunction<'_>, range: Vec<(usize, usize)>, ) -> Result<(), LuaError>; } -impl LuaMap for Arc> { +impl LuaMap for Sheet { fn lua_map( - &self, + &mut self, func: LuaFunction<'_>, range: Vec<(usize, usize)>, ) -> Result<(), LuaError> { - let mut this = self.write().unwrap(); - let mut sheet = this.clone(); + let mut sheet = self.clone(); for (row, column) in range.iter() { - let cellref = this.get_ref(*row, *column); + let cellref = self.get_ref(*row, *column); match func.call::<_, Cell>(cellref) { Ok(cell) => sheet.set_cell(*row, *column, cell), @@ -30,7 +27,7 @@ impl LuaMap for Arc> { } } - this.apply(sheet); + self.apply(sheet); Ok(()) } diff --git a/src/sheet/register.rs b/src/sheet/register.rs index aaf9c35..82982e9 100644 --- a/src/sheet/register.rs +++ b/src/sheet/register.rs @@ -1,10 +1,8 @@ -use std::sync::{Arc, RwLock}; - use mlua::{Table, UserData, Value}; use super::{cell::Cell, loader::Loader, luaref::SheetLuaRef, Sheet}; -static REGISTER: RwLock>>> = RwLock::new(Vec::new()); +static mut REGISTER: Vec = Vec::new(); pub type SheetId = usize; @@ -13,17 +11,16 @@ pub struct Register; impl Register { pub fn create(width: usize, height: usize) -> SheetId { - let mut register = REGISTER.write().unwrap(); - - let id = register.len(); - let sheet = Sheet::new(width, height, id); - register.push(Arc::new(RwLock::new(sheet))); - id + unsafe { + let id = REGISTER.len(); + let sheet = Sheet::new(width, height, id); + REGISTER.push(sheet); + id + } } pub fn create_from_table(table: Table) -> mlua::Result { - let mut register = REGISTER.write().unwrap(); - let id = register.len(); + let id = unsafe { REGISTER.len() }; let height = table.len()? as usize; let mut width: usize = 0; @@ -42,18 +39,12 @@ impl Register { } } - register.push(Arc::new(RwLock::new(sheet))); + unsafe { REGISTER.push(sheet) }; Ok(id) } - pub fn get(id: SheetId) -> Option>> { - let register = REGISTER.read().unwrap(); - - if id < register.len() { - Some(Arc::clone(®ister[id])) - } else { - None - } + pub fn get(id: SheetId) -> Option<&'static mut Sheet> { + unsafe { REGISTER.get_mut(id) } } } diff --git a/src/sheet/tablized.rs b/src/sheet/tablized.rs index a40af0d..27b17e0 100644 --- a/src/sheet/tablized.rs +++ b/src/sheet/tablized.rs @@ -22,8 +22,7 @@ impl Tablized { .len(); let id = Register::create(columns, rows); - let lock = Register::get(id).unwrap(); - let mut sheet = lock.write().unwrap(); + let sheet = Register::get(id).unwrap(); for row in 0..rows { for column in 0..columns { diff --git a/src/state/bar.rs b/src/state/bar.rs index 2f8e6aa..ea69dfe 100644 --- a/src/state/bar.rs +++ b/src/state/bar.rs @@ -1,5 +1,5 @@ macro_rules! BarState { - ($name:ident, $type:ty, $cfg:expr, $cfg_mut:expr) => { + ($name:ident, $type:ty, $cfg:expr) => { use crate::lua::evalsto::EvalTo; use crate::widgets::statusbar::StatusBar; use mlua::{Lua, UserData}; @@ -36,19 +36,19 @@ macro_rules! BarState { fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_function_get("left", |_, _| Ok($cfg.left.clone())); fields.add_field_function_set("left", |_, _, style: EvalTo| { - $cfg_mut.left = style; + $cfg.left = style; Ok(()) }); fields.add_field_function_get("middle", |_, _| Ok($cfg.middle.clone())); fields.add_field_function_set("middle", |_, _, style: EvalTo| { - $cfg_mut.middle = style; + $cfg.middle = style; Ok(()) }); fields.add_field_function_get("right", |_, _| Ok($cfg.right.clone())); fields.add_field_function_set("right", |_, _, style: EvalTo| { - $cfg_mut.right = style; + $cfg.right = style; Ok(()) }); } diff --git a/src/state/editor/bar.rs b/src/state/editor/bar.rs index 752d021..f6163af 100644 --- a/src/state/editor/bar.rs +++ b/src/state/editor/bar.rs @@ -3,6 +3,5 @@ use crate::state::{bar::BarState, GlobalState}; BarState!( EditorBarState, (), - GlobalState::instance().editor.bar, - GlobalState::instance_mut().editor.bar + GlobalState::get().editor.bar ); diff --git a/src/state/editor/mod.rs b/src/state/editor/mod.rs index 3639226..3e9d9e0 100644 --- a/src/state/editor/mod.rs +++ b/src/state/editor/mod.rs @@ -19,13 +19,7 @@ pub struct EditorState { macro_rules! cfg { () => { - GlobalState::instance().editor - }; -} - -macro_rules! cfg_mut { - () => { - GlobalState::instance_mut().editor + GlobalState::get().editor }; } @@ -51,12 +45,11 @@ impl UserData for EditorState { fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_function_get("visible", |_, _| Ok(cfg!().visible)); fields.add_field_function_set("visible", |_, _, visible: bool| { - let mut state = GlobalState::instance_mut(); - state.editor.visible = visible; + cfg!().visible = visible; - if let Window::Editor = state.active_window { + if let Window::Editor = GlobalState::get().active_window { if !visible { - state.set_focus(Window::View); + GlobalState::get().set_focus(Window::View); } } @@ -65,17 +58,16 @@ impl UserData for EditorState { fields.add_field_function_get("content", |_, _| Ok(cfg!().buffer.as_string())); fields.add_field_function_set("content", |_, _, content: String| { - cfg_mut!().buffer.set_lines_from_string(content); + cfg!().buffer.set_lines_from_string(content); Ok(()) }); fields.add_field_function_get("cursor_shape", |_, _| Ok(cfg!().cursor_shape)); fields.add_field_function_set("cursor_shape", |_, _, shape: CursorShape| { - cfg_mut!().cursor_shape = shape; + cfg!().cursor_shape = shape; Ok(()) }); - fields.add_field_function_get("lines", |lua, _| { let table = lua.create_table()?; @@ -86,7 +78,7 @@ impl UserData for EditorState { Ok(table) }); fields.add_field_function_set("lines", |_, _, content: String| { - cfg_mut!().buffer.set_lines_from_string(content); + cfg!().buffer.set_lines_from_string(content); Ok(()) }); @@ -100,7 +92,7 @@ impl UserData for EditorState { }); methods.add_function("move_cursor", |_, m: CursorMove| { - cfg_mut!().buffer.move_cursor(m); + cfg!().buffer.move_cursor(m); Ok(()) }) } diff --git a/src/state/log.rs b/src/state/log.rs index f9b4665..6c0c924 100644 --- a/src/state/log.rs +++ b/src/state/log.rs @@ -14,7 +14,7 @@ impl LogState { macro_rules! cfg { () => { - GlobalState::instance().log + GlobalState::get().log }; } @@ -22,7 +22,7 @@ impl UserData for LogState { fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_function_get("visible", |_, _| Ok(cfg!().visible)); fields.add_field_function_set("visible", |_, _, visible: bool| { - let mut state = GlobalState::instance_mut(); + let state = GlobalState::get(); state.log.visible = visible; if let Window::Log = state.active_window { diff --git a/src/state/mod.rs b/src/state/mod.rs index 138b597..1b1430d 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -1,4 +1,4 @@ -use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::ptr::addr_of_mut; use mlua::{UserData, UserDataFields}; @@ -19,7 +19,6 @@ pub struct GlobalState { pub exit: bool, } -static GLOBAL_STATE: RwLock = RwLock::new(GlobalState::new()); const DUMMY_STATE: GlobalState = GlobalState::new(); impl GlobalState { @@ -33,12 +32,9 @@ impl GlobalState { } } - pub fn instance() -> RwLockReadGuard<'static, Self> { - GLOBAL_STATE.read().unwrap() - } - - pub fn instance_mut() -> RwLockWriteGuard<'static, Self> { - GLOBAL_STATE.write().unwrap() + pub fn get() -> &'static mut Self { + static mut GLOBAL_STATE: GlobalState = GlobalState::new(); + unsafe { &mut *addr_of_mut!(GLOBAL_STATE) } } pub fn set_focus(&mut self, win: window::Window) { @@ -58,17 +54,17 @@ impl UserData for GlobalState { fields.add_field_function_get("editor", |_, _| Ok(DUMMY_STATE.editor)); fields.add_field_function_get("log", |_, _| Ok(DUMMY_STATE.log)); fields.add_field_function_get("active_window", |_, _| { - Ok(GlobalState::instance().active_window) + Ok(GlobalState::get().active_window) }); fields.add_field_function_set("active_window", |_, _, win: window::Window| { - GlobalState::instance_mut().set_focus(win); + GlobalState::get().set_focus(win); Ok(()) }); } fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_function("quit", |_, _: ()| { - GlobalState::instance_mut().exit = true; + GlobalState::get().exit = true; Ok(()) }) } diff --git a/src/state/view/bar.rs b/src/state/view/bar.rs index 57898f5..f935de7 100644 --- a/src/state/view/bar.rs +++ b/src/state/view/bar.rs @@ -5,6 +5,5 @@ use super::mode::Mode; BarState!( SheetViewBarState, Mode, - GlobalState::instance().view.bar, - GlobalState::instance_mut().view.bar + GlobalState::get().view.bar ); diff --git a/src/state/view/mod.rs b/src/state/view/mod.rs index 961c4ca..41937a1 100644 --- a/src/state/view/mod.rs +++ b/src/state/view/mod.rs @@ -1,5 +1,3 @@ -use std::sync::{Arc, RwLock}; - use mlua::{IntoLua, UserData, Value}; use self::{bar::SheetViewBarState, mode::Mode}; @@ -37,24 +35,19 @@ impl SheetViewState { } } - pub fn set_active_sheet(&mut self, sheet: Option) { - if let Some(id) = sheet { - if let Some(lock) = Register::get(id) { - let sheet = lock.read().unwrap(); + pub fn set_active_sheet(&mut self, active: Option) { + if let Some(id) = active { + if let Some(sheet) = Register::get(id) { self.cursor.set_x_max(sheet.width() - 1); self.cursor.set_y_max(sheet.height() - 1); } } - self.active_sheet = sheet + self.active_sheet = active } - pub fn active_sheet(&self) -> Option>> { - if let Some(id) = self.active_sheet { - Register::get(id) - } else { - None - } + pub fn active_sheet(&self) -> Option<&'static mut Sheet> { + Register::get(self.active_sheet?) } pub fn cancel_mode(&mut self) { @@ -121,13 +114,7 @@ impl SheetViewState { macro_rules! cfg { () => { - GlobalState::instance().view - }; -} - -macro_rules! cfg_mut { - () => { - GlobalState::instance_mut().view + GlobalState::get().view }; } @@ -143,9 +130,9 @@ impl UserData for SheetViewState { fields.add_field_function_set("active", |_, _, sheet: Option| { if let Some(r) = sheet { - cfg_mut!().active_sheet = Some(r.id()) + cfg!().active_sheet = Some(r.id()) } else { - cfg_mut!().active_sheet = None + cfg!().active_sheet = None } Ok(()) @@ -160,7 +147,7 @@ impl UserData for SheetViewState { fields.add_field_function_get("mode", |_, _| Ok(cfg!().mode)); fields.add_field_function_set("mode", |_, _, mode: Mode| { - let this = &mut cfg_mut!(); + let this = &mut cfg!(); match mode { Mode::Visual => match this.mode { Mode::Visual => {} @@ -177,12 +164,12 @@ impl UserData for SheetViewState { fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_function("move_cursor", |_, m: CursorMove| { - cfg_mut!().cursor.move_checked(m); + cfg!().cursor.move_checked(m); Ok(()) }); methods.add_function("cancel_mode", |_, _: ()| { - cfg_mut!().cancel_mode(); + cfg!().cancel_mode(); Ok(()) }) } diff --git a/src/widgets/luaeditor/mod.rs b/src/widgets/luaeditor/mod.rs index a24c6e7..d553734 100644 --- a/src/widgets/luaeditor/mod.rs +++ b/src/widgets/luaeditor/mod.rs @@ -38,12 +38,12 @@ impl LuaEditor { if populate { match event.code { - KeyCode::Char(c) => GlobalState::instance_mut().editor.buffer.insert(c), + KeyCode::Char(c) => GlobalState::get().editor.buffer.insert(c), KeyCode::Backspace => { - GlobalState::instance_mut().editor.buffer.delete(); + GlobalState::get().editor.buffer.delete(); } KeyCode::Enter => { - GlobalState::instance_mut().editor.buffer.insert('\n'); + GlobalState::get().editor.buffer.insert('\n'); } _ => {} } @@ -51,7 +51,7 @@ impl LuaEditor { } pub fn render_cursor(&self) -> Option { - let state = GlobalState::instance(); + let state = GlobalState::get(); let buffer = &state.editor.buffer; let nr_width = (buffer.lines().len().to_string().len() + 1).max(4) as u16; let x = buffer.cursor().x() @@ -73,10 +73,10 @@ impl Widget for &mut LuaEditor { Self: Sized, { { - let state = GlobalState::instance(); + let state = GlobalState::get(); let buffer = &state.editor.buffer; - let config = GlobalConfig::instance(); + let config = GlobalConfig::get(); let theme = &config.theme.editor; let inner_area = self.bar.area(area); diff --git a/src/widgets/sheetview/mod.rs b/src/widgets/sheetview/mod.rs index fe2aa5a..9b6b5bd 100644 --- a/src/widgets/sheetview/mod.rs +++ b/src/widgets/sheetview/mod.rs @@ -33,7 +33,7 @@ impl SheetView { } pub fn handle_key_event(&mut self, event: KeyEvent) { - let mode = { GlobalState::instance().view.mode }; + let mode = { GlobalState::get().view.mode }; match mode { Mode::Command => match event.code { KeyCode::Enter => { @@ -41,11 +41,11 @@ impl SheetView { // TODO: push errors to buffer } - GlobalState::instance_mut().view.cancel_mode(); + GlobalState::get().view.cancel_mode(); self.bar.set_input_mode(false); } KeyCode::Esc => { - GlobalState::instance_mut().view.cancel_mode(); + GlobalState::get().view.cancel_mode(); self.bar.set_input_mode(false); } _ => self.bar.handle_keyevent(event), @@ -53,7 +53,7 @@ impl SheetView { _ => { ViewKeyMap::handle(event); - let mode = { GlobalState::instance().view.mode }; + let mode = { GlobalState::get().view.mode }; if let Mode::Command = mode { self.bar.set_input_mode(true) } @@ -68,11 +68,10 @@ impl Widget for &mut SheetView { Self: Sized, { let mode = { - let theme = GlobalConfig::instance().theme.view.clone(); + let theme = GlobalConfig::get().theme.view.clone(); - let state = GlobalState::instance(); - let lock = state.view.active_sheet().unwrap(); - let sheet = lock.read().unwrap(); + let state = GlobalState::get(); + let sheet = state.view.active_sheet().unwrap(); let cursor = &state.view.cursor; let sheet_area_inner = self.bar.area(area); -- cgit v1.2.3-70-g09d2