diff --git a/app-proto/src/add_remove.rs b/app-proto/src/add_remove.rs index deac2bb..4972d3c 100644 --- a/app-proto/src/add_remove.rs +++ b/app-proto/src/add_remove.rs @@ -4,7 +4,7 @@ use web_sys::{console, wasm_bindgen::JsValue}; use crate::{ engine, AppState, - assembly::{Assembly, Element, ProductRegulator} + assembly::{Assembly, Element} }; /* DEBUG */ @@ -189,9 +189,7 @@ pub fn AddRemove() -> View { .try_into() .unwrap() ); - state.assembly.insert_regulator( - ProductRegulator::new(subjects, &state.assembly) - ); + state.assembly.insert_new_product_regulator(subjects); state.selection.update(|sel| sel.clear()); } ) { "🔗" } diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index f14f0c4..055b9a2 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -58,8 +58,6 @@ pub struct Element { } impl Element { - const CURVATURE_COMPONENT: usize = 3; - pub fn new( id: String, label: String, @@ -147,8 +145,6 @@ pub trait Regulator: ProblemPoser + OutlineItem { fn subjects(&self) -> Vec; fn measurement(&self) -> ReadSignal; fn set_point(&self) -> Signal; - - fn activate(&self, _assembly: &Assembly) {} } pub struct ProductRegulator { @@ -157,29 +153,6 @@ pub struct ProductRegulator { pub set_point: Signal } -impl ProductRegulator { - pub fn new(subjects: [ElementKey; 2], assembly: &Assembly) -> ProductRegulator { - let measurement = assembly.elements.map( - move |elts| { - let representations = subjects.map(|subj| elts[subj].representation); - representations[0].with(|rep_0| - representations[1].with(|rep_1| - rep_0.dot(&(&*Q * rep_1)) - ) - ) - } - ); - - let set_point = create_signal(SpecifiedValue::from_empty_spec()); - - ProductRegulator { - subjects: subjects, - measurement: measurement, - set_point: set_point - } - } -} - impl Regulator for ProductRegulator { fn subjects(&self) -> Vec { self.subjects.into() @@ -217,24 +190,6 @@ pub struct HalfCurvatureRegulator { pub set_point: Signal } -impl HalfCurvatureRegulator { - pub fn new(subject: ElementKey, assembly: &Assembly) -> HalfCurvatureRegulator { - let measurement = assembly.elements.map( - move |elts| elts[subject].representation.with( - |rep| rep[Element::CURVATURE_COMPONENT] - ) - ); - - let set_point = create_signal(SpecifiedValue::from_empty_spec()); - - HalfCurvatureRegulator { - subject: subject, - measurement: measurement, - set_point: set_point - } - } -} - impl Regulator for HalfCurvatureRegulator { fn subjects(&self) -> Vec { vec![self.subject] @@ -247,17 +202,6 @@ impl Regulator for HalfCurvatureRegulator { fn set_point(&self) -> Signal { self.set_point } - - fn activate(&self, assembly: &Assembly) { - if let Some(half_curv) = self.set_point.with_untracked(|set_pt| set_pt.value) { - let representation = assembly.elements.with_untracked( - |elts| elts[self.subject].representation - ); - representation.update( - |rep| change_half_curvature(rep, half_curv) - ); - } - } } impl ProblemPoser for HalfCurvatureRegulator { @@ -265,7 +209,8 @@ impl ProblemPoser for HalfCurvatureRegulator { self.set_point.with_untracked(|set_pt| { if let Some(val) = set_pt.value { if let Some(col) = elts[self.subject].column_index { - problem.frozen.push(Element::CURVATURE_COMPONENT, col, val); + const CURVATURE_COMPONENT: usize = 3; + problem.frozen.push(CURVATURE_COMPONENT, col, val); } else { panic!("Tried to write problem data from a regulator with an unindexed subject"); } @@ -327,7 +272,7 @@ impl Assembly { self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key)); // regulate the sphere's curvature - self.insert_regulator(HalfCurvatureRegulator::new(key, &self)); + self.insert_new_half_curvature_regulator(key); key } @@ -365,15 +310,11 @@ impl Assembly { ); } - pub fn insert_regulator(&self, regulator: T) { - // add the regulator to the assembly's regulator list - let regulator_rc = Rc::new(regulator); + fn insert_regulator(&self, regulator: Rc) { + let subjects = regulator.subjects(); let key = self.regulators.update( - |regs| regs.insert(regulator_rc.clone()) + |regs| regs.insert(regulator) ); - - // add the regulator to each subject's regulator list - let subjects = regulator_rc.subjects(); let subject_regulators: Vec<_> = self.elements.with_untracked( |elts| subjects.into_iter().map( |subj| elts[subj].regulators @@ -383,19 +324,6 @@ impl Assembly { regulators.update(|regs| regs.insert(key)); } - // update the realization when the regulator becomes a constraint, or is - // edited while acting as a constraint - let self_for_effect = self.clone(); - create_effect(move || { - console::log_1(&JsValue::from( - format!("Updated regulator with subjects {:?}", regulator_rc.subjects()) - )); - if regulator_rc.set_point().with(|set_pt| set_pt.is_present()) { - regulator_rc.activate(&self_for_effect); - self_for_effect.realize(); - } - }); - /* DEBUG */ // print an updated list of regulators console::log_1(&JsValue::from("Regulators:")); @@ -419,6 +347,69 @@ impl Assembly { }); } + pub fn insert_new_product_regulator(&self, subjects: [ElementKey; 2]) { + // create and insert a new product regulator + let measurement = self.elements.map( + move |elts| { + let representations = subjects.map(|subj| elts[subj].representation); + representations[0].with(|rep_0| + representations[1].with(|rep_1| + rep_0.dot(&(&*Q * rep_1)) + ) + ) + } + ); + let set_point = create_signal(SpecifiedValue::from_empty_spec()); + self.insert_regulator(Rc::new(ProductRegulator { + subjects: subjects, + measurement: measurement, + set_point: set_point + })); + + // update the realization when the regulator becomes a constraint, or is + // edited while acting as a constraint + let self_for_effect = self.clone(); + create_effect(move || { + console::log_1(&JsValue::from( + format!("Updated regulator with subjects {:?}", subjects) + )); + if set_point.with(|set_pt| set_pt.is_present()) { + self_for_effect.realize(); + } + }); + } + + pub fn insert_new_half_curvature_regulator(&self, subject: ElementKey) { + // create and insert a new half-curvature regulator + let measurement = self.elements.map( + move |elts| elts[subject].representation.with(|rep| rep[3]) + ); + let set_point = create_signal(SpecifiedValue::from_empty_spec()); + self.insert_regulator(Rc::new(HalfCurvatureRegulator { + subject: subject, + measurement: measurement, + set_point: set_point + })); + + // update the realization when the regulator becomes a constraint, or is + // edited while acting as a constraint + let self_for_effect = self.clone(); + create_effect(move || { + console::log_1(&JsValue::from( + format!("Updated regulator with subjects [{}]", subject) + )); + if let Some(half_curv) = set_point.with(|set_pt| set_pt.value) { + let representation = self_for_effect.elements.with_untracked( + |elts| elts[subject].representation + ); + representation.update( + |rep| change_half_curvature(rep, half_curv) + ); + self_for_effect.realize(); + } + }); + } + // --- realization --- pub fn realize(&self) {