forked from StudioInfinity/dyna3

Make a regulator's set point specification private, and split the set point into a private writable signal and a public read-only signal. The set point can now be initialized only through the factory method `insert_new_regulator` and changed only through the setter method `try_specify_set_point`, which both ensure that the set point specification is valid and consistent with the set point.
211 lines
No EOL
6.8 KiB
Rust
211 lines
No EOL
6.8 KiB
Rust
use sycamore::prelude::*;
|
|
use web_sys::{console, wasm_bindgen::JsValue};
|
|
|
|
use crate::{
|
|
engine,
|
|
AppState,
|
|
assembly::{
|
|
Assembly,
|
|
Element
|
|
}
|
|
};
|
|
|
|
/* 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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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(
|
|
Element::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)
|
|
)
|
|
);
|
|
}
|
|
|
|
#[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.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),
|
|
_ => ()
|
|
};
|
|
});
|
|
});
|
|
|
|
view! {
|
|
div(id="add-remove") {
|
|
button(
|
|
on:click=|_| {
|
|
let state = use_context::<AppState>();
|
|
state.assembly.insert_new_element();
|
|
|
|
/* DEBUG */
|
|
// print updated list of elements by identifier
|
|
console::log_1(&JsValue::from("elements by identifier:"));
|
|
for (id, key) in state.assembly.elements_by_id.get_clone().iter() {
|
|
console::log_3(
|
|
&JsValue::from(" "),
|
|
&JsValue::from(id),
|
|
&JsValue::from(*key)
|
|
);
|
|
}
|
|
}
|
|
) { "+" }
|
|
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 = state.selection.with(
|
|
|sel| {
|
|
let subject_vec: Vec<_> = sel.into_iter().collect();
|
|
(subject_vec[0].clone(), subject_vec[1].clone())
|
|
}
|
|
);
|
|
state.assembly.insert_new_regulator(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="empty") { "Empty" }
|
|
}
|
|
}
|
|
}
|
|
} |