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:
parent
e67f97058b
commit
62208591fc
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -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"
|
||||
|
@ -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"] }
|
||||
|
@ -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"/>
|
||||
|
@ -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
2
src/routes/empty/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod page;
|
||||
pub use page::*;
|
12
src/routes/empty/page.rs
Normal file
12
src/routes/empty/page.rs
Normal 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>
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
pub mod whymdc;
|
||||
pub mod home;
|
||||
pub mod blog;
|
||||
pub mod empty;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user