forked from StudioInfinity/dyna3
Give every sphere a curvature regulator
In the process, fix a reactivity bug by removing unintended signal tracking from `insert_regulator`.
This commit is contained in:
parent
63e3d733ba
commit
81e423fcbe
2 changed files with 34 additions and 30 deletions
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
// load an example assembly for testing. this code will be removed once we've
|
// load an example assembly for testing. this code will be removed once we've
|
||||||
// built a more formal test assembly system
|
// built a more formal test assembly system
|
||||||
fn load_gen_assemb(assembly: &Assembly) {
|
fn load_gen_assemb(assembly: &Assembly) {
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
String::from("gemini_a"),
|
String::from("gemini_a"),
|
||||||
String::from("Castor"),
|
String::from("Castor"),
|
||||||
|
@ -19,7 +19,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(0.5, 0.5, 0.0, 1.0)
|
engine::sphere(0.5, 0.5, 0.0, 1.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
String::from("gemini_b"),
|
String::from("gemini_b"),
|
||||||
String::from("Pollux"),
|
String::from("Pollux"),
|
||||||
|
@ -27,7 +27,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(-0.5, -0.5, 0.0, 1.0)
|
engine::sphere(-0.5, -0.5, 0.0, 1.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
String::from("ursa_major"),
|
String::from("ursa_major"),
|
||||||
String::from("Ursa major"),
|
String::from("Ursa major"),
|
||||||
|
@ -35,7 +35,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(-0.5, 0.5, 0.0, 0.75)
|
engine::sphere(-0.5, 0.5, 0.0, 0.75)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
String::from("ursa_minor"),
|
String::from("ursa_minor"),
|
||||||
String::from("Ursa minor"),
|
String::from("Ursa minor"),
|
||||||
|
@ -43,7 +43,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(0.5, -0.5, 0.0, 0.5)
|
engine::sphere(0.5, -0.5, 0.0, 0.5)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
String::from("moon_deimos"),
|
String::from("moon_deimos"),
|
||||||
String::from("Deimos"),
|
String::from("Deimos"),
|
||||||
|
@ -51,7 +51,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(0.0, 0.15, 1.0, 0.25)
|
engine::sphere(0.0, 0.15, 1.0, 0.25)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
String::from("moon_phobos"),
|
String::from("moon_phobos"),
|
||||||
String::from("Phobos"),
|
String::from("Phobos"),
|
||||||
|
@ -66,7 +66,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
// built a more formal test assembly system
|
// built a more formal test assembly system
|
||||||
fn load_low_curv_assemb(assembly: &Assembly) {
|
fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
let a = 0.75_f64.sqrt();
|
let a = 0.75_f64.sqrt();
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
"central".to_string(),
|
"central".to_string(),
|
||||||
"Central".to_string(),
|
"Central".to_string(),
|
||||||
|
@ -74,7 +74,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(0.0, 0.0, 0.0, 1.0)
|
engine::sphere(0.0, 0.0, 0.0, 1.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
"assemb_plane".to_string(),
|
"assemb_plane".to_string(),
|
||||||
"Assembly plane".to_string(),
|
"Assembly plane".to_string(),
|
||||||
|
@ -82,7 +82,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere_with_offset(0.0, 0.0, 1.0, 0.0, 0.0)
|
engine::sphere_with_offset(0.0, 0.0, 1.0, 0.0, 0.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
"side1".to_string(),
|
"side1".to_string(),
|
||||||
"Side 1".to_string(),
|
"Side 1".to_string(),
|
||||||
|
@ -90,7 +90,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere_with_offset(1.0, 0.0, 0.0, 1.0, 0.0)
|
engine::sphere_with_offset(1.0, 0.0, 0.0, 1.0, 0.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
"side2".to_string(),
|
"side2".to_string(),
|
||||||
"Side 2".to_string(),
|
"Side 2".to_string(),
|
||||||
|
@ -98,7 +98,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere_with_offset(-0.5, a, 0.0, 1.0, 0.0)
|
engine::sphere_with_offset(-0.5, a, 0.0, 1.0, 0.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
"side3".to_string(),
|
"side3".to_string(),
|
||||||
"Side 3".to_string(),
|
"Side 3".to_string(),
|
||||||
|
@ -106,7 +106,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere_with_offset(-0.5, -a, 0.0, 1.0, 0.0)
|
engine::sphere_with_offset(-0.5, -a, 0.0, 1.0, 0.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
"corner1".to_string(),
|
"corner1".to_string(),
|
||||||
"Corner 1".to_string(),
|
"Corner 1".to_string(),
|
||||||
|
@ -114,7 +114,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0)
|
engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
"corner2".to_string(),
|
"corner2".to_string(),
|
||||||
"Corner 2".to_string(),
|
"Corner 2".to_string(),
|
||||||
|
@ -122,7 +122,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
engine::sphere(2.0/3.0, -4.0/3.0 * a, 0.0, 1.0/3.0)
|
engine::sphere(2.0/3.0, -4.0/3.0 * a, 0.0, 1.0/3.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_element(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Element::new(
|
||||||
String::from("corner3"),
|
String::from("corner3"),
|
||||||
String::from("Corner 3"),
|
String::from("Corner 3"),
|
||||||
|
|
|
@ -261,28 +261,33 @@ impl Assembly {
|
||||||
|
|
||||||
// --- inserting elements and regulators ---
|
// --- inserting elements and regulators ---
|
||||||
|
|
||||||
// insert an element into the assembly without checking whether we already
|
// insert a sphere into the assembly without checking whether we already
|
||||||
// have an element with the same identifier. any element that does have the
|
// have an element with the same identifier. any element that does have the
|
||||||
// same identifier will get kicked out of the `elements_by_id` index
|
// same identifier will get kicked out of the `elements_by_id` index
|
||||||
fn insert_element_unchecked(&self, elt: Element) -> ElementKey {
|
fn insert_sphere_unchecked(&self, elt: Element) -> ElementKey {
|
||||||
|
// insert the sphere
|
||||||
let id = elt.id.clone();
|
let id = elt.id.clone();
|
||||||
let key = self.elements.update(|elts| elts.insert(elt));
|
let key = self.elements.update(|elts| elts.insert(elt));
|
||||||
self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
|
self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
|
||||||
|
|
||||||
|
// regulate the sphere's curvature
|
||||||
|
self.insert_new_half_curvature_regulator(key);
|
||||||
|
|
||||||
key
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_insert_element(&self, elt: Element) -> Option<ElementKey> {
|
pub fn try_insert_sphere(&self, elt: Element) -> Option<ElementKey> {
|
||||||
let can_insert = self.elements_by_id.with_untracked(
|
let can_insert = self.elements_by_id.with_untracked(
|
||||||
|elts_by_id| !elts_by_id.contains_key(&elt.id)
|
|elts_by_id| !elts_by_id.contains_key(&elt.id)
|
||||||
);
|
);
|
||||||
if can_insert {
|
if can_insert {
|
||||||
Some(self.insert_element_unchecked(elt))
|
Some(self.insert_sphere_unchecked(elt))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_new_sphere(self) {
|
pub fn insert_new_sphere(&self) {
|
||||||
// find the next unused identifier in the default sequence
|
// find the next unused identifier in the default sequence
|
||||||
let mut id_num = 1;
|
let mut id_num = 1;
|
||||||
let mut id = format!("sphere{}", id_num);
|
let mut id = format!("sphere{}", id_num);
|
||||||
|
@ -294,7 +299,7 @@ impl Assembly {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create and insert a sphere
|
// create and insert a sphere
|
||||||
let key = self.insert_element_unchecked(
|
let _ = self.insert_sphere_unchecked(
|
||||||
Element::new(
|
Element::new(
|
||||||
id,
|
id,
|
||||||
format!("Sphere {}", id_num),
|
format!("Sphere {}", id_num),
|
||||||
|
@ -302,9 +307,6 @@ impl Assembly {
|
||||||
sphere(0.0, 0.0, 0.0, 1.0)
|
sphere(0.0, 0.0, 0.0, 1.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// create and insert a curvature regulator
|
|
||||||
self.insert_new_half_curvature_regulator(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_regulator(&self, regulator: Rc<dyn Regulator>) {
|
fn insert_regulator(&self, regulator: Rc<dyn Regulator>) {
|
||||||
|
@ -312,7 +314,7 @@ impl Assembly {
|
||||||
let key = self.regulators.update(
|
let key = self.regulators.update(
|
||||||
|regs| regs.insert(regulator)
|
|regs| regs.insert(regulator)
|
||||||
);
|
);
|
||||||
let subject_regulators: Vec<_> = self.elements.with(
|
let subject_regulators: Vec<_> = self.elements.with_untracked(
|
||||||
|elts| subjects.into_iter().map(
|
|elts| subjects.into_iter().map(
|
||||||
|subj| elts[subj].regulators
|
|subj| elts[subj].regulators
|
||||||
).collect()
|
).collect()
|
||||||
|
@ -324,7 +326,7 @@ impl Assembly {
|
||||||
/* DEBUG */
|
/* DEBUG */
|
||||||
// print an updated list of regulators
|
// print an updated list of regulators
|
||||||
console::log_1(&JsValue::from("Regulators:"));
|
console::log_1(&JsValue::from("Regulators:"));
|
||||||
self.regulators.with(|regs| {
|
self.regulators.with_untracked(|regs| {
|
||||||
for (_, reg) in regs.into_iter() {
|
for (_, reg) in regs.into_iter() {
|
||||||
console::log_1(&JsValue::from(format!(
|
console::log_1(&JsValue::from(format!(
|
||||||
" {:?}: {}",
|
" {:?}: {}",
|
||||||
|
@ -344,7 +346,7 @@ impl Assembly {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_new_product_regulator(self, subjects: [ElementKey; 2]) {
|
pub fn insert_new_product_regulator(&self, subjects: [ElementKey; 2]) {
|
||||||
// create and insert a new product regulator
|
// create and insert a new product regulator
|
||||||
let measurement = self.elements.map(
|
let measurement = self.elements.map(
|
||||||
move |elts| {
|
move |elts| {
|
||||||
|
@ -365,17 +367,18 @@ impl Assembly {
|
||||||
|
|
||||||
// update the realization when the regulator becomes a constraint, or is
|
// update the realization when the regulator becomes a constraint, or is
|
||||||
// edited while acting as a constraint
|
// edited while acting as a constraint
|
||||||
|
let self_for_effect = self.clone();
|
||||||
create_effect(move || {
|
create_effect(move || {
|
||||||
console::log_1(&JsValue::from(
|
console::log_1(&JsValue::from(
|
||||||
format!("Updated regulator with subjects {:?}", subjects)
|
format!("Updated regulator with subjects {:?}", subjects)
|
||||||
));
|
));
|
||||||
if set_point.with(|set_pt| set_pt.is_present()) {
|
if set_point.with(|set_pt| set_pt.is_present()) {
|
||||||
self.realize();
|
self_for_effect.realize();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_new_half_curvature_regulator(self, subject: ElementKey) {
|
pub fn insert_new_half_curvature_regulator(&self, subject: ElementKey) {
|
||||||
// create and insert a new half-curvature regulator
|
// create and insert a new half-curvature regulator
|
||||||
let measurement = self.elements.map(
|
let measurement = self.elements.map(
|
||||||
move |elts| elts[subject].representation.with(|rep| rep[3])
|
move |elts| elts[subject].representation.with(|rep| rep[3])
|
||||||
|
@ -389,12 +392,13 @@ impl Assembly {
|
||||||
|
|
||||||
// update the realization when the regulator becomes a constraint, or is
|
// update the realization when the regulator becomes a constraint, or is
|
||||||
// edited while acting as a constraint
|
// edited while acting as a constraint
|
||||||
|
let self_for_effect = self.clone();
|
||||||
create_effect(move || {
|
create_effect(move || {
|
||||||
console::log_1(&JsValue::from(
|
console::log_1(&JsValue::from(
|
||||||
format!("Updated regulator with subjects [{}]", subject)
|
format!("Updated regulator with subjects [{}]", subject)
|
||||||
));
|
));
|
||||||
if let Some(half_curv) = set_point.with(|set_pt| set_pt.value) {
|
if let Some(half_curv) = set_point.with(|set_pt| set_pt.value) {
|
||||||
let representation = self.elements.with(
|
let representation = self_for_effect.elements.with_untracked(
|
||||||
|elts| elts[subject].representation
|
|elts| elts[subject].representation
|
||||||
);
|
);
|
||||||
representation.update(|rep| {
|
representation.update(|rep| {
|
||||||
|
@ -428,7 +432,7 @@ impl Assembly {
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
self.realize();
|
self_for_effect.realize();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue