diff --git a/Cargo.lock b/Cargo.lock index 99cf8c3..53ebaae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2640,9 +2640,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2650,16 +2650,16 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -2677,9 +2677,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2687,22 +2687,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" diff --git a/Cargo.toml b/Cargo.toml index 4f95d55..c50aaa2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ leptos_actix = { version = "0.2", optional = true } leptos_router = { version = "0.2", default-features = false } log = "0.4" simple_logger = "4" -wasm-bindgen = "=0.2.84" +wasm-bindgen = "=0.2.87" js-sys = "0.3.51" rand = "0.8.5" getrandom = { version = "0.2", features = ["js"] } diff --git a/src/app.rs b/src/app.rs index 1569139..5a494ca 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2,6 +2,7 @@ use crate::components::BackgroundProps; use crate::components::Background; use crate::routes::whymdc::*; use crate::routes::home::*; +use crate::routes::empty::*; use crate::routes::blog::*; use leptos::*; use leptos_meta::*; @@ -35,6 +36,7 @@ pub fn App(cx: Scope) -> impl IntoView { }/> }/> }/> + }/> diff --git a/src/components/background.rs b/src/components/background.rs index 35c171b..a1f8acd 100644 --- a/src/components/background.rs +++ b/src/components/background.rs @@ -1,5 +1,9 @@ +use std::cell::RefCell; +use std::rc::Rc; + use leptos::html::Canvas; use leptos::*; +use wasm_bindgen::prelude::Closure; use wasm_bindgen::JsCast; use wasm_bindgen::JsValue; use web_sys::window; @@ -17,11 +21,16 @@ pub fn Background(cx: Scope, class: &'static str) -> impl IntoView { let canvas_parent = canvas.parent_element().unwrap(); let width = canvas_parent.client_width(); let height = canvas_parent.client_height(); - canvas.set_width(u32::try_from(width).unwrap()); - canvas.set_height(u32::try_from(height).unwrap()); + let window_width = u32::try_from(width).unwrap(); + let window_height = u32::try_from(height).unwrap(); + canvas.set_width(window_width); + canvas.set_height(window_height); let mut sc = SpaceColonization::new(width.try_into().unwrap(), height.try_into().unwrap()); - let mut nodes = Vec::new(); - nodes.push(Node::new(Point::new((100, 100)))); + let nodes = Rc::new(RefCell::new(Vec::new())); + nodes.borrow_mut().push(Node::new(Point::new(( + (window_width / 2) as i32, + (window_height / 2) as i32, + )))); // TODO Resize on window resize log!( "TODO resize on window resize canvas parent size = {} {}", @@ -47,7 +56,7 @@ pub fn Background(cx: Scope, class: &'static str) -> impl IntoView { context.line_to(child.position.x.into(), child.position.y.into()); }; let render_id = window().unwrap().performance().unwrap().now(); - sc.render_nodes(&nodes, render_id, render_node_fn); + sc.render_nodes(&nodes.borrow(), render_id, render_node_fn); context.stroke(); context.set_fill_style(&JsValue::from("magenta")); @@ -60,14 +69,29 @@ pub fn Background(cx: Scope, class: &'static str) -> impl IntoView { sc.attractors.len(), end_time - start_time ); - - for _i in 1..150 { - nodes = sc.grow(nodes); + let context = context.clone(); + let closure = Closure::::new(move |_: web_sys::MouseEvent| { + let start_time = window().unwrap().performance().unwrap().now(); + let render_node_fn = |n: &Node, child: &Node| { + context.move_to(n.position.x.into(), n.position.y.into()); + context.line_to(child.position.x.into(), child.position.y.into()); + }; + sc.grow(&mut nodes.borrow_mut()); let render_id = window().unwrap().performance().unwrap().now(); context.begin_path(); - sc.render_nodes(&nodes, render_id, render_node_fn); + sc.render_nodes(&nodes.borrow(), render_id, render_node_fn); context.stroke(); - } + let end_time = window().unwrap().performance().unwrap().now(); + log!( + "Rendering nodes and {} attractors took {}", + sc.attractors.len(), + end_time - start_time + ); + }); + + let window = window().unwrap(); + window.add_event_listener_with_callback("click", closure.as_ref().unchecked_ref()).unwrap(); + closure.forget(); }); let class = format!("canvas {}", class); diff --git a/src/routes/empty/mod.rs b/src/routes/empty/mod.rs new file mode 100644 index 0000000..f5f67f8 --- /dev/null +++ b/src/routes/empty/mod.rs @@ -0,0 +1,2 @@ +mod page; +pub use page::*; diff --git a/src/routes/empty/page.rs b/src/routes/empty/page.rs new file mode 100644 index 0000000..39dc4bd --- /dev/null +++ b/src/routes/empty/page.rs @@ -0,0 +1,12 @@ +use leptos::*; +use leptos_meta::*; + +/// Renders the home page of your application. +#[component] +pub fn Empty(cx: Scope) -> impl IntoView { + view! { cx, + + <div class=""> + </div> + } +} diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 1bfe892..22d4b35 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,3 +1,4 @@ pub mod whymdc; pub mod home; pub mod blog; +pub mod empty; diff --git a/src/space_colonization/mod.rs b/src/space_colonization/mod.rs index dbce4f0..b10e132 100644 --- a/src/space_colonization/mod.rs +++ b/src/space_colonization/mod.rs @@ -19,9 +19,9 @@ pub struct Attractor { } impl Attractor { - pub fn new(position: (i32, i32)) -> Attractor { + pub fn new(position: Point) -> Attractor { Attractor { - position: Point::new(position), + position, dead: false, } } @@ -55,16 +55,6 @@ impl Attraction { } } -#[derive(Debug)] -pub struct NodeRef { - path: Vec<u16>, -} - -#[derive(Debug)] -pub struct AttractorRef { - path: Vec<u16>, -} - impl std::hash::Hash for Node { fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.position.hash(state); diff --git a/src/space_colonization/space_colonization.rs b/src/space_colonization/space_colonization.rs index 0b9fcae..5a776ed 100644 --- a/src/space_colonization/space_colonization.rs +++ b/src/space_colonization/space_colonization.rs @@ -95,10 +95,9 @@ impl SpaceColonization { let mut y_pos = 0; while x_pos < self.max_point.x { while y_pos < self.max_point.y { - self.attractors.push(Attractor { - position: self.get_random_point(x_pos.into(), y_pos.into()), - dead: false, - }); + self.attractors.push(Attractor::new( + self.get_random_point(x_pos.into(), y_pos.into()), + )); y_pos += self.density; } x_pos += self.density; @@ -130,7 +129,7 @@ impl SpaceColonization { } } - pub fn grow(&mut self, mut nodes: Vec<Node>) -> Vec<Node> { + pub fn grow<'a>(&mut self, mut nodes: &'a mut Vec<Node>) { // TODO // [x] Find a clean API that will be stable across refactoring // [ ] Write the test against this api including performance @@ -140,8 +139,7 @@ impl SpaceColonization { // - I can efficiently render my nodes on a canvas // - I use as little memory as possible // - I can update my nodes - self.grow_nodes(&mut nodes); - nodes + self.grow_nodes(&mut nodes) } pub fn grow_nodes(&mut self, nodes: &mut Vec<Node>) { @@ -287,7 +285,7 @@ mod test { let mut nodes = Vec::new(); nodes.push(Node::new(Point::new((0, 0)))); let mut attractors = Vec::new(); - attractors.push(Attractor::new((10, 0))); + attractors.push(Attractor::new(Point::new((10, 0)))); let mut sc = SpaceColonization::new_for_tests(100, 100, attractors); @@ -296,13 +294,13 @@ mod test { println!("before grow"); dbg!(&nodes); - nodes = sc.grow(nodes); + sc.grow(&mut nodes); println!("after grow 1"); dbg!(&nodes); assert!(sc.attractors.iter().find(|a| a.dead == true).is_none()); - nodes = sc.grow(nodes); + sc.grow(&mut nodes); println!("after grow 2"); dbg!(&nodes);