forked from StudioInfinity/dyna3
Compare commits
3 commits
874c823dbe
...
c58fed073d
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c58fed073d | ||
![]() |
309b0881df | ||
![]() |
894931a6e7 |
4 changed files with 69 additions and 75 deletions
|
@ -1,15 +1,14 @@
|
||||||
use nalgebra::{DMatrix, DVector, DVectorView, Vector3};
|
use nalgebra::{DMatrix, DVector, DVectorView, Vector3};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
use std::{
|
use std::{collections::BTreeSet, sync::atomic::{AtomicU64, Ordering}};
|
||||||
collections::BTreeSet,
|
|
||||||
num::ParseFloatError,
|
|
||||||
sync::atomic::{AtomicU64, Ordering}
|
|
||||||
};
|
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */
|
use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */
|
||||||
|
|
||||||
use crate::engine::{Q, local_unif_to_std, realize_gram, ConfigSubspace, PartialMatrix};
|
use crate::{
|
||||||
|
engine::{Q, local_unif_to_std, realize_gram, ConfigSubspace, PartialMatrix},
|
||||||
|
specified::{SpecifiedValue, SpecifiedValue::{Absent, Present}}
|
||||||
|
};
|
||||||
|
|
||||||
// the types of the keys we use to access an assembly's elements and regulators
|
// the types of the keys we use to access an assembly's elements and regulators
|
||||||
pub type ElementKey = usize;
|
pub type ElementKey = usize;
|
||||||
|
@ -118,61 +117,6 @@ impl Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// to construct a `SpecifiedValue` that might be `Present`, use the associated
|
|
||||||
// function `try_from`. this ensures that `spec` is always a valid specification
|
|
||||||
// of `value` according to the format discussed at the implementation of
|
|
||||||
// `TryFrom<String>`
|
|
||||||
pub enum SpecifiedValue {
|
|
||||||
Absent,
|
|
||||||
Present {
|
|
||||||
spec: String,
|
|
||||||
value: f64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use SpecifiedValue::*;
|
|
||||||
|
|
||||||
impl SpecifiedValue {
|
|
||||||
// get the specification for this value. the associated function `try_from`
|
|
||||||
// is essentially a left inverse of this method:
|
|
||||||
//
|
|
||||||
// SpecifiedValue::try_from(x.spec()) == Ok(x)
|
|
||||||
//
|
|
||||||
pub fn spec(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Absent => String::new(),
|
|
||||||
Present { spec, .. } => spec.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_present(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Absent => false,
|
|
||||||
Present { .. } => true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we can try to turn a specification string into a `SpecifiedValue`. if the
|
|
||||||
// specification is empty, the `SpecifiedValue` is `Absent`. if the
|
|
||||||
// specification parses to a floating-point value `x`, the `SpecifiedValue` is
|
|
||||||
// `Present`, with a `value` of `x`, and the specification is stored in `spec`.
|
|
||||||
// these are currently the only valid specifications; any other produces an
|
|
||||||
// error
|
|
||||||
impl TryFrom<String> for SpecifiedValue {
|
|
||||||
type Error = ParseFloatError;
|
|
||||||
|
|
||||||
fn try_from(spec: String) -> Result<Self, Self::Error> {
|
|
||||||
if spec.is_empty() {
|
|
||||||
Ok(Absent)
|
|
||||||
} else {
|
|
||||||
spec.parse::<f64>().map(
|
|
||||||
|value| Present { spec: spec, value: value }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Regulator {
|
pub struct Regulator {
|
||||||
pub subjects: (ElementKey, ElementKey),
|
pub subjects: (ElementKey, ElementKey),
|
||||||
|
@ -181,13 +125,11 @@ pub struct Regulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Regulator {
|
impl Regulator {
|
||||||
pub fn try_set(&self, set_pt_spec: String) -> bool {
|
/* TO DO */
|
||||||
match SpecifiedValue::try_from(set_pt_spec) {
|
// if it's called for, add a `set` method that takes a bare SpecifiedValue
|
||||||
Ok(set_pt) => {
|
pub fn set_if_ok<E>(&self, set_pt_result: Result<SpecifiedValue, E>) {
|
||||||
|
if let Ok(set_pt) = set_pt_result {
|
||||||
self.set_point.set(set_pt);
|
self.set_point.set(set_pt);
|
||||||
true
|
|
||||||
}
|
|
||||||
Err(_) => false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,7 +269,7 @@ impl Assembly {
|
||||||
console::log_1(&JsValue::from(
|
console::log_1(&JsValue::from(
|
||||||
format!("Updated constraint with subjects ({}, {})", subjects.0, subjects.1)
|
format!("Updated constraint with subjects ({}, {})", subjects.0, subjects.1)
|
||||||
));
|
));
|
||||||
if set_point.with(|set_pt| set_pt.is_present()) {
|
if set_point.with(|set_pt| matches!(set_pt, Present { .. })) {
|
||||||
self.realize();
|
self.realize();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@ mod assembly;
|
||||||
mod display;
|
mod display;
|
||||||
mod engine;
|
mod engine;
|
||||||
mod outline;
|
mod outline;
|
||||||
|
mod specified;
|
||||||
|
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
|
@ -12,9 +12,9 @@ use crate::{
|
||||||
assembly::{
|
assembly::{
|
||||||
ElementKey,
|
ElementKey,
|
||||||
Regulator,
|
Regulator,
|
||||||
RegulatorKey,
|
RegulatorKey
|
||||||
SpecifiedValue::*
|
},
|
||||||
}
|
specified::{SpecifiedValue, SpecifiedValue::{Absent, Present}}
|
||||||
};
|
};
|
||||||
|
|
||||||
// an editable view of a regulator
|
// an editable view of a regulator
|
||||||
|
@ -55,9 +55,11 @@ fn RegulatorInput(regulator: Regulator) -> View {
|
||||||
},
|
},
|
||||||
placeholder=regulator.measurement.with(|result| result.to_string()),
|
placeholder=regulator.measurement.with(|result| result.to_string()),
|
||||||
bind:value=value,
|
bind:value=value,
|
||||||
on:change=move |_| valid.set(
|
on:change=move |_| {
|
||||||
regulator.try_set(value.get_clone_untracked())
|
let set_pt_result = SpecifiedValue::try_from(value.get_clone_untracked());
|
||||||
),
|
valid.set(set_pt_result.is_ok());
|
||||||
|
regulator.set_if_ok(set_pt_result);
|
||||||
|
},
|
||||||
on:keydown={
|
on:keydown={
|
||||||
move |event: KeyboardEvent| {
|
move |event: KeyboardEvent| {
|
||||||
match event.key().as_str() {
|
match event.key().as_str() {
|
||||||
|
|
49
app-proto/src/specified.rs
Normal file
49
app-proto/src/specified.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use std::num::ParseFloatError;
|
||||||
|
|
||||||
|
// to construct a `SpecifiedValue` that might be `Present`, use the associated
|
||||||
|
// function `try_from`. this ensures that `spec` is always a valid specification
|
||||||
|
// of `value` according to the format discussed at the implementation of
|
||||||
|
// `TryFrom<String>`
|
||||||
|
pub enum SpecifiedValue {
|
||||||
|
Absent,
|
||||||
|
Present {
|
||||||
|
spec: String,
|
||||||
|
value: f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use SpecifiedValue::{Absent, Present};
|
||||||
|
|
||||||
|
impl SpecifiedValue {
|
||||||
|
// get the specification for this value. the associated function `try_from`
|
||||||
|
// is essentially a left inverse of this method:
|
||||||
|
//
|
||||||
|
// SpecifiedValue::try_from(x.spec()) == Ok(x)
|
||||||
|
//
|
||||||
|
pub fn spec(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Absent => String::new(),
|
||||||
|
Present { spec, .. } => spec.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can try to turn a specification string into a `SpecifiedValue`. if the
|
||||||
|
// specification is empty, the `SpecifiedValue` is `Absent`. if the
|
||||||
|
// specification parses to a floating-point value `x`, the `SpecifiedValue` is
|
||||||
|
// `Present`, with a `value` of `x`, and the specification is stored in `spec`.
|
||||||
|
// these are currently the only valid specifications; any other produces an
|
||||||
|
// error
|
||||||
|
impl TryFrom<String> for SpecifiedValue {
|
||||||
|
type Error = ParseFloatError;
|
||||||
|
|
||||||
|
fn try_from(spec: String) -> Result<Self, Self::Error> {
|
||||||
|
if spec.is_empty() {
|
||||||
|
Ok(Absent)
|
||||||
|
} else {
|
||||||
|
spec.parse::<f64>().map(
|
||||||
|
|value| Present { spec: spec, value: value }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue