Store a product regulator's subjects in an array

This lets us iterate over subjects. Based on commit 257ce33, with a few
updates from 4a9e777.
This commit is contained in:
Aaron Fenyes 2025-03-26 23:50:40 -07:00
parent 677d770738
commit f1f87e97be
3 changed files with 35 additions and 38 deletions

View file

@ -188,11 +188,16 @@ pub fn AddRemove() -> View {
},
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())
}
let subjects: [_; 2] = state.selection.with(
// the button is only enabled when two elements are
// selected, so we know the cast to a two-element array
// will succeed
|sel| sel
.clone()
.into_iter()
.collect::<Vec<_>>()
.try_into()
.unwrap()
);
state.assembly.insert_new_regulator(subjects);
state.selection.update(|sel| sel.clear());

View file

@ -134,7 +134,7 @@ impl Element {
#[derive(Clone, Copy)]
pub struct ProductRegulator {
pub subjects: (ElementKey, ElementKey),
pub subjects: [ElementKey; 2],
pub measurement: ReadSignal<f64>,
pub set_point: Signal<SpecifiedValue>
}
@ -143,12 +143,10 @@ impl ProductRegulator {
fn write_to_problem(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
self.set_point.with_untracked(|set_pt| {
if let Some(val) = set_pt.value {
let subjects = self.subjects;
let subject_column_indices = (
elts[subjects.0].column_index,
elts[subjects.1].column_index
let subject_column_indices = self.subjects.map(
|subj| elts[subj].column_index
);
if let (Some(row), Some(col)) = subject_column_indices {
if let [Some(row), Some(col)] = subject_column_indices {
problem.gram.push_sym(row, col, val);
} else {
panic!("Tried to write problem data from a regulator with an unindexed subject");
@ -246,21 +244,23 @@ impl Assembly {
let subjects = regulator.subjects;
let key = self.regulators.update(|regs| regs.insert(regulator));
let subject_regulators = self.elements.with(
|elts| (elts[subjects.0].regulators, elts[subjects.1].regulators)
|elts| subjects.map(|subj| elts[subj].regulators)
);
subject_regulators.0.update(|regs| regs.insert(key));
subject_regulators.1.update(|regs| regs.insert(key));
for regulators in subject_regulators {
regulators.update(|regs| regs.insert(key));
}
}
pub fn insert_new_regulator(self, subjects: (ElementKey, ElementKey)) {
pub fn insert_new_regulator(self, subjects: [ElementKey; 2]) {
// create and insert a new regulator
let measurement = self.elements.map(
move |elts| {
let reps = (
elts[subjects.0].representation.get_clone(),
elts[subjects.1].representation.get_clone()
);
reps.0.dot(&(&*Q * reps.1))
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());
@ -277,8 +277,8 @@ impl Assembly {
for (_, reg) in regs.into_iter() {
console::log_5(
&JsValue::from(" "),
&JsValue::from(reg.subjects.0),
&JsValue::from(reg.subjects.1),
&JsValue::from(reg.subjects[0]),
&JsValue::from(reg.subjects[1]),
&JsValue::from(":"),
&reg.set_point.with_untracked(
|set_pt| JsValue::from(set_pt.spec.as_str())
@ -502,25 +502,17 @@ mod tests {
fn unindexed_subject_test() {
let _ = create_root(|| {
let mut elts = Slab::new();
let subjects = (
let subjects = [0, 1].map(|k| {
elts.insert(
Element::new(
"sphere0".to_string(),
"Sphere 0".to_string(),
[1.0_f32, 1.0_f32, 1.0_f32],
engine::sphere(0.0, 0.0, 0.0, 1.0)
)
),
elts.insert(
Element::new(
"sphere1".to_string(),
"Sphere 1".to_string(),
"sphere{k}".to_string(),
"Sphere {k}".to_string(),
[1.0_f32, 1.0_f32, 1.0_f32],
engine::sphere(0.0, 0.0, 0.0, 1.0)
)
)
);
elts[subjects.0].column_index = Some(0);
});
elts[subjects[0]].column_index = Some(0);
ProductRegulator {
subjects: subjects,
measurement: create_memo(|| 0.0),

View file

@ -81,10 +81,10 @@ fn RegulatorOutlineItem(regulator_key: RegulatorKey, element_key: ElementKey) ->
let state = use_context::<AppState>();
let assembly = &state.assembly;
let regulator = assembly.regulators.with(|regs| regs[regulator_key]);
let other_subject = if regulator.subjects.0 == element_key {
regulator.subjects.1
let other_subject = if regulator.subjects[0] == element_key {
regulator.subjects[1]
} else {
regulator.subjects.0
regulator.subjects[0]
};
let other_subject_label = assembly.elements.with(|elts| elts[other_subject].label.clone());
view! {