diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-08-10 19:06:46 +0200 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-08-10 19:06:46 +0200 |
| commit | 63cfcbe7a7745b276de58ec92e0141b958c44feb (patch) | |
| tree | 990e33a83756e27187033579ee2f85d5c79169d5 /src/sheet | |
| parent | b747ca8af52129876b577a4f20f7105a05c6b002 (diff) | |
use unsafe blocks instead of mutexes
Diffstat (limited to 'src/sheet')
| -rw-r--r-- | src/sheet/cell.rs | 38 | ||||
| -rw-r--r-- | src/sheet/loader.rs | 19 | ||||
| -rw-r--r-- | src/sheet/luaref.rs | 53 | ||||
| -rw-r--r-- | src/sheet/map.rs | 15 | ||||
| -rw-r--r-- | src/sheet/register.rs | 31 | ||||
| -rw-r--r-- | src/sheet/tablized.rs | 3 |
6 files changed, 60 insertions, 99 deletions
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(®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 { |