summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-08-10 19:06:46 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2024-08-10 19:06:46 +0200
commit63cfcbe7a7745b276de58ec92e0141b958c44feb (patch)
tree990e33a83756e27187033579ee2f85d5c79169d5 /src
parentb747ca8af52129876b577a4f20f7105a05c6b002 (diff)
use unsafe blocks instead of mutexes
Diffstat (limited to 'src')
-rw-r--r--src/app.rs10
-rw-r--r--src/config/constants.rs23
-rw-r--r--src/config/env.rs22
-rw-r--r--src/config/keymap/template.rs8
-rw-r--r--src/config/mod.rs18
-rw-r--r--src/config/theme/bar.rs8
-rw-r--r--src/config/theme/editor/bar.rs3
-rw-r--r--src/config/theme/editor/mod.rs18
-rw-r--r--src/config/theme/view/bar.rs3
-rw-r--r--src/config/theme/view/mod.rs16
-rw-r--r--src/lua/mod.rs57
-rw-r--r--src/lua/runtime.rs8
-rw-r--r--src/sheet/cell.rs38
-rw-r--r--src/sheet/loader.rs19
-rw-r--r--src/sheet/luaref.rs53
-rw-r--r--src/sheet/map.rs15
-rw-r--r--src/sheet/register.rs31
-rw-r--r--src/sheet/tablized.rs3
-rw-r--r--src/state/bar.rs8
-rw-r--r--src/state/editor/bar.rs3
-rw-r--r--src/state/editor/mod.rs24
-rw-r--r--src/state/log.rs4
-rw-r--r--src/state/mod.rs18
-rw-r--r--src/state/view/bar.rs3
-rw-r--r--src/state/view/mod.rs37
-rw-r--r--src/widgets/luaeditor/mod.rs12
-rw-r--r--src/widgets/sheetview/mod.rs15
27 files changed, 189 insertions, 288 deletions
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<Rect>, Option<Rect>) {
- 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<String> = 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<String> = 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<GlobalConfig> = 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<Style, $type>| {
- $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<Style, $type>| {
- $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<Style, $type>| {
- $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<Style, ()>| {
- 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<Style, ()>| {
- 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<Style, ()>| {
- 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<Style, ()>| {
- 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<Style, CellRef>| {
- 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<Style, CellRef>| {
- 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<Style, CellRef>| {
- 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<Style, ()>| {
- 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<Lua> = {
- 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::<CellRef>(),
- 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<Lua> {
+ static mut LUA: Lazy<Lua> = 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::<Vec<&str>>()
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<Self> {
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<Self> {
@@ -157,16 +155,8 @@ impl CellRef {
}
pub fn end(&self) -> Option<Self> {
- 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<Self> {
@@ -174,16 +164,8 @@ impl CellRef {
}
pub fn bottom(&self) -> Option<Self> {
- 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<Loader> = Mutex::new(Loader::new());
-}
-
#[derive(Default)]
pub struct Loader {
loaders: HashMap<String, Box<dyn Runnable<String, Tablized>>>,
@@ -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<Loader> = 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<RwLock<Sheet>> {
+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<RwLock<Sheet>> {
}
}
- 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<Vec<Arc<RwLock<Sheet>>>> = RwLock::new(Vec::new());
+static mut REGISTER: Vec<Sheet> = 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<SheetId> {
- 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<Arc<RwLock<Sheet>>> {
- let register = REGISTER.read().unwrap();
-
- if id < register.len() {
- Some(Arc::clone(&register[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<String, $type>| {
- $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<String, $type>| {
- $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<String, $type>| {
- $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<GlobalState> = 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<SheetId>) {
- 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<SheetId>) {
+ 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<Arc<RwLock<Sheet>>> {
- 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<SheetLuaRef>| {
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<TuiCursor> {
- 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);