Use pointers to refer to elements and regulators #84

Merged
glen merged 10 commits from Vectornaut/dyna3:use-pointers into main 2025-05-06 19:17:31 +00:00
Member

Summary

The branch to be merged uses reference-counted pointers, rather than storage keys, to refer to elements and regulators in tasks like these:

  • Specifying the subjects of regulators.
  • Collecting the regulators each element is subject to
  • Handling selection.
  • Creating interface components.

This simplifies code throughout the application by reducing the need to drag around context. A function that used to take an element storage key and a collection of elements as arguments can now just take a pointer to an element.

Implementation

Element and regulator collections

On the branch to be merged, an assembly's elements and regulators are stored in non-keyed collections. I chose B-tree sets, because I've read that they provide decent speed with low memory overhead as long as the collections don't get too large [1][2]. Since the branch to be merged already changes the type of the element and regulator collections, I took the opportunity to standardize on B-trees for other collections too, rather than using a mix of those and Fx hash collections like we do on the main branch.

Serial numbers

Rust pointers don't seem to be designed for use as identifiers, so the serial number system from the main branch still plays a useful role on the branch to be merged. The serial numbering code is moved into the Serial trait, where it can provide serial numbers for both elements and regulators.

Rust version

The branch to be merged sets a Rust version in Cargo.toml, because it uses the trait object upcasting feature that was stabilized in the recently released Rust 1.86. Call rustup update to update your toolchain.

## Summary The branch to be merged uses reference-counted pointers, rather than storage keys, to refer to elements and regulators in tasks like these: - Specifying the subjects of regulators. - Collecting the regulators each element is subject to - Handling selection. - Creating interface components. This simplifies code throughout the application by reducing the need to drag around context. A function that used to take an element storage key and a collection of elements as arguments can now just take a pointer to an element. ## Implementation ### Element and regulator collections On the branch to be merged, an assembly's elements and regulators are stored in non-keyed collections. I chose B-tree sets, because I've read that they provide decent speed with low memory overhead as long as the collections don't get too large [[1](https://users.rust-lang.org/t/hashmap-vs-btreemap/13804)][[2](https://www.reddit.com/r/rust/comments/7rgowj/hashmap_vs_btreemap/)]. Since the branch to be merged already changes the type of the element and regulator collections, I took the opportunity to standardize on B-trees for other collections too, rather than using a mix of those and Fx hash collections like we do on the main branch. ### Serial numbers Rust pointers [don't seem to be designed](https://stackoverflow.com/a/72149089) for use as identifiers, so the serial number system from the main branch still plays a useful role on the branch to be merged. The serial numbering code is moved into the `Serial` trait, where it can provide serial numbers for both elements and regulators. ### Rust version The branch to be merged sets a [Rust version](https://doc.rust-lang.org/cargo/reference/rust-version.html) in `Cargo.toml`, because it uses the trait object upcasting feature that was stabilized in the recently released [Rust 1.86](https://releases.rs/docs/1.86.0/). Call `rustup update` to update your toolchain.
Vectornaut added 9 commits 2025-05-06 08:23:29 +00:00
This gets rid of duplicated code.
Rust pointers don't seem to be designed for use as identifiers, so it's
probably more idiomatic and possibly more reliable to manage our own
unique identifier system.

  https://stackoverflow.com/a/72149089

This also lets us get rid of the `ElementRc` newtype.
Use reference-counted pointers, rather than collection keys, to refer to
elements in tasks like specifying the subjects of regulators, handling
selection, and creating interface components.
Using pointers to refer to elements reduces the need to drag context
around.
In the process, move the code that used to handle serial numbering for
elements into the `Serial` trait, where it can provide serial numbers
for regulators too.
Since we're no longer using storage keys to refer to elements and
regulators, we don't need to store these items in keyed collections
anymore.

To keep element and regulator pointers in `BTreeSet` collections, we
implement `Ord` for `Serial` trait objects. As a bonus, this lets us
turn the element-wise regulator collections back into `BTreeSet`.
This removes a dependency. Since the collections in question should
usually be pretty small, it might also reduce memory overhead at little
cost in speed. Here are some relevant performance discussions:

  https://users.rust-lang.org/t/hashmap-vs-btreemap/13804
  https://www.reddit.com/r/rust/comments/7rgowj/hashmap_vs_btreemap/
Update assembly tests to use pointers
Some checks failed
/ test (pull_request) Failing after 13s
3dd6303e99
Vectornaut added 1 commit 2025-05-06 17:27:13 +00:00
Update continuous integration image to Rust 1.86
All checks were successful
/ test (pull_request) Successful in 3m12s
f9ff1c0f43
Author
Member

Tests pass now that I've updated the continuous integration container image to Rust 1.86!

Tests pass now that I've updated the continuous integration container image to Rust 1.86!
Owner

Indeed, works on my system, and tests pass on my system as well. Merging.

Indeed, works on my system, and tests pass on my system as well. Merging.
glen merged commit 2adf4669f4 into main 2025-05-06 19:17:31 +00:00
Sign in to join this conversation.
No description provided.