code cleanup

This commit is contained in:
Simon Gardling 2022-04-05 09:14:35 -04:00
parent e427e7a04e
commit 6f1d64ea02
7 changed files with 56 additions and 72 deletions

View File

@ -53,7 +53,7 @@ fn generate_hashmap() {
.unwrap();
writeln!(&mut file, ";").unwrap();
write!(&mut file, "const MAX_FUNC_LEN: usize = {};", max_len).unwrap();
write!(&mut file, "const MAX_COMPLETION_LEN: usize = {};", max_len).unwrap();
}
include!(concat!(

View File

@ -20,10 +20,11 @@ pub const BUILD_INFO: &str = formatc!(
/// Range of acceptable input values for integral_num
pub const INTEGRAL_NUM_RANGE: RangeInclusive<usize> = 1..=50000;
/// Minimum X value for calculating an Integral
pub const INTEGRAL_X_MIN: f64 = -1000.0;
/// Maximum X value for calculating an Integral
/// Maximum X value for calculating an Integral
pub const INTEGRAL_X_MAX: f64 = 1000.0;
const_assert!(INTEGRAL_X_MAX > INTEGRAL_X_MIN);
@ -40,7 +41,6 @@ pub const DEFAULT_RIEMANN: Riemann = Riemann::Left;
pub const DEFAULT_MIN_X: f64 = -10.0;
/// Default Maxmimum X value to display
pub const DEFAULT_MAX_X: f64 = 10.0;
const_assert!(DEFAULT_MAX_X > DEFAULT_MIN_X);
@ -48,7 +48,10 @@ const_assert!(DEFAULT_MAX_X > DEFAULT_MIN_X);
/// Default number of integral boxes
pub const DEFAULT_INTEGRAL_NUM: usize = 100;
pub const COLORS: &'static [Color32; 14] = &[
/// Colors used for plotting
// Colors commented out are used elsewhere and are not included here for better
// user experience
pub const COLORS: &[Color32; 14] = &[
Color32::RED,
// Color32::GREEN,
// Color32::YELLOW,

View File

@ -90,14 +90,11 @@ impl Default for FunctionEntry {
impl FunctionEntry {
pub fn get_func_raw(&self) -> String { self.raw_func_str.to_string() }
pub fn auto_complete(
&mut self, ui: &mut egui::Ui, string: &mut String, i: i32,
) -> (bool, bool, Option<String>) {
let (output_string, in_focus) = self.autocomplete.ui(ui, string.to_string(), i);
pub fn auto_complete(&mut self, ui: &mut egui::Ui, i: i32) -> (bool, bool, Option<String>) {
let (output_string, in_focus) = self.autocomplete.ui(ui, self.raw_func_str.clone(), i);
let changed = output_string != *string;
let changed = output_string != self.raw_func_str;
if changed {
*string = output_string.clone();
self.update_string(&output_string);
}
@ -390,7 +387,8 @@ impl FunctionEntry {
}
// Plot integral data
if let Some(integral_data) = &self.integral_data {
match &self.integral_data {
Some(integral_data) => {
plot_ui.bar_chart(
BarChart::new(integral_data.0.clone())
.color(Color32::BLUE)
@ -399,8 +397,8 @@ impl FunctionEntry {
// return value rounded to 8 decimal places
Some(crate::misc::decimal_round(integral_data.1, 8))
} else {
None
}
_ => None,
}
}

View File

@ -276,6 +276,7 @@ impl Default for AppSettings {
}
}
/// Used to store the opened of windows/widgets
struct Opened {
pub help: bool,
pub info: bool,
@ -299,13 +300,9 @@ pub struct MathApp {
/// Stores vector of functions
functions: Vec<FunctionEntry>,
/// Stores vector containing the string representation of the functions.
/// This is used because of hacky reasons
func_strs: Vec<String>,
/// Stores last error from parsing functions (used to display the same error
/// when side panel is minimized)
func_errors: Vec<Option<(usize, String)>>,
func_errors: Vec<Option<String>>,
/// Stores whether or not an error is stored in `self.func_errors`
exists_error: bool,
@ -331,7 +328,6 @@ impl Default for MathApp {
fn default() -> Self {
Self {
functions: vec![DEFAULT_FUNCTION_ENTRY.clone()],
func_strs: vec![String::new()],
func_errors: vec![None],
exists_error: false,
last_info: (vec![None], Duration::ZERO),
@ -502,41 +498,24 @@ impl MathApp {
);
// Contains the function string in a text box that the user can edit
let (focused, changed, error) =
function.auto_complete(ui, &mut self.func_strs[i], i as i32);
let (focused, changed, error) = function.auto_complete(ui, i as i32);
if focused {
self.text_boxes_focused = true;
}
if error.is_some() {
if let Some(error_string) = error {
self.exists_error = true;
if changed {
self.func_errors[i] =
function.get_test_result().map(|error| (i, error));
self.func_errors[i] = Some(error_string);
}
}
});
// let func_failed = self.func_errors[i].is_some();
// if func_failed {
//
// }
// let update_result = function
// .update(&self.func_strs[i], integral_enabled,
// derivative_enabled) .map(|error| (i, error));
// if update_result.is_some() {
// self.exists_error = true;
// }
// self.func_errors[i] = update_result
}
// Remove function if the user requests it
if let Some(remove_i_unwrap) = remove_i {
self.functions.remove(remove_i_unwrap);
self.func_strs.remove(remove_i_unwrap);
self.func_errors.remove(remove_i_unwrap);
}
@ -593,12 +572,14 @@ impl epi::App for MathApp {
// Button to add a new function
if ui
.add_enabled(14 > self.func_strs.len(), Button::new("Add Function"))
.add_enabled(
COLORS.len() > self.functions.len(),
Button::new("Add Function"),
)
.on_hover_text("Create and graph new function")
.clicked()
{
self.functions.push(DEFAULT_FUNCTION_ENTRY.clone());
self.func_strs.push(String::new());
self.func_errors.push(None);
}
@ -713,10 +694,11 @@ impl epi::App for MathApp {
ui.centered_and_justified(|ui| {
self.func_errors
.iter()
.filter(|ele| ele.is_some())
.map(|ele| ele.as_ref().unwrap())
.for_each(|ele| {
ui.heading(format!("(Function #{}) {}\n", ele.0, ele.1));
.enumerate()
.filter(|(_, error)| error.is_some())
.map(|(i, error)| (i, error.as_ref().unwrap()))
.for_each(|(i, error)| {
ui.heading(format!("(Function #{}) {}\n", i, error));
})
});
return;

View File

@ -342,12 +342,18 @@ pub fn step_helper(max_i: usize, min_x: &f64, step: &f64) -> Vec<f64> {
(0..max_i).map(|x| (x as f64 * step) + min_x).collect()
}
pub fn chars_take(chars: &[char], i: usize) -> String {
if i > chars.len() {
panic!("chars_take: i is larget than chars.len()");
pub fn chars_take(chars: &[char], take: usize) -> String {
let len = chars.len();
assert!(len >= take);
if take == len {
// return `chars` turned into a string if `take == len`
return chars.iter().collect::<String>();
} else if take == 0 {
// return empty string if `take == 0`
return String::new();
}
chars.iter().rev().take(i).rev().collect::<String>()
chars.iter().rev().take(take).rev().collect::<String>()
}
#[cfg(test)]

View File

@ -6,7 +6,7 @@ pub fn generate_hint(input: &str) -> HintEnum<'static> {
return HintEnum::Single("x^2");
}
let chars: Vec<char> = input.chars().collect();
let chars: Vec<char> = input.chars().collect::<Vec<char>>();
let mut open_parens: usize = 0;
let mut closed_parens: usize = 0;
@ -22,8 +22,8 @@ pub fn generate_hint(input: &str) -> HintEnum<'static> {
let len = chars.len();
for i in (1..=MAX_FUNC_LEN).rev().filter(|i| len >= *i) {
if let Some(output) = get_completion(chars_take(&chars, i)) {
for i in (1..=MAX_COMPLETION_LEN).rev().filter(|i| len >= *i) {
if let Some(output) = get_completion(&chars_take(&chars, i)) {
return output;
}
}
@ -72,13 +72,6 @@ impl ToString for HintEnum<'static> {
}
impl HintEnum<'static> {
pub fn get_single(&self) -> Option<String> {
match self {
HintEnum::Single(x) => Some(x.to_string()),
_ => None,
}
}
pub fn is_some(&self) -> bool { !matches!(self, HintEnum::None) }
pub fn is_none(&self) -> bool { !self.is_some() }
@ -87,12 +80,14 @@ impl HintEnum<'static> {
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
/// Gets completion from `COMPLETION_HASHMAP`
pub fn get_completion(key: String) -> Option<HintEnum<'static>> {
pub fn get_completion(key: &str) -> Option<HintEnum<'static>> {
// If key is empty, just return None
if key.is_empty() {
return None;
}
COMPLETION_HASHMAP.get(&key).cloned()
// Get and clone the recieved data
COMPLETION_HASHMAP.get(key).cloned()
}
#[cfg(test)]

View File

@ -55,9 +55,9 @@ impl AutoComplete {
let enter_pressed = ui.input_mut().consume_key(Modifiers::NONE, Key::Enter);
let tab_pressed = ui.input_mut().consume_key(Modifiers::NONE, Key::Tab);
if let Some(single_hint) = self.hint.get_single() {
if let HintEnum::Single(single_hint) = self.hint {
let func_edit_2 = func_edit;
func_edit = func_edit_2.hint_text(&single_hint);
func_edit = func_edit_2.hint_text(single_hint);
}
let re = func_edit.id(te_id).ui(ui);
@ -71,7 +71,7 @@ impl AutoComplete {
let push_cursor: bool = match self.hint {
HintEnum::Single(hint) => {
if apply_key {
new_string = string + &hint;
new_string += hint;
true
} else {
false