summaryrefslogtreecommitdiff
path: root/src/sheet
diff options
context:
space:
mode:
Diffstat (limited to 'src/sheet')
-rw-r--r--src/sheet/eval.rs55
-rw-r--r--src/sheet/foreach.rs37
-rw-r--r--src/sheet/luaref.rs82
-rw-r--r--src/sheet/mod.rs65
-rw-r--r--src/sheet/register.rs2
5 files changed, 124 insertions, 117 deletions
diff --git a/src/sheet/eval.rs b/src/sheet/eval.rs
deleted file mode 100644
index 2108e48..0000000
--- a/src/sheet/eval.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use std::{
- sync::{Arc, RwLock},
- thread::JoinHandle,
-};
-
-use mlua::prelude::*;
-
-use crate::lua;
-
-use super::{cell::Cell, Sheet};
-
-pub trait EvalFunction {
- fn eval_function(
- &self,
- func: String,
- range: Vec<(usize, usize)>,
- ) -> JoinHandle<Result<Sheet, String>>;
-}
-
-impl EvalFunction for Arc<RwLock<Sheet>> {
- fn eval_function(
- &self,
- func_text: String,
- range: Vec<(usize, usize)>,
- ) -> JoinHandle<Result<Sheet, String>> {
- *self.read().unwrap().progress.lock().unwrap() = 0;
- let this = Arc::clone(self);
- std::thread::spawn(move || {
- let lua = lua::get();
- let read_sheet = this.read().unwrap();
- let mut sheet = read_sheet.clone();
- let result = lua.load(func_text).eval::<LuaFunction>();
-
- match result {
- Ok(func) => {
- let read_sheet = this.read().unwrap();
-
- for (i, (row, column)) in range.iter().enumerate() {
- *read_sheet.progress.lock().unwrap() = (i * 100 / range.len()) as u8;
-
- let cellref = read_sheet.get_ref(*row, *column);
-
- match func.call::<_, Cell>(cellref) {
- Ok(cell) => sheet.set_cell(*row, *column, cell),
- Err(error) => return Err(error.to_string()),
- }
- }
- }
- Err(error) => return Err(error.to_string()),
- }
-
- Ok(sheet)
- })
- }
-}
diff --git a/src/sheet/foreach.rs b/src/sheet/foreach.rs
new file mode 100644
index 0000000..a2a3f90
--- /dev/null
+++ b/src/sheet/foreach.rs
@@ -0,0 +1,37 @@
+use std::sync::{Arc, RwLock};
+
+use mlua::prelude::*;
+
+use super::{cell::Cell, Sheet};
+
+pub trait LuaForEach {
+ fn lua_foreach<'lua>(
+ &self,
+ func: LuaFunction<'lua>,
+ range: Vec<(usize, usize)>,
+ ) -> Result<(), LuaError>;
+}
+
+impl LuaForEach for Arc<RwLock<Sheet>> {
+ fn lua_foreach<'lua>(
+ &self,
+ func: LuaFunction<'lua>,
+ range: Vec<(usize, usize)>,
+ ) -> Result<(), LuaError> {
+ let mut this = self.write().unwrap();
+ let mut sheet = this.clone();
+
+ for (row, column) in range.iter() {
+ let cellref = this.get_ref(*row, *column);
+
+ match func.call::<_, Cell>(cellref) {
+ Ok(cell) => sheet.set_cell(*row, *column, cell),
+ Err(error) => return Err(error),
+ }
+ }
+
+ this.apply(sheet);
+
+ Ok(())
+ }
+}
diff --git a/src/sheet/luaref.rs b/src/sheet/luaref.rs
new file mode 100644
index 0000000..fa4b8f9
--- /dev/null
+++ b/src/sheet/luaref.rs
@@ -0,0 +1,82 @@
+use crate::state::GlobalState;
+
+use super::{
+ foreach::LuaForEach,
+ register::{Register, SheetId},
+};
+use mlua::prelude::*;
+
+pub struct SheetLuaRef {
+ id: SheetId,
+}
+
+impl SheetLuaRef {
+ pub fn new(id: SheetId) -> Self {
+ Self { id }
+ }
+
+ pub fn id(&self) -> SheetId {
+ self.id
+ }
+}
+
+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())
+ });
+
+ fields.add_field_method_get("height", |_, luaref| {
+ Ok(Register::get(luaref.id).unwrap().read().unwrap().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();
+ Ok(sheet.get_ref(row, column).into_lua(lua).unwrap())
+ } else {
+ Ok(LuaValue::Nil)
+ }
+ });
+
+ methods.add_method_mut("foreach", |_, luaref, func: LuaFunction| {
+ let range: Vec<_> = {
+ let state = GlobalState::instance();
+ let lock = state.sheetview.active_sheet().unwrap();
+ let sheet = lock.read().unwrap();
+
+ if sheet.id() != luaref.id() {
+ return Ok(());
+ }
+
+ let (width, height) = (sheet.width(), sheet.height());
+
+ if state.sheetview.selection_anchor.is_some() {
+ state.sheetview.selection()
+ } else {
+ let mut cells = Vec::new();
+ for row in 0..height {
+ for column in 0..width {
+ cells.push((row, column));
+ }
+ }
+ cells
+ }
+ };
+
+ Register::get(luaref.id).unwrap().lua_foreach(func, range)
+ })
+ }
+}
+
+impl<'lua> FromLua<'lua> for SheetLuaRef {
+ fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
+ if let Some(ud) = value.as_userdata() {
+ ud.take()
+ } else {
+ Err(LuaError::runtime("failed to parse sheet"))
+ }
+ }
+}
diff --git a/src/sheet/mod.rs b/src/sheet/mod.rs
index 501b71e..5f28e07 100644
--- a/src/sheet/mod.rs
+++ b/src/sheet/mod.rs
@@ -1,18 +1,14 @@
-use std::sync::Mutex;
-
use cell::{Cell, CellRef};
-use mlua::prelude::*;
-use register::{Register, SheetId};
pub mod cell;
-pub mod eval;
+pub mod foreach;
pub mod register;
+pub mod luaref;
#[derive(Debug, Default)]
pub struct Sheet {
id: register::SheetId,
rows: Vec<Vec<Cell>>,
- progress: Mutex<u8>,
}
impl Sheet {
@@ -20,7 +16,6 @@ impl Sheet {
Self {
id,
rows: vec![vec![Cell::new_empty(); width]; height],
- progress: Mutex::new(0),
}
}
@@ -41,9 +36,8 @@ impl Sheet {
}
pub fn get_ref(&self, row: usize, column: usize) -> Option<CellRef> {
- self.get_cell(row, column).map(|cell| {
- unsafe { CellRef::new(self.id, row, column, cell.clone()) }
- })
+ self.get_cell(row, column)
+ .map(|cell| unsafe { CellRef::new(self.id, row, column, cell.clone()) })
}
pub fn height(&self) -> usize {
@@ -74,10 +68,6 @@ impl Sheet {
pub fn apply(&mut self, other: Sheet) {
self.rows = other.rows;
}
-
- pub fn progress(&self) -> u8 {
- *self.progress.lock().unwrap()
- }
}
impl Clone for Sheet {
@@ -85,54 +75,7 @@ impl Clone for Sheet {
Sheet {
id: self.id,
rows: self.rows.clone(),
- progress: Mutex::new(0),
}
}
}
-pub struct SheetLuaRef {
- id: SheetId,
-}
-
-impl SheetLuaRef {
- pub fn new(id: SheetId) -> Self {
- Self { id }
- }
-
- pub fn id(&self) -> SheetId {
- self.id
- }
-}
-
-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())
- });
-
- fields.add_field_method_get("height", |_, luaref| {
- Ok(Register::get(luaref.id).unwrap().read().unwrap().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();
- Ok(sheet.get_ref(row, column).into_lua(lua).unwrap())
- } else {
- Ok(LuaValue::Nil)
- }
- })
- }
-}
-
-impl<'lua> FromLua<'lua> for SheetLuaRef {
- fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
- if let Some(ud) = value.as_userdata() {
- ud.take()
- } else {
- Err(LuaError::runtime("failed to parse sheet"))
- }
- }
-}
diff --git a/src/sheet/register.rs b/src/sheet/register.rs
index 039c6f0..c43720d 100644
--- a/src/sheet/register.rs
+++ b/src/sheet/register.rs
@@ -2,7 +2,7 @@ use std::sync::{Arc, RwLock};
use mlua::{Table, UserData, Value};
-use super::{cell::Cell, Sheet, SheetLuaRef};
+use super::{cell::Cell, Sheet, luaref::SheetLuaRef};
static REGISTER: RwLock<Vec<Arc<RwLock<Sheet>>>> = RwLock::new(Vec::new());