summaryrefslogtreecommitdiff
path: root/src/sheet
diff options
context:
space:
mode:
Diffstat (limited to 'src/sheet')
-rw-r--r--src/sheet/eval.rs147
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
- }
- }
-}