forked from StudioInfinity/dyna3
Compare commits
No commits in common. "7f21e7e999c965c793491afe5e1a67cfe8cbc4ea" and "955220c0bc43256fe7e47b38f7f26ca2c6a77af8" have entirely different histories.
7f21e7e999
...
955220c0bc
2 changed files with 71 additions and 82 deletions
|
@ -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());
|
||||||
}
|
}
|
||||||
) { "🔗" }
|
) { "🔗" }
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue