diff options
Diffstat (limited to 'src/sheet')
| -rw-r--r-- | src/sheet/eval.rs | 147 |
1 files changed, 16 insertions, 131 deletions
diff --git a/src/sheet/eval.rs b/src/sheet/eval.rs index 4633949..2108e48 100644 --- a/src/sheet/eval.rs +++ b/src/sheet/eval.rs @@ -1,10 +1,12 @@ use std::{ - sync::{mpsc::channel, Arc, RwLock, RwLockReadGuard}, + sync::{Arc, RwLock}, thread::JoinHandle, }; use mlua::prelude::*; +use crate::lua; + use super::{cell::Cell, Sheet}; pub trait EvalFunction { @@ -24,147 +26,30 @@ impl EvalFunction for Arc<RwLock<Sheet>> { *self.read().unwrap().progress.lock().unwrap() = 0; let this = Arc::clone(self); std::thread::spawn(move || { - let chunks = range.chunks( - (range.len() / std::thread::available_parallelism().unwrap()) - .min(range.len()) - .max(1000), - ); - - if chunks.len() > 4 { - let (tx, rx) = channel(); - - std::thread::scope(|s| { - for chunk in chunks { - let tx = tx.clone(); - let this = Arc::clone(&this); - let func_text = func_text.clone(); - - s.spawn(move || { - let tx = tx.clone(); - let read_sheet = this.read().unwrap(); - let result = EvalRange::new(chunk.iter(), func_text, read_sheet); - match result { - Ok(evaluator) => { - for result in evaluator { - if result.is_err() { - tx.send(result).unwrap(); - break; - } - - tx.send(result).unwrap(); - } - } - Err(error) => tx.send(Err(error)).unwrap(), - } - }); - } - - drop(tx); + 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(); - let mut sheet = read_sheet.clone(); - let mut count = 0; + for (i, (row, column)) in range.iter().enumerate() { + *read_sheet.progress.lock().unwrap() = (i * 100 / range.len()) as u8; - for result in rx { - count += 1; - *read_sheet.progress.lock().unwrap() = (count * 100 / range.len()) as u8; + let cellref = read_sheet.get_ref(*row, *column); - match result { - Ok((row, column, cell)) => sheet.set_cell(row, column, cell), + match func.call::<_, Cell>(cellref) { + Ok(cell) => sheet.set_cell(*row, *column, cell), Err(error) => return Err(error.to_string()), } } - - crate::lua::new_instance().unwrap().expire_registry_values(); - Ok(sheet) - }) - } else { - let read_sheet = this.read().unwrap(); - let mut sheet = read_sheet.clone(); - let result = EvalRange::new((&range).iter(), func_text, read_sheet); - - match result { - Ok(evaluator) => { - for result in evaluator { - match result { - Ok((row, column, cell)) => sheet.set_cell(row, column, cell), - Err(error) => return Err(error.to_string()), - } - } - } - Err(error) => return Err(error), } - - crate::lua::new_instance().unwrap().expire_registry_values(); - - Ok(sheet) + Err(error) => return Err(error.to_string()), } - }) - } -} - -struct EvalRange<'a, I> -where - I: Iterator<Item = &'a (usize, usize)>, -{ - lua: Lua, - reg_func_key: LuaRegistryKey, - range: I, - read_sheet: RwLockReadGuard<'a, Sheet>, -} - -impl<'a, I> EvalRange<'a, I> -where - I: Iterator<Item = &'a (usize, usize)>, -{ - fn new( - range: I, - script: String, - read_sheet: RwLockReadGuard<'a, Sheet>, - ) -> Result<Self, String> { - let lua = crate::lua::new_instance().unwrap(); - let result = lua - .load(script.clone()) - .set_name("Temp Script") - .eval::<LuaFunction>(); - - if result.is_err() { - return Err(result.err().unwrap().to_string()); - } - let lua = crate::lua::new_instance().unwrap(); - let func = lua - .load(script) - .set_name("Temp Script") - .eval::<LuaFunction>() - .unwrap(); - - Ok(Self { - reg_func_key: lua.create_registry_value(func).unwrap(), - lua, - range, - read_sheet, + Ok(sheet) }) } } - -impl<'a, I> Iterator for EvalRange<'a, I> -where - I: Iterator<Item = &'a (usize, usize)>, -{ - type Item = Result<(usize, usize, Cell), String>; - - fn next(&mut self) -> Option<Self::Item> { - let func: LuaFunction = self.lua.registry_value(&self.reg_func_key).unwrap(); - if let Some((row, column)) = self.range.next() { - let cellref = self.read_sheet.get_ref(*row, *column); - match func.call::<_, Cell>(cellref) { - Ok(cell) => Some(Ok((*row, *column, cell))), - Err(error) => Some(Err(error.to_string())), - } - } else { - None - } - } -} |