Compare commits

..

No commits in common. "7f21e7e999c965c793491afe5e1a67cfe8cbc4ea" and "955220c0bc43256fe7e47b38f7f26ca2c6a77af8" have entirely different histories.

2 changed files with 71 additions and 82 deletions

View file

@ -4,7 +4,7 @@ use web_sys::{console, wasm_bindgen::JsValue};
use crate::{ use crate::{
engine, engine,
AppState, AppState,
assembly::{Assembly, Element, ProductRegulator} assembly::{Assembly, Element}
}; };
/* DEBUG */ /* DEBUG */
@ -189,9 +189,7 @@ pub fn AddRemove() -> View {
.try_into() .try_into()
.unwrap() .unwrap()
); );
state.assembly.insert_regulator( state.assembly.insert_new_product_regulator(subjects);
ProductRegulator::new(subjects, &state.assembly)
);
state.selection.update(|sel| sel.clear()); state.selection.update(|sel| sel.clear());
} }
) { "🔗" } ) { "🔗" }

View file

@ -58,8 +58,6 @@ pub struct Element {
} }
impl Element { impl Element {
const CURVATURE_COMPONENT: usize = 3;
pub fn new( pub fn new(
id: String, id: String,
label: String, label: String,
@ -147,8 +145,6 @@ pub trait Regulator: ProblemPoser + OutlineItem {
fn subjects(&self) -> Vec<ElementKey>; fn subjects(&self) -> Vec<ElementKey>;
fn measurement(&self) -> ReadSignal<f64>; fn measurement(&self) -> ReadSignal<f64>;
fn set_point(&self) -> Signal<SpecifiedValue>; fn set_point(&self) -> Signal<SpecifiedValue>;
fn activate(&self, _assembly: &Assembly) {}
} }
pub struct ProductRegulator { pub struct ProductRegulator {
@ -157,29 +153,6 @@ pub struct ProductRegulator {
pub set_point: Signal<SpecifiedValue> pub set_point: Signal<SpecifiedValue>
} }
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 { impl Regulator for ProductRegulator {
fn subjects(&self) -> Vec<ElementKey> { fn subjects(&self) -> Vec<ElementKey> {
self.subjects.into() self.subjects.into()
@ -217,24 +190,6 @@ pub struct HalfCurvatureRegulator {
pub set_point: Signal<SpecifiedValue> pub set_point: Signal<SpecifiedValue>
} }
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 { impl Regulator for HalfCurvatureRegulator {
fn subjects(&self) -> Vec<ElementKey> { fn subjects(&self) -> Vec<ElementKey> {
vec![self.subject] vec![self.subject]
@ -247,17 +202,6 @@ impl Regulator for HalfCurvatureRegulator {
fn set_point(&self) -> Signal<SpecifiedValue> { fn set_point(&self) -> Signal<SpecifiedValue> {
self.set_point 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 { impl ProblemPoser for HalfCurvatureRegulator {
@ -265,7 +209,8 @@ impl ProblemPoser for HalfCurvatureRegulator {
self.set_point.with_untracked(|set_pt| { self.set_point.with_untracked(|set_pt| {
if let Some(val) = set_pt.value { if let Some(val) = set_pt.value {
if let Some(col) = elts[self.subject].column_index { 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 { } else {
panic!("Tried to write problem data from a regulator with an unindexed subject"); 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)); self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
// regulate the sphere's curvature // regulate the sphere's curvature
self.insert_regulator(HalfCurvatureRegulator::new(key, &self)); self.insert_new_half_curvature_regulator(key);
key key
} }
@ -365,15 +310,11 @@ impl Assembly {
); );
} }
pub fn insert_regulator<T: Regulator + 'static>(&self, regulator: T) { fn insert_regulator(&self, regulator: Rc<dyn Regulator>) {
// add the regulator to the assembly's regulator list let subjects = regulator.subjects();
let regulator_rc = Rc::new(regulator);
let key = self.regulators.update( 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( 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
@ -383,19 +324,6 @@ impl Assembly {
regulators.update(|regs| regs.insert(key)); 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 */ /* 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:"));
@ -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 --- // --- realization ---
pub fn realize(&self) { pub fn realize(&self) {