AddRemove: make a button that adds elements
In the process, switch selection storage back to `FxHashSet`, reverting
commit b3afd6f
.
This commit is contained in:
parent
2444649dd1
commit
bd0982f821
@ -11,6 +11,7 @@ default = ["console_error_panic_hook"]
|
|||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
js-sys = "0.3.70"
|
js-sys = "0.3.70"
|
||||||
nalgebra = "0.33.0"
|
nalgebra = "0.33.0"
|
||||||
|
rustc-hash = "2.0.0"
|
||||||
slab = "0.4.9"
|
slab = "0.4.9"
|
||||||
sycamore = "0.9.0-beta.3"
|
sycamore = "0.9.0-beta.3"
|
||||||
|
|
||||||
|
@ -6,16 +6,51 @@ use crate::Constraint;
|
|||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn AddRemove() -> View {
|
pub fn AddRemove() -> View {
|
||||||
let state = use_context::<AppState>();
|
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
div(id="add-remove") {
|
div(id="add-remove") {
|
||||||
button(
|
button(
|
||||||
on:click=move |_| {
|
on:click=|_| {
|
||||||
|
let state = use_context::<AppState>();
|
||||||
|
state.assembly.insert_new_element();
|
||||||
|
|
||||||
|
/* DEBUG */
|
||||||
|
// print updated list of elements by identifier
|
||||||
|
console::log_1(&JsValue::from("elements by identifier:"));
|
||||||
|
for (id, key) in state.assembly.elements_by_id.get_clone().iter() {
|
||||||
|
console::log_3(
|
||||||
|
&JsValue::from(" "),
|
||||||
|
&JsValue::from(id),
|
||||||
|
&JsValue::from(*key)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) { "+" }
|
||||||
|
button(
|
||||||
|
disabled={
|
||||||
|
let state = use_context::<AppState>();
|
||||||
|
state.selection.with(|sel| sel.len() != 2)
|
||||||
|
},
|
||||||
|
on:click=|_| {
|
||||||
|
let state = use_context::<AppState>();
|
||||||
|
let args = state.selection.with(
|
||||||
|
|sel| {
|
||||||
|
let arg_vec: Vec<_> = sel.into_iter().collect();
|
||||||
|
(arg_vec[0].clone(), arg_vec[1].clone())
|
||||||
|
}
|
||||||
|
);
|
||||||
|
state.assembly.insert_constraint(Constraint {
|
||||||
|
args: args,
|
||||||
|
rep: 0.0
|
||||||
|
});
|
||||||
|
state.selection.update(|sel| sel.clear());
|
||||||
|
|
||||||
|
/* DEBUG */
|
||||||
|
// print updated constraint list
|
||||||
console::log_1(&JsValue::from("constraints:"));
|
console::log_1(&JsValue::from("constraints:"));
|
||||||
state.assembly.constraints.with(|csts| {
|
state.assembly.constraints.with(|csts| {
|
||||||
for (_, cst) in csts.into_iter() {
|
for (_, cst) in csts.into_iter() {
|
||||||
console::log_4(
|
console::log_5(
|
||||||
|
&JsValue::from(" "),
|
||||||
&JsValue::from(cst.args.0),
|
&JsValue::from(cst.args.0),
|
||||||
&JsValue::from(cst.args.1),
|
&JsValue::from(cst.args.1),
|
||||||
&JsValue::from(":"),
|
&JsValue::from(":"),
|
||||||
@ -24,31 +59,6 @@ pub fn AddRemove() -> View {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
) { "+" }
|
|
||||||
button(
|
|
||||||
disabled={
|
|
||||||
state.selection.with(|sel| sel.len() != 2)
|
|
||||||
},
|
|
||||||
on:click=move |_| {
|
|
||||||
let args = state.selection.with(
|
|
||||||
|sel| {
|
|
||||||
let arg_vec: Vec<_> = sel.into_iter().collect();
|
|
||||||
(arg_vec[0].clone(), arg_vec[1].clone())
|
|
||||||
}
|
|
||||||
);
|
|
||||||
console::log_5(
|
|
||||||
&JsValue::from("add constraint"),
|
|
||||||
&JsValue::from(args.0),
|
|
||||||
&JsValue::from(args.1),
|
|
||||||
&JsValue::from(":"),
|
|
||||||
&JsValue::from(0.0)
|
|
||||||
);
|
|
||||||
state.assembly.insert_constraint(Constraint {
|
|
||||||
args: args,
|
|
||||||
rep: 0.0
|
|
||||||
});
|
|
||||||
state.selection.update(|sel| sel.clear());
|
|
||||||
}
|
|
||||||
) { "🔗" }
|
) { "🔗" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use nalgebra::DVector;
|
use nalgebra::DVector;
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
@ -21,18 +22,46 @@ pub struct Constraint {
|
|||||||
// a complete, view-independent description of an assembly
|
// a complete, view-independent description of an assembly
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Assembly {
|
pub struct Assembly {
|
||||||
|
// elements and constraints
|
||||||
pub elements: Signal<Slab<Element>>,
|
pub elements: Signal<Slab<Element>>,
|
||||||
pub constraints: Signal<Slab<Constraint>>
|
pub constraints: Signal<Slab<Constraint>>,
|
||||||
|
|
||||||
|
// indexing
|
||||||
|
pub elements_by_id: Signal<FxHashMap<String, usize>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Assembly {
|
impl Assembly {
|
||||||
pub fn new() -> Assembly {
|
pub fn new() -> Assembly {
|
||||||
Assembly {
|
Assembly {
|
||||||
elements: create_signal(Slab::new()),
|
elements: create_signal(Slab::new()),
|
||||||
constraints: create_signal(Slab::new())
|
constraints: create_signal(Slab::new()),
|
||||||
|
elements_by_id: create_signal(FxHashMap::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_new_element(&self) {
|
||||||
|
// find the next unused identifier in the default sequence
|
||||||
|
let mut id_num = 1;
|
||||||
|
let mut id = format!("sphere{}", id_num);
|
||||||
|
while self.elements_by_id.with(
|
||||||
|
|elts_by_id| elts_by_id.contains_key(&id)
|
||||||
|
) {
|
||||||
|
id_num += 1;
|
||||||
|
id = format!("sphere{}", id_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create and insert a new element
|
||||||
|
let elt = Element {
|
||||||
|
id: id.clone(),
|
||||||
|
label: format!("Sphere {}", id_num),
|
||||||
|
color: [0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
rep: DVector::<f64>::from_column_slice(&[0.0, 0.0, 0.0, 0.5, -0.5]),
|
||||||
|
constraints: BTreeSet::default()
|
||||||
|
};
|
||||||
|
let key = self.elements.update(|elts| elts.insert(elt));
|
||||||
|
self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert_constraint(&self, constraint: Constraint) {
|
pub fn insert_constraint(&self, constraint: Constraint) {
|
||||||
let args = constraint.args;
|
let args = constraint.args;
|
||||||
let key = self.constraints.update(|csts| csts.insert(constraint));
|
let key = self.constraints.update(|csts| csts.insert(constraint));
|
||||||
|
@ -4,6 +4,7 @@ mod display;
|
|||||||
mod outline;
|
mod outline;
|
||||||
|
|
||||||
use nalgebra::DVector;
|
use nalgebra::DVector;
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
||||||
@ -15,14 +16,14 @@ use outline::Outline;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct AppState {
|
struct AppState {
|
||||||
assembly: Assembly,
|
assembly: Assembly,
|
||||||
selection: Signal<BTreeSet<usize>>
|
selection: Signal<FxHashSet<usize>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
fn new() -> AppState {
|
fn new() -> AppState {
|
||||||
AppState {
|
AppState {
|
||||||
assembly: Assembly::new(),
|
assembly: Assembly::new(),
|
||||||
selection: create_signal(BTreeSet::default())
|
selection: create_signal(FxHashSet::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user