Refactor: Use pointers to refer to elements and regulators (#84)
All checks were successful
/ test (push) Successful in 2m25s
All checks were successful
/ test (push) Successful in 2m25s
Previously, dyna3 used storage keys to refer to elements, necessitating passing around element containers to various functions so that they could access the relevant elements. These storage keys have been replaced with reference-counted pointers, used for tasks like these: - Specifying the subjects of regulators. - Collecting the regulators each element is subject to - Handling selection. - Creating interface components. Also, systematizes the handling of serial numbers for entities, through a Serial trait. And updates to rust 1.86 and institutes explicit checking of the rust version. Co-authored-by: Aaron Fenyes <aaron.fenyes@fareycircles.ooo> Reviewed-on: #84 Co-authored-by: Vectornaut <vectornaut@nobody@nowhere.net> Co-committed-by: Vectornaut <vectornaut@nobody@nowhere.net>
This commit is contained in:
parent
a2478febc1
commit
2adf4669f4
8 changed files with 288 additions and 270 deletions
|
@ -11,12 +11,9 @@ use crate::{
|
|||
AppState,
|
||||
assembly::{
|
||||
Element,
|
||||
ElementKey,
|
||||
ElementRc,
|
||||
HalfCurvatureRegulator,
|
||||
InversiveDistanceRegulator,
|
||||
Regulator,
|
||||
RegulatorKey
|
||||
Regulator
|
||||
},
|
||||
specified::SpecifiedValue
|
||||
};
|
||||
|
@ -92,20 +89,16 @@ fn RegulatorInput(regulator: Rc<dyn Regulator>) -> View {
|
|||
}
|
||||
|
||||
pub trait OutlineItem {
|
||||
fn outline_item(self: Rc<Self>, element_key: ElementKey) -> View;
|
||||
fn outline_item(self: Rc<Self>, element: &Rc<dyn Element>) -> View;
|
||||
}
|
||||
|
||||
impl OutlineItem for InversiveDistanceRegulator {
|
||||
fn outline_item(self: Rc<Self>, element_key: ElementKey) -> View {
|
||||
let state = use_context::<AppState>();
|
||||
let other_subject = if self.subjects[0] == element_key {
|
||||
self.subjects[1]
|
||||
fn outline_item(self: Rc<Self>, element: &Rc<dyn Element>) -> View {
|
||||
let other_subject_label = if self.subjects[0] == element.clone() {
|
||||
self.subjects[1].label()
|
||||
} else {
|
||||
self.subjects[0]
|
||||
};
|
||||
let other_subject_label = state.assembly.elements.with(
|
||||
|elts| elts[other_subject].label().clone()
|
||||
);
|
||||
self.subjects[0].label()
|
||||
}.clone();
|
||||
view! {
|
||||
li(class="regulator") {
|
||||
div(class="regulator-label") { (other_subject_label) }
|
||||
|
@ -118,7 +111,7 @@ impl OutlineItem for InversiveDistanceRegulator {
|
|||
}
|
||||
|
||||
impl OutlineItem for HalfCurvatureRegulator {
|
||||
fn outline_item(self: Rc<Self>, _element_key: ElementKey) -> View {
|
||||
fn outline_item(self: Rc<Self>, _element: &Rc<dyn Element>) -> View {
|
||||
view! {
|
||||
li(class="regulator") {
|
||||
div(class="regulator-label") // for spacing
|
||||
|
@ -130,23 +123,16 @@ impl OutlineItem for HalfCurvatureRegulator {
|
|||
}
|
||||
}
|
||||
|
||||
// a list item that shows a regulator in an outline view of an element
|
||||
#[component(inline_props)]
|
||||
fn RegulatorOutlineItem(regulator_key: RegulatorKey, element_key: ElementKey) -> View {
|
||||
let state = use_context::<AppState>();
|
||||
let regulator = state.assembly.regulators.with(
|
||||
|regs| regs[regulator_key].clone()
|
||||
);
|
||||
regulator.outline_item(element_key)
|
||||
}
|
||||
|
||||
// a list item that shows an element in an outline view of an assembly
|
||||
#[component(inline_props)]
|
||||
fn ElementOutlineItem(key: ElementKey, element: Rc<dyn Element>) -> View {
|
||||
fn ElementOutlineItem(element: Rc<dyn Element>) -> View {
|
||||
let state = use_context::<AppState>();
|
||||
let class = state.selection.map(
|
||||
move |sel| if sel.contains(&key) { "selected" } else { "" }
|
||||
);
|
||||
let class = {
|
||||
let element_for_class = element.clone();
|
||||
state.selection.map(
|
||||
move |sel| if sel.contains(&element_for_class) { "selected" } else { "" }
|
||||
)
|
||||
};
|
||||
let label = element.label().clone();
|
||||
let representation = element.representation().clone();
|
||||
let rep_components = move || {
|
||||
|
@ -161,14 +147,10 @@ fn ElementOutlineItem(key: ElementKey, element: Rc<dyn Element>) -> View {
|
|||
};
|
||||
let regulated = element.regulators().map(|regs| regs.len() > 0);
|
||||
let regulator_list = element.regulators().map(
|
||||
move |elt_reg_keys| elt_reg_keys
|
||||
|regs| regs
|
||||
.clone()
|
||||
.into_iter()
|
||||
.sorted_by_key(
|
||||
|®_key| state.assembly.regulators.with(
|
||||
|regs| regs[reg_key].subjects().len()
|
||||
)
|
||||
)
|
||||
.sorted_by_key(|reg| reg.subjects().len())
|
||||
.collect()
|
||||
);
|
||||
let details_node = create_node_ref();
|
||||
|
@ -178,10 +160,11 @@ fn ElementOutlineItem(key: ElementKey, element: Rc<dyn Element>) -> View {
|
|||
summary(
|
||||
class=class.get(),
|
||||
on:keydown={
|
||||
let element_for_handler = element.clone();
|
||||
move |event: KeyboardEvent| {
|
||||
match event.key().as_str() {
|
||||
"Enter" => {
|
||||
state.select(key, event.shift_key());
|
||||
state.select(&element_for_handler, event.shift_key());
|
||||
event.prevent_default();
|
||||
},
|
||||
"ArrowRight" if regulated.get() => {
|
||||
|
@ -208,19 +191,10 @@ fn ElementOutlineItem(key: ElementKey, element: Rc<dyn Element>) -> View {
|
|||
div(
|
||||
class="element",
|
||||
on:click={
|
||||
let state_for_handler = state.clone();
|
||||
let element_for_handler = element.clone();
|
||||
move |event: MouseEvent| {
|
||||
if event.shift_key() {
|
||||
state.selection.update(|sel| {
|
||||
if !sel.remove(&key) {
|
||||
sel.insert(key);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
state.selection.update(|sel| {
|
||||
sel.clear();
|
||||
sel.insert(key);
|
||||
});
|
||||
}
|
||||
state_for_handler.select(&element_for_handler, event.shift_key());
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
}
|
||||
|
@ -234,13 +208,8 @@ fn ElementOutlineItem(key: ElementKey, element: Rc<dyn Element>) -> View {
|
|||
ul(class="regulators") {
|
||||
Keyed(
|
||||
list=regulator_list,
|
||||
view=move |reg_key| view! {
|
||||
RegulatorOutlineItem(
|
||||
regulator_key=reg_key,
|
||||
element_key=key
|
||||
)
|
||||
},
|
||||
key=|reg_key| reg_key.clone()
|
||||
view=move |reg| reg.outline_item(&element),
|
||||
key=|reg| reg.serial()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -259,12 +228,15 @@ pub fn Outline() -> View {
|
|||
let state = use_context::<AppState>();
|
||||
|
||||
// list the elements alphabetically by ID
|
||||
/* TO DO */
|
||||
// this code is designed to generalize easily to other sort keys. if we only
|
||||
// ever wanted to sort by ID, we could do that more simply using the
|
||||
// `elements_by_id` index
|
||||
let element_list = state.assembly.elements.map(
|
||||
|elts| elts
|
||||
.clone()
|
||||
.into_iter()
|
||||
.sorted_by_key(|(_, elt)| elt.id().clone())
|
||||
.map(|(key, elt)| (key, ElementRc(elt)))
|
||||
.sorted_by_key(|elt| elt.id().clone())
|
||||
.collect()
|
||||
);
|
||||
|
||||
|
@ -278,10 +250,10 @@ pub fn Outline() -> View {
|
|||
) {
|
||||
Keyed(
|
||||
list=element_list,
|
||||
view=|(key, ElementRc(elt))| view! {
|
||||
ElementOutlineItem(key=key, element=elt)
|
||||
view=|elt| view! {
|
||||
ElementOutlineItem(element=elt)
|
||||
},
|
||||
key=|(_, ElementRc(elt))| elt.serial()
|
||||
key=|elt| elt.serial()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue