Skip to content

RFC: Switch NodeId from NonZeroU128 to u64 #275

@mwcampbell

Description

@mwcampbell

This is currently a request for comments; I haven't made a final decision to do this. But I'm opening it as an issue because, if we move forward with it, it will be actionable. And I want to make sure this gets resolved one way or the other.

I'm thinking of switching the underlying type for AccessKit node IDs from NonZeroU128 to u64. The primary reason is that most type systems, for both programming languages and statically typed serialization formats, don't have a native type for an unsigned 128-bit integer. The need to have a struct for a node ID is one thing that makes the C API cumbersome, and the same concern applies to the work-in-progress Java API.

The original reason for switching from NonZeroU64 to NonZeroU128 last year was to allow a node ID to be constructed from an unsigned 64-bit integer that might be zero, such as a Rust hash code, without any risk of either losing data or breaking the "non-zero" requirement. This is an important concern, which is why I didn't hesitate to make the switch. But I've since reconsidered whether we really need to require that the node ID be non-zero. The original reason for that requirement was to optimize the size of Option<NodeId> in Rust. But with the node structure refactor that we introduced earlier this year, we no longer need to store many Option<NodeId> fields. So now I'm OK with using a plain u64.

My only concern at this point is that this change will interfere with the way slint's AccessKit integration currently composes a node ID from a component ID plus an index of an item within the component. The item index is currently a usize, which is 64-bit on modern general-purpose machines, meaning the node ID has to be more than 64-bit. One option would be to specify that the item index must be a u32, as it already is on some machines that slint targets (specifically, microcontrollers). Another solution would be for slint's AccessKit integration to maintain a complete mapping between items and node IDs. A final option I'm considering is some kind of subtree support, where each subtree has a node ID within the parent tree, and each subtree has its own node ID space. The problem that immediately comes to mind with that solution is that, with the current schema, there wouldn't be a way for a node in one subtree to refer to a node in a different subtree, such as when a control and its label are in different subtrees.

What we have right now works, but it's arguably a wart in the current design, particularly when considering FFI and serialization. We need to address all known warts as we move toward stabilization.

cc @raphlinus @wtholliday @tronical

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions