Give each element a serial number (#22)
Give each `Element` a serial number, which identifies it uniquely. The serial number is assigned by the `Element::new` constructor. Because disallows potentially unsafe global state (at least without explicit `unsafe` blocks), the next serial number is stored in a thread-safe static atomic variable (`assembly::NEXT_ELEMENT_SERIAL`), as suggested in [this StackOverflow answer](https://stackoverflow.com/a/32936288). Since the overhead for keeping track of memory ordering should be minimal, we're using the strongest available ordering: [sequentially consistent](https://marabos.nl/atomics/memory-ordering.html#seqcst). Resolves #20. Co-authored-by: Aaron Fenyes <aaron.fenyes@fareycircles.ooo> Reviewed-on: #22 Co-authored-by: Vectornaut <vectornaut@nobody@nowhere.net> Co-committed-by: Vectornaut <vectornaut@nobody@nowhere.net>
This commit is contained in:
parent
65cee1ecc2
commit
e917272c60
@ -1,7 +1,7 @@
|
|||||||
use nalgebra::{DMatrix, DVector};
|
use nalgebra::{DMatrix, DVector};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
use std::collections::BTreeSet;
|
use std::{collections::BTreeSet, 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 */
|
||||||
|
|
||||||
@ -13,6 +13,13 @@ pub type ConstraintKey = usize;
|
|||||||
|
|
||||||
pub type ElementColor = [f32; 3];
|
pub type ElementColor = [f32; 3];
|
||||||
|
|
||||||
|
/* KLUDGE */
|
||||||
|
// we should reconsider this design when we build a system for switching between
|
||||||
|
// assemblies. at that point, we might want to switch to hierarchical keys,
|
||||||
|
// where each each element has a key that identifies it within its assembly and
|
||||||
|
// each assembly has a key that identifies it within the sesssion
|
||||||
|
static NEXT_ELEMENT_SERIAL: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct Element {
|
pub struct Element {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
@ -21,6 +28,10 @@ pub struct Element {
|
|||||||
pub representation: Signal<DVector<f64>>,
|
pub representation: Signal<DVector<f64>>,
|
||||||
pub constraints: Signal<BTreeSet<ConstraintKey>>,
|
pub constraints: Signal<BTreeSet<ConstraintKey>>,
|
||||||
|
|
||||||
|
// a serial number, assigned by `Element::new`, that uniquely identifies
|
||||||
|
// each element
|
||||||
|
pub serial: u64,
|
||||||
|
|
||||||
// the configuration matrix column index that was assigned to this element
|
// the configuration matrix column index that was assigned to this element
|
||||||
// last time the assembly was realized
|
// last time the assembly was realized
|
||||||
column_index: usize
|
column_index: usize
|
||||||
@ -33,12 +44,24 @@ impl Element {
|
|||||||
color: ElementColor,
|
color: ElementColor,
|
||||||
representation: DVector<f64>
|
representation: DVector<f64>
|
||||||
) -> Element {
|
) -> Element {
|
||||||
|
// take the next serial number, panicking if that was the last number we
|
||||||
|
// had left. the technique we use to panic on overflow is taken from
|
||||||
|
// _Rust Atomics and Locks_, by Mara Bos
|
||||||
|
//
|
||||||
|
// https://marabos.nl/atomics/atomics.html#example-handle-overflow
|
||||||
|
//
|
||||||
|
let serial = NEXT_ELEMENT_SERIAL.fetch_update(
|
||||||
|
Ordering::SeqCst, Ordering::SeqCst,
|
||||||
|
|serial| serial.checked_add(1)
|
||||||
|
).expect("Out of serial numbers for elements");
|
||||||
|
|
||||||
Element {
|
Element {
|
||||||
id: id,
|
id: id,
|
||||||
label: label,
|
label: label,
|
||||||
color: color,
|
color: color,
|
||||||
representation: create_signal(representation),
|
representation: create_signal(representation),
|
||||||
constraints: create_signal(BTreeSet::default()),
|
constraints: create_signal(BTreeSet::default()),
|
||||||
|
serial: serial,
|
||||||
column_index: 0
|
column_index: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ pub fn Outline() -> View {
|
|||||||
view=|(key, elt)| view! {
|
view=|(key, elt)| view! {
|
||||||
ElementOutlineItem(key=key, element=elt)
|
ElementOutlineItem(key=key, element=elt)
|
||||||
},
|
},
|
||||||
key=|(key, _)| key.clone()
|
key=|(_, elt)| elt.serial
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user