Introduce a regulator trait

This will provide a common interface for Lorentz product regulators,
curvature regulators, and hopefully all the other regulators too.
This commit is contained in:
Aaron Fenyes 2025-03-27 00:29:27 -07:00
parent 00f60b0e90
commit 126d4c0cce
3 changed files with 75 additions and 35 deletions

View file

@ -1,4 +1,5 @@
use itertools::Itertools;
use std::rc::Rc;
use sycamore::prelude::*;
use web_sys::{
KeyboardEvent,
@ -9,24 +10,32 @@ use web_sys::{
use crate::{
AppState,
assembly,
assembly::{ElementKey, ProductRegulator, RegulatorKey},
assembly::{ElementKey, Regulator, RegulatorKey},
specified::SpecifiedValue
};
// an editable view of a regulator
#[component(inline_props)]
fn RegulatorInput(regulator: ProductRegulator) -> View {
fn RegulatorInput(regulator: Rc<dyn Regulator>) -> View {
// get the regulator's measurement and set point signals
let measurement = regulator.measurement();
let set_point = regulator.set_point();
// the `valid` signal tracks whether the last entered value is a valid set
// point specification
let valid = create_signal(true);
// the `value` signal holds the current set point specification
let value = create_signal(
regulator.set_point.with_untracked(|set_pt| set_pt.spec.clone())
set_point.with_untracked(|set_pt| set_pt.spec.clone())
);
// this closure resets the input value to the regulator's set point
// specification
// this `reset_value` closure resets the input value to the regulator's set
// point specification
let reset_value = move || {
batch(|| {
valid.set(true);
value.set(regulator.set_point.with(|set_pt| set_pt.spec.clone()));
value.set(set_point.with(|set_pt| set_pt.spec.clone()));
})
};
@ -39,7 +48,7 @@ fn RegulatorInput(regulator: ProductRegulator) -> View {
r#type="text",
class=move || {
if valid.get() {
regulator.set_point.with(|set_pt| {
set_point.with(|set_pt| {
if set_pt.is_present() {
"regulator-input constraint"
} else {
@ -50,13 +59,13 @@ fn RegulatorInput(regulator: ProductRegulator) -> View {
"regulator-input invalid"
}
},
placeholder=regulator.measurement.with(|result| result.to_string()),
placeholder=measurement.with(|result| result.to_string()),
bind:value=value,
on:change=move |_| {
valid.set(
match SpecifiedValue::try_from(value.get_clone_untracked()) {
Ok(set_pt) => {
regulator.set_point.set(set_pt);
set_point.set(set_pt);
true
}
Err(_) => false
@ -80,11 +89,12 @@ fn RegulatorInput(regulator: ProductRegulator) -> View {
fn RegulatorOutlineItem(regulator_key: RegulatorKey, element_key: ElementKey) -> View {
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 regulator = assembly.regulators.with(|regs| regs[regulator_key].clone());
let subjects = regulator.subjects();
let other_subject = if subjects[0] == element_key {
subjects[1]
} else {
regulator.subjects[0]
subjects[0]
};
let other_subject_label = assembly.elements.with(|elts| elts[other_subject].label.clone());
view! {