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
static NEXT_ELEMENT_SERIAL: AtomicU64 = AtomicU64::new(0);
pub trait ProblemPoser {
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>);
}
#[derive(Clone, PartialEq)]
pub struct Element {
pub id: String,
@ -123,8 +127,10 @@ impl Element {
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 {
problem.gram.push_sym(index, index, 1.0);
problem.guess.set_column(index, &self.representation.get_clone_untracked());
@ -134,14 +140,10 @@ impl Element {
}
}
pub trait Regulator: OutlineItem {
// get information
pub trait Regulator: ProblemPoser + OutlineItem {
fn subjects(&self) -> Vec<ElementKey>;
fn measurement(&self) -> ReadSignal<f64>;
fn set_point(&self) -> Signal<SpecifiedValue>;
// write problem data
fn write_to_problem(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>);
}
pub struct ProductRegulator {
@ -162,8 +164,10 @@ impl Regulator for ProductRegulator {
fn set_point(&self) -> Signal<SpecifiedValue> {
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| {
if let Some(val) = set_pt.value {
let subject_column_indices = self.subjects.map(
@ -197,8 +201,10 @@ impl Regulator for HalfCurvatureRegulator {
fn set_point(&self) -> Signal<SpecifiedValue> {
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| {
if let Some(val) = set_pt.value {
if let Some(col) = elts[self.subject].column_index {
@ -441,11 +447,11 @@ impl Assembly {
let problem = self.elements.with_untracked(|elts| {
let mut problem_to_be = ConstraintProblem::new(elts.len());
for (_, elt) in elts {
elt.write_to_problem(&mut problem_to_be);
elt.pose(&mut problem_to_be, elts);
}
self.regulators.with_untracked(|regs| {
for (_, reg) in regs {
reg.write_to_problem(&mut problem_to_be, elts);
reg.pose(&mut problem_to_be, elts);
}
});
problem_to_be
@ -621,7 +627,7 @@ mod tests {
"Sphere".to_string(),
[1.0_f32, 1.0_f32, 1.0_f32],
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,
measurement: create_memo(|| 0.0),
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);
});
}
}