Skip to content

Commit 611ba8b

Browse files
authored
Add AsyncSeekForwardExt trait to allows a similar API to the previous Bevy version (bevyengine#16027)
# Objective This PR introduces an `AsyncSeekForwardExt` trait, which I forgot in my previous PR bevyengine#14194. This new trait is analogous to `AsyncSeekExt` and allows all implementors of `AsyncSeekForward` to directly use the `seek_forward` function in async contexts. ## Solution - Implement a new `AsyncSeekForwardExt` trait - Automatically implement this trait for all types that implement `AsyncSeekForward` ## Showcase This new trait allows a similar API to the previous Bevy version: ```rust #[derive(Default)] struct UniverseLoader; #[derive(Asset, TypePath, Debug)] struct JustALilAsteroid([u8; 128]); impl AssetLoader for UniverseLoader { type Asset = JustALilAsteroid; type Settings = (); type Error = std::io::Error; async fn load<'a>( &'a self, reader: &'a mut Reader<'a>, _settings: &'a Self::Settings, _context: &'a mut LoadContext<'_>, ) -> Result<Self::Asset, Self::Error> { // read the asteroids entry table let entry_offset: u64 = /* ... */; let current_offset: u64 = reader.seek_forward(0).await?; // jump to the entry reader.seek_forward(entry_offset - current_offset).await?; let mut asteroid_buf = [0; 128]; reader.read_exact(&mut asteroid_buf).await?; Ok(JustALilAsteroid(asteroid_buf)) } fn extensions(&self) -> &[&str] { &["celestial"] } } ```
1 parent c6a66a7 commit 611ba8b

File tree

1 file changed

+35
-0
lines changed
  • crates/bevy_asset/src/io

1 file changed

+35
-0
lines changed

crates/bevy_asset/src/io/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub use source::*;
2323

2424
use alloc::sync::Arc;
2525
use bevy_utils::{BoxedFuture, ConditionalSendFuture};
26+
use core::future::Future;
2627
use core::{
2728
mem::size_of,
2829
pin::Pin,
@@ -120,6 +121,40 @@ impl<T: ?Sized + AsyncSeekForward + Unpin> AsyncSeekForward for Box<T> {
120121
}
121122
}
122123

124+
/// Extension trait for [`AsyncSeekForward`].
125+
pub trait AsyncSeekForwardExt: AsyncSeekForward {
126+
/// Seek by the provided `offset` in the forwards direction, using the [`AsyncSeekForward`] trait.
127+
fn seek_forward(&mut self, offset: u64) -> SeekForwardFuture<'_, Self>
128+
where
129+
Self: Unpin,
130+
{
131+
SeekForwardFuture {
132+
seeker: self,
133+
offset,
134+
}
135+
}
136+
}
137+
138+
impl<R: AsyncSeekForward + ?Sized> AsyncSeekForwardExt for R {}
139+
140+
#[derive(Debug)]
141+
#[must_use = "futures do nothing unless you `.await` or poll them"]
142+
pub struct SeekForwardFuture<'a, S: Unpin + ?Sized> {
143+
seeker: &'a mut S,
144+
offset: u64,
145+
}
146+
147+
impl<S: Unpin + ?Sized> Unpin for SeekForwardFuture<'_, S> {}
148+
149+
impl<S: AsyncSeekForward + Unpin + ?Sized> Future for SeekForwardFuture<'_, S> {
150+
type Output = futures_lite::io::Result<u64>;
151+
152+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
153+
let offset = self.offset;
154+
Pin::new(&mut *self.seeker).poll_seek_forward(cx, offset)
155+
}
156+
}
157+
123158
/// A type returned from [`AssetReader::read`], which is used to read the contents of a file
124159
/// (or virtual file) corresponding to an asset.
125160
///

0 commit comments

Comments
 (0)