All checks were successful
/ test (push) Successful in 2m25s
Previously, dyna3 used storage keys to refer to elements, necessitating passing around element containers to various functions so that they could access the relevant elements. These storage keys have been replaced with reference-counted pointers, used for tasks like these: - Specifying the subjects of regulators. - Collecting the regulators each element is subject to - Handling selection. - Creating interface components. Also, systematizes the handling of serial numbers for entities, through a Serial trait. And updates to rust 1.86 and institutes explicit checking of the rust version. Co-authored-by: Aaron Fenyes <aaron.fenyes@fareycircles.ooo> Reviewed-on: #84 Co-authored-by: Vectornaut <vectornaut@nobody@nowhere.net> Co-committed-by: Vectornaut <vectornaut@nobody@nowhere.net>
257 lines
No EOL
8.5 KiB
Rust
257 lines
No EOL
8.5 KiB
Rust
use std::{f64::consts::FRAC_1_SQRT_2, rc::Rc};
|
|
use sycamore::prelude::*;
|
|
use web_sys::{console, wasm_bindgen::JsValue};
|
|
|
|
use crate::{
|
|
engine,
|
|
AppState,
|
|
assembly::{Assembly, InversiveDistanceRegulator, Point, Sphere}
|
|
};
|
|
|
|
/* DEBUG */
|
|
// load an example assembly for testing. this code will be removed once we've
|
|
// built a more formal test assembly system
|
|
fn load_gen_assemb(assembly: &Assembly) {
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
String::from("gemini_a"),
|
|
String::from("Castor"),
|
|
[1.00_f32, 0.25_f32, 0.00_f32],
|
|
engine::sphere(0.5, 0.5, 0.0, 1.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
String::from("gemini_b"),
|
|
String::from("Pollux"),
|
|
[0.00_f32, 0.25_f32, 1.00_f32],
|
|
engine::sphere(-0.5, -0.5, 0.0, 1.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
String::from("ursa_major"),
|
|
String::from("Ursa major"),
|
|
[0.25_f32, 0.00_f32, 1.00_f32],
|
|
engine::sphere(-0.5, 0.5, 0.0, 0.75)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
String::from("ursa_minor"),
|
|
String::from("Ursa minor"),
|
|
[0.25_f32, 1.00_f32, 0.00_f32],
|
|
engine::sphere(0.5, -0.5, 0.0, 0.5)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
String::from("moon_deimos"),
|
|
String::from("Deimos"),
|
|
[0.75_f32, 0.75_f32, 0.00_f32],
|
|
engine::sphere(0.0, 0.15, 1.0, 0.25)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
String::from("moon_phobos"),
|
|
String::from("Phobos"),
|
|
[0.00_f32, 0.75_f32, 0.50_f32],
|
|
engine::sphere(0.0, -0.15, -1.0, 0.25)
|
|
)
|
|
);
|
|
}
|
|
|
|
/* DEBUG */
|
|
// load an example assembly for testing. this code will be removed once we've
|
|
// built a more formal test assembly system
|
|
fn load_low_curv_assemb(assembly: &Assembly) {
|
|
let a = 0.75_f64.sqrt();
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
"central".to_string(),
|
|
"Central".to_string(),
|
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
|
engine::sphere(0.0, 0.0, 0.0, 1.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
"assemb_plane".to_string(),
|
|
"Assembly plane".to_string(),
|
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
|
engine::sphere_with_offset(0.0, 0.0, 1.0, 0.0, 0.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
"side1".to_string(),
|
|
"Side 1".to_string(),
|
|
[1.00_f32, 0.00_f32, 0.25_f32],
|
|
engine::sphere_with_offset(1.0, 0.0, 0.0, 1.0, 0.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
"side2".to_string(),
|
|
"Side 2".to_string(),
|
|
[0.25_f32, 1.00_f32, 0.00_f32],
|
|
engine::sphere_with_offset(-0.5, a, 0.0, 1.0, 0.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
"side3".to_string(),
|
|
"Side 3".to_string(),
|
|
[0.00_f32, 0.25_f32, 1.00_f32],
|
|
engine::sphere_with_offset(-0.5, -a, 0.0, 1.0, 0.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
"corner1".to_string(),
|
|
"Corner 1".to_string(),
|
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
|
engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
"corner2".to_string(),
|
|
"Corner 2".to_string(),
|
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
|
engine::sphere(2.0/3.0, -4.0/3.0 * a, 0.0, 1.0/3.0)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
String::from("corner3"),
|
|
String::from("Corner 3"),
|
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
|
engine::sphere(2.0/3.0, 4.0/3.0 * a, 0.0, 1.0/3.0)
|
|
)
|
|
);
|
|
}
|
|
|
|
fn load_pointed_assemb(assembly: &Assembly) {
|
|
let _ = assembly.try_insert_element(
|
|
Point::new(
|
|
format!("point_front"),
|
|
format!("Front point"),
|
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
|
engine::point(0.0, 0.0, FRAC_1_SQRT_2)
|
|
)
|
|
);
|
|
let _ = assembly.try_insert_element(
|
|
Point::new(
|
|
format!("point_back"),
|
|
format!("Back point"),
|
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
|
engine::point(0.0, 0.0, -FRAC_1_SQRT_2)
|
|
)
|
|
);
|
|
for index_x in 0..=1 {
|
|
for index_y in 0..=1 {
|
|
let x = index_x as f64 - 0.5;
|
|
let y = index_y as f64 - 0.5;
|
|
|
|
let _ = assembly.try_insert_element(
|
|
Sphere::new(
|
|
format!("sphere{index_x}{index_y}"),
|
|
format!("Sphere {index_x}{index_y}"),
|
|
[0.5*(1.0 + x) as f32, 0.5*(1.0 + y) as f32, 0.5*(1.0 - x*y) as f32],
|
|
engine::sphere(x, y, 0.0, 1.0)
|
|
)
|
|
);
|
|
|
|
let _ = assembly.try_insert_element(
|
|
Point::new(
|
|
format!("point{index_x}{index_y}"),
|
|
format!("Point {index_x}{index_y}"),
|
|
[0.5*(1.0 + x) as f32, 0.5*(1.0 + y) as f32, 0.5*(1.0 - x*y) as f32],
|
|
engine::point(x, y, 0.0)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
pub fn AddRemove() -> View {
|
|
/* DEBUG */
|
|
let assembly_name = create_signal("general".to_string());
|
|
create_effect(move || {
|
|
// get name of chosen assembly
|
|
let name = assembly_name.get_clone();
|
|
console::log_1(
|
|
&JsValue::from(format!("Showing assembly \"{}\"", name.clone()))
|
|
);
|
|
|
|
batch(|| {
|
|
let state = use_context::<AppState>();
|
|
let assembly = &state.assembly;
|
|
|
|
// clear state
|
|
assembly.regulators.update(|regs| regs.clear());
|
|
assembly.elements.update(|elts| elts.clear());
|
|
assembly.elements_by_id.update(|elts_by_id| elts_by_id.clear());
|
|
state.selection.update(|sel| sel.clear());
|
|
|
|
// load assembly
|
|
match name.as_str() {
|
|
"general" => load_gen_assemb(assembly),
|
|
"low-curv" => load_low_curv_assemb(assembly),
|
|
"pointed" => load_pointed_assemb(assembly),
|
|
_ => ()
|
|
};
|
|
});
|
|
});
|
|
|
|
view! {
|
|
div(id="add-remove") {
|
|
button(
|
|
on:click=|_| {
|
|
let state = use_context::<AppState>();
|
|
state.assembly.insert_element_default::<Sphere>();
|
|
}
|
|
) { "Add sphere" }
|
|
button(
|
|
on:click=|_| {
|
|
let state = use_context::<AppState>();
|
|
state.assembly.insert_element_default::<Point>();
|
|
}
|
|
) { "Add point" }
|
|
button(
|
|
class="emoji", /* KLUDGE */ // for convenience, we're using an emoji as a temporary icon for this button
|
|
disabled={
|
|
let state = use_context::<AppState>();
|
|
state.selection.with(|sel| sel.len() != 2)
|
|
},
|
|
on:click=|_| {
|
|
let state = use_context::<AppState>();
|
|
let subjects: [_; 2] = state.selection.with(
|
|
// the button is only enabled when two elements are
|
|
// selected, so we know the cast to a two-element array
|
|
// will succeed
|
|
|sel| sel
|
|
.clone()
|
|
.into_iter()
|
|
.collect::<Vec<_>>()
|
|
.try_into()
|
|
.unwrap()
|
|
);
|
|
state.assembly.insert_regulator(
|
|
Rc::new(InversiveDistanceRegulator::new(subjects))
|
|
);
|
|
state.selection.update(|sel| sel.clear());
|
|
}
|
|
) { "🔗" }
|
|
select(bind:value=assembly_name) { /* DEBUG */ // example assembly chooser
|
|
option(value="general") { "General" }
|
|
option(value="low-curv") { "Low-curvature" }
|
|
option(value="pointed") { "Pointed" }
|
|
option(value="empty") { "Empty" }
|
|
}
|
|
}
|
|
}
|
|
} |