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>; } impl EvalFunction for Arc> { fn eval_function( &self, func_text: String, range: Vec<(usize, usize)>, ) -> JoinHandle> { *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::(); 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) }) } }