dyna3/app-proto/src/components/add_remove.rs
Vectornaut 2eba80fb69 Simplify the realization triggering system (#105)
Simplifies the system that reactively triggers realizations, at the cost of removing the preconditioning step described in issue #101 and doing unnecessary realizations after certain kinds of updates.

Co-authored-by: Aaron Fenyes <aaron.fenyes@fareycircles.ooo>
Reviewed-on: StudioInfinity/dyna3#105
Co-authored-by: Vectornaut <vectornaut@nobody@nowhere.net>
Co-committed-by: Vectornaut <vectornaut@nobody@nowhere.net>
2025-07-31 22:21:32 +00:00

69 lines
No EOL
2.8 KiB
Rust

use std::rc::Rc;
use sycamore::prelude::*;
use super::test_assembly_chooser::TestAssemblyChooser;
use crate::{
AppState,
assembly::{InversiveDistanceRegulator, Point, Sphere}
};
#[component]
pub fn AddRemove() -> View {
view! {
div(id="add-remove") {
button(
on:click=|_| {
let state = use_context::<AppState>();
batch(|| {
// this call is batched to avoid redundant realizations.
// it updates the element list and the regulator list,
// which are both tracked by the realization effect
/* TO DO */
// it would make more to do the batching inside
// `insert_element_default`, but that will have to wait
// until Sycamore handles nested batches correctly.
//
// https://github.com/sycamore-rs/sycamore/issues/802
//
// the nested batch issue is relevant here because the
// assembly loaders in the test assembly chooser use
// `insert_element_default` within larger batches
state.assembly.insert_element_default::<Sphere>();
});
}
) { "Add sphere" }
button(
on:click=|_| {
let state = use_context::<AppState>();
state.assembly.insert_element_default::<Point>();
}
) { "Add point" }
button(
class="emoji", /* KLUDGE */ // for convenience, we're using an emoji as a temporary icon for this button
disabled={
let state = use_context::<AppState>();
state.selection.with(|sel| sel.len() != 2)
},
on:click=|_| {
let state = use_context::<AppState>();
let subjects: [_; 2] = state.selection.with(
// the button is only enabled when two elements are
// selected, so we know the cast to a two-element array
// will succeed
|sel| sel
.clone()
.into_iter()
.collect::<Vec<_>>()
.try_into()
.unwrap()
);
state.assembly.insert_regulator(
Rc::new(InversiveDistanceRegulator::new(subjects))
);
state.selection.update(|sel| sel.clear());
}
) { "🔗" }
TestAssemblyChooser {}
}
}
}