Its alive! Refactoring to improve performance using pointers works, now performance still sucks because there is no spatial index and there are some math bugs that create nodes way too far from home

This commit is contained in:
jeangab 2023-08-10 10:55:08 -04:00
parent e67f97058b
commit 62208591fc
9 changed files with 74 additions and 45 deletions

24
Cargo.lock generated
View File

@ -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"

View File

@ -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"] }

View File

@ -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 {
<Route path="" view=|cx| view! { cx, <HomePage/> }/>
<Route path="/why-micro-datacenters" view=|cx| view! { cx, <WhyMicroDatacenters/> }/>
<Route path="/blog" view=|cx| view! { cx, <Blog/> }/>
<Route path="/background" view=|cx| view! { cx, <Empty/> }/>
</Routes>
</div>
<Background class="fixed h-screen w-screen top-0 z-0"/>

View File

@ -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::<dyn FnMut(_)>::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);

2
src/routes/empty/mod.rs Normal file
View File

@ -0,0 +1,2 @@
mod page;
pub use page::*;

12
src/routes/empty/page.rs Normal file
View File

@ -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,
<Title text="Pretty cool background | NationTech - Unconventional team for extraordinary challenges"/>
<div class="">
</div>
}
}

View File

@ -1,3 +1,4 @@
pub mod whymdc;
pub mod home;
pub mod blog;
pub mod empty;

View File

@ -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);

View File

@ -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);