aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs75
1 files changed, 38 insertions, 37 deletions
diff --git a/src/main.rs b/src/main.rs
index bbd54b8..7521440 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,7 @@
+pub mod function_cache;
pub mod math;
+use function_cache::FunctionCache;
use iced::event;
use iced::executor;
use iced::mouse;
@@ -14,10 +16,9 @@ use iced::{
};
use math::context::Context;
use math::expression_function::ExpressionFunction;
-use math::function::Function;
+use std::sync::Mutex;
use crate::math::complex::Complex;
-use crate::math::function::FunctionArgument;
pub fn main() -> iced::Result {
Graph::run(Settings {
@@ -29,7 +30,7 @@ pub fn main() -> iced::Result {
#[derive(Default)]
struct Graph {
graph: Cache,
- func: ExpressionFunction,
+ func: Mutex<FunctionCache>,
ctx: Context,
input_state: String,
}
@@ -37,6 +38,7 @@ struct Graph {
#[derive(Debug, Clone)]
enum Message {
InputChanged(String),
+ UpdateFunction,
UpdateScreen,
}
@@ -48,10 +50,11 @@ impl Application for Graph {
fn new(_flags: ()) -> (Self, Command<Message>) {
let ctx = Context::commonsense();
+ let func = ExpressionFunction::from_string("f(x) = x^2".to_string(), ctx.operations());
(
Graph {
input_state: "f(x) = x^2".to_string(),
- func: ExpressionFunction::from_string("f(x) = x^2".to_string(), ctx.operations()),
+ func: Mutex::new(FunctionCache::new(func)),
ctx,
..Default::default()
},
@@ -68,8 +71,15 @@ impl Application for Graph {
Message::InputChanged(s) => {
self.input_state = s;
}
+ Message::UpdateFunction => {
+ let func = ExpressionFunction::from_string(
+ self.input_state.clone(),
+ self.ctx.operations(),
+ );
+ self.func = Mutex::new(FunctionCache::new(func));
+ self.graph.clear();
+ }
Message::UpdateScreen => {
- self.func = ExpressionFunction::from_string(self.input_state.clone(), self.ctx.operations());
self.graph.clear();
}
}
@@ -79,7 +89,7 @@ impl Application for Graph {
fn view(&self) -> Element<Message> {
let input = text_input("x", &self.input_state)
.on_input(Message::InputChanged)
- .on_submit(Message::UpdateScreen)
+ .on_submit(Message::UpdateFunction)
.padding(15)
.size(30);
let canvas = canvas(self as &Self)
@@ -118,7 +128,7 @@ impl Default for MouseState {
interaction: Interaction::default(),
center: Point::default(),
last_position: None,
- scale: 50.0
+ scale: 50.0,
}
}
}
@@ -169,12 +179,12 @@ impl canvas::Program<Message, Renderer> for Graph {
frame.with_save(|frame| {
let start_y = ((state.center.y - frame.height() / 2.0) / state.scale) as i64
* state.scale as i64;
- let start_x =
- ((state.center.x - frame.width() / 2.0) / state.scale) as i64 * state.scale as i64;
+ let start_x = ((state.center.x - frame.width() / 2.0) / state.scale) as i64
+ * state.scale as i64;
let end_y = ((state.center.y + frame.height() / 2.0) / state.scale) as i64
* state.scale as i64;
- let end_x =
- ((state.center.x + frame.width() / 2.0) / state.scale) as i64 * state.scale as i64;
+ let end_x = ((state.center.x + frame.width() / 2.0) / state.scale) as i64
+ * state.scale as i64;
for y in (start_y..end_y + state.scale as i64).step_by(1) {
let line = Path::line(
@@ -230,12 +240,10 @@ impl canvas::Program<Message, Renderer> for Graph {
frame.stroke(&line, zeroline.clone());
let mut y1 = self
.func
- .eval(
- &FunctionArgument::from_values(vec![Complex::new(start_x as f64, 0.0)]),
- &self.ctx,
- )
+ .lock()
.unwrap()
- .real as f32;
+ .eval(Complex::new(start_x as f64, 0.0), &self.ctx)
+ .real as f32;
for x in start_x..end_x {
for d in 0..10 {
let d = d as f32 / 10.0;
@@ -243,14 +251,13 @@ impl canvas::Program<Message, Renderer> for Graph {
let x2 = x as f32 + d + 0.1;
let y2 = self
.func
- .eval(
- &FunctionArgument::from_values(vec![Complex::new(x2 as f64, 0.0)]),
- &self.ctx,
- )
+ .lock()
.unwrap()
+ .eval(Complex::new(x2 as f64, 0.0), &self.ctx)
.real as f32;
if y1.is_finite() && !y1.is_nan() && y2.is_finite() && !y2.is_nan() {
- let line = Path::line(state.map_coords(x1, y1), state.map_coords(x2, y2));
+ let line =
+ Path::line(state.map_coords(x1, y1), state.map_coords(x2, y2));
frame.stroke(&line, graphline.clone())
}
y1 = y2;
@@ -263,12 +270,12 @@ impl canvas::Program<Message, Renderer> for Graph {
}
fn update(
- &self,
- state: &mut Self::State,
- event: canvas::Event,
- _bounds: Rectangle,
- cursor: iced::advanced::mouse::Cursor,
- ) -> (canvas::event::Status, Option<Message>) {
+ &self,
+ state: &mut Self::State,
+ event: canvas::Event,
+ _bounds: Rectangle,
+ cursor: iced::advanced::mouse::Cursor,
+ ) -> (canvas::event::Status, Option<Message>) {
if let canvas::Event::Mouse(mouse::Event::ButtonPressed(_)) = event {
state.interaction = Interaction::Grabbing;
state.last_position = cursor.position();
@@ -299,11 +306,9 @@ impl canvas::Program<Message, Renderer> for Graph {
state.scale *= 1.1;
}
state.scale = state.scale.max(0.000001);
- println!("SCALE: {}", state.scale);
- return (event::Status::Captured, Some(Message::UpdateScreen))
- },
- _ => {
+ return (event::Status::Captured, Some(Message::UpdateScreen));
}
+ _ => {}
}
}
(event::Status::Ignored, None)
@@ -316,12 +321,8 @@ impl canvas::Program<Message, Renderer> for Graph {
_cursor: mouse::Cursor,
) -> mouse::Interaction {
match state.interaction {
- Interaction::Grabbing => {
- mouse::Interaction::Grabbing
- },
- _ => {
- mouse::Interaction::Grab
- }
+ Interaction::Grabbing => mouse::Interaction::Grabbing,
+ _ => mouse::Interaction::Grab,
}
}
}