diff --git a/app-proto/src/add_remove.rs b/app-proto/src/add_remove.rs index 3280dac..c96d5ab 100644 --- a/app-proto/src/add_remove.rs +++ b/app-proto/src/add_remove.rs @@ -7,7 +7,6 @@ use crate::{ assembly::{ Assembly, Regulator, - RegulatorRole, Element }, engine::Q @@ -209,14 +208,12 @@ pub fn AddRemove() -> View { reps.0.dot(&(&*Q * reps.1)) } ); - let set_point = create_signal(0.0); - let role = create_signal(RegulatorRole::Measurement); + let set_point = create_signal(None); state.assembly.insert_regulator(Regulator { subjects: subjects, measurement: measurement, set_point: set_point, - set_point_text: create_signal(String::new()), - role: role, + set_point_spec: create_signal(String::new()) }); state.selection.update(|sel| sel.clear()); @@ -241,8 +238,7 @@ pub fn AddRemove() -> View { console::log_1(&JsValue::from( format!("Updated constraint with subjects ({}, {})", subjects.0, subjects.1) )); - set_point.track(); - if role.with(|rl| rl.is_valid_constraint()) { + if set_point.with(|set_pt| set_pt.is_some()) { state.assembly.realize(); } }); diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index c052a3b..c1eba1e 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -111,32 +111,17 @@ impl Element { } } -pub enum RegulatorRole { - Measurement, - Constraint(bool) -} - -impl RegulatorRole { - pub fn is_valid_constraint(&self) -> bool { - match self { - RegulatorRole::Measurement => false, - RegulatorRole::Constraint(valid) => *valid - } - } -} - -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct Regulator { pub subjects: (ElementKey, ElementKey), pub measurement: ReadSignal, - pub set_point: Signal, - pub set_point_text: Signal, - pub role: Signal + pub set_point: Signal>, + pub set_point_spec: Signal } impl Regulator { - fn role_is_valid_constraint_untracked(&self) -> bool { - self.role.with_untracked(|role| role.is_valid_constraint()) + pub fn has_no_set_point_spec(&self) -> bool { + self.set_point_spec.with(|spec| spec.is_empty()) } } @@ -250,11 +235,14 @@ impl Assembly { let mut gram_to_be = PartialMatrix::new(); self.regulators.with_untracked(|regs| { for (_, reg) in regs { - if reg.role_is_valid_constraint_untracked() { - let subjects = reg.subjects; - let row = elts[subjects.0].column_index.unwrap(); - let col = elts[subjects.1].column_index.unwrap(); - gram_to_be.push_sym(row, col, reg.set_point.get_untracked()); + match reg.set_point.get_untracked() { + Some(set_pt) => { + let subjects = reg.subjects; + let row = elts[subjects.0].column_index.unwrap(); + let col = elts[subjects.1].column_index.unwrap(); + gram_to_be.push_sym(row, col, set_pt); + }, + None => () } } }); diff --git a/app-proto/src/outline.rs b/app-proto/src/outline.rs index 8dcda93..d892f0f 100644 --- a/app-proto/src/outline.rs +++ b/app-proto/src/outline.rs @@ -1,8 +1,6 @@ use itertools::Itertools; use sycamore::prelude::*; use web_sys::{ - Event, - HtmlInputElement, KeyboardEvent, MouseEvent, wasm_bindgen::JsCast @@ -14,7 +12,6 @@ use crate::{ assembly::{ Regulator, RegulatorKey, - RegulatorRole::*, ElementKey } }; @@ -22,25 +19,17 @@ use crate::{ // an editable view of a regulator #[component(inline_props)] fn RegulatorInput(regulator: Regulator) -> View { + let value = create_signal(regulator.set_point_spec.get_clone_untracked()); + create_effect(move || value.set(regulator.set_point_spec.get_clone())); view! { input( r#type="text", placeholder=regulator.measurement.with(|result| result.to_string()), - bind:value=regulator.set_point_text, - on:change=move |event: Event| { - let target: HtmlInputElement = event.target().unwrap().unchecked_into(); - let value = target.value(); - if value.is_empty() { - regulator.role.set(Measurement); - } else { - match target.value().parse::() { - Ok(set_pt) => batch(|| { - regulator.set_point.set(set_pt); - regulator.role.set(Constraint(true)); - }), - Err(_) => regulator.role.set(Constraint(false)) - }; - } + bind:value=value, + on:change=move |_| { + let value_val = value.get_clone_untracked(); + regulator.set_point.set(value_val.parse::().ok()); + regulator.set_point_spec.set(value_val); } ) } @@ -51,20 +40,20 @@ fn RegulatorInput(regulator: Regulator) -> View { fn RegulatorOutlineItem(regulator_key: RegulatorKey, element_key: ElementKey) -> View { let state = use_context::(); let assembly = &state.assembly; - let regulator = assembly.regulators.with(|regs| regs[regulator_key].clone()); + let regulator = assembly.regulators.with(|regs| regs[regulator_key]); let other_subject = if regulator.subjects.0 == element_key { regulator.subjects.1 } else { regulator.subjects.0 }; let other_subject_label = assembly.elements.with(|elts| elts[other_subject].label.clone()); - let class = regulator.role.map( - |role| match role { - Measurement => "regulator", - Constraint(true) => "regulator valid-constraint", - Constraint(false) => "regulator invalid-constraint" + let class = create_memo(move || { + match regulator.set_point.get() { + None if regulator.has_no_set_point_spec() => "regulator", + None => "regulator invalid-constraint", + Some(_) => "regulator valid-constraint" } - ); + }); view! { li(class=class.get()) { div(class="regulator-label") { (other_subject_label) }