Skip to content

Commit

Permalink
Add to_bits and from_bits functions to AssetIndex (bevyengine#12127)
Browse files Browse the repository at this point in the history
# Objective

The `AssetIndex` cannot be carried across boundaries that do not allow
explicit rust types.

For context, I ran into this issue while trying to implent an
improvement for bevy_egui which leverages the not-so-new custom loader
API. Passing through a handle directly isn't possible, but instead it
requires stringified URI s. I had to work around the lack of this API s
existance using reflection, which is rather dirty.

## Solution

- Add `to_bits` and `from_bits` functions to `AssetIndex` to allow
moving this type through such boundaries.

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
  • Loading branch information
TheRawMeatball and rparrett authored Feb 26, 2024
1 parent 881f660 commit 3bdeac6
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions crates/bevy_asset/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ pub struct AssetIndex {
pub(crate) index: u32,
}

impl AssetIndex {
/// Convert the [`AssetIndex`] into an opaque blob of bits to transport it in circumstances where carrying a strongly typed index isn't possible.
///
/// The result of this function should not be relied upon for anything except putting it back into [`AssetIndex::from_bits`] to recover the index.
pub fn to_bits(self) -> u64 {
let Self { generation, index } = self;
((generation as u64) << 32) | index as u64
}
/// Convert an opaque `u64` acquired from [`AssetIndex::to_bits`] back into an [`AssetIndex`]. This should not be used with any inputs other than those
/// derived from [`AssetIndex::to_bits`], as there are no guarantees for what will happen with such inputs.
pub fn from_bits(bits: u64) -> Self {
let index = ((bits << 32) >> 32) as u32;
let generation = (bits >> 32) as u32;
Self { generation, index }
}
}

/// Allocates generational [`AssetIndex`] values and facilitates their reuse.
pub(crate) struct AssetIndexAllocator {
/// A monotonically increasing index.
Expand Down Expand Up @@ -620,3 +637,18 @@ pub struct InvalidGenerationError {
index: AssetIndex,
current_generation: u32,
}

#[cfg(test)]
mod test {
use crate::AssetIndex;

#[test]
fn asset_index_round_trip() {
let asset_index = AssetIndex {
generation: 42,
index: 1337,
};
let roundtripped = AssetIndex::from_bits(asset_index.to_bits());
assert_eq!(asset_index, roundtripped);
}
}

0 comments on commit 3bdeac6

Please sign in to comment.