Introduce a problem poser trait

Elements and regulators use this common interface to write their data
into the constraint problem.
This commit is contained in:
Aaron Fenyes 2025-04-03 14:13:45 -07:00
parent bba0ac3cd6
commit 63e3d733ba

View file

@ -31,6 +31,10 @@ pub type ElementColor = [f32; 3];
// each assembly has a key that identifies it within the sesssion // each assembly has a key that identifies it within the sesssion
static NEXT_ELEMENT_SERIAL: AtomicU64 = AtomicU64::new(0); static NEXT_ELEMENT_SERIAL: AtomicU64 = AtomicU64::new(0);
pub trait ProblemPoser {
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>);
}
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub struct Element { pub struct Element {
pub id: String, pub id: String,
@ -123,8 +127,10 @@ impl Element {
None None
} }
} }
}
fn write_to_problem(&self, problem: &mut ConstraintProblem) {
impl ProblemPoser for Element {
fn pose(&self, problem: &mut ConstraintProblem, _elts: &Slab<Element>) {
if let Some(index) = self.column_index { if let Some(index) = self.column_index {
problem.gram.push_sym(index, index, 1.0); problem.gram.push_sym(index, index, 1.0);
problem.guess.set_column(index, &self.representation.get_clone_untracked()); problem.guess.set_column(index, &self.representation.get_clone_untracked());
@ -134,14 +140,10 @@ impl Element {
} }
} }
pub trait Regulator: OutlineItem { pub trait Regulator: ProblemPoser + OutlineItem {
// get information
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>;
// write problem data
fn write_to_problem(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>);
} }
pub struct ProductRegulator { pub struct ProductRegulator {
@ -162,8 +164,10 @@ impl Regulator for ProductRegulator {
fn set_point(&self) -> Signal<SpecifiedValue> { fn set_point(&self) -> Signal<SpecifiedValue> {
self.set_point self.set_point
} }
}
fn write_to_problem(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
impl ProblemPoser for ProductRegulator {
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
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 {
let subject_column_indices = self.subjects.map( let subject_column_indices = self.subjects.map(
@ -197,8 +201,10 @@ impl Regulator for HalfCurvatureRegulator {
fn set_point(&self) -> Signal<SpecifiedValue> { fn set_point(&self) -> Signal<SpecifiedValue> {
self.set_point self.set_point
} }
}
fn write_to_problem(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
impl ProblemPoser for HalfCurvatureRegulator {
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
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 {
@ -441,11 +447,11 @@ impl Assembly {
let problem = self.elements.with_untracked(|elts| { let problem = self.elements.with_untracked(|elts| {
let mut problem_to_be = ConstraintProblem::new(elts.len()); let mut problem_to_be = ConstraintProblem::new(elts.len());
for (_, elt) in elts { for (_, elt) in elts {
elt.write_to_problem(&mut problem_to_be); elt.pose(&mut problem_to_be, elts);
} }
self.regulators.with_untracked(|regs| { self.regulators.with_untracked(|regs| {
for (_, reg) in regs { for (_, reg) in regs {
reg.write_to_problem(&mut problem_to_be, elts); reg.pose(&mut problem_to_be, elts);
} }
}); });
problem_to_be problem_to_be
@ -621,7 +627,7 @@ mod tests {
"Sphere".to_string(), "Sphere".to_string(),
[1.0_f32, 1.0_f32, 1.0_f32], [1.0_f32, 1.0_f32, 1.0_f32],
engine::sphere(0.0, 0.0, 0.0, 1.0) engine::sphere(0.0, 0.0, 0.0, 1.0)
).write_to_problem(&mut ConstraintProblem::new(1)); ).pose(&mut ConstraintProblem::new(1), &Slab::new());
}); });
} }
@ -645,7 +651,7 @@ mod tests {
subjects: subjects, subjects: subjects,
measurement: create_memo(|| 0.0), measurement: create_memo(|| 0.0),
set_point: create_signal(SpecifiedValue::try_from("0.0".to_string()).unwrap()) set_point: create_signal(SpecifiedValue::try_from("0.0".to_string()).unwrap())
}.write_to_problem(&mut ConstraintProblem::new(2), &elts); }.pose(&mut ConstraintProblem::new(2), &elts);
}); });
} }
} }