Add AsyncSeekForwardExt trait to allows a similar API to the previous Bevy version (#16027)
				
					
				
			# Objective This PR introduces an `AsyncSeekForwardExt` trait, which I forgot in my previous PR #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"] } } ```
This commit is contained in:
		
							parent
							
								
									c6a66a7e96
								
							
						
					
					
						commit
						611ba8b98e
					
				| @ -23,6 +23,7 @@ pub use source::*; | |||||||
| 
 | 
 | ||||||
| use alloc::sync::Arc; | use alloc::sync::Arc; | ||||||
| use bevy_utils::{BoxedFuture, ConditionalSendFuture}; | use bevy_utils::{BoxedFuture, ConditionalSendFuture}; | ||||||
|  | use core::future::Future; | ||||||
| use core::{ | use core::{ | ||||||
|     mem::size_of, |     mem::size_of, | ||||||
|     pin::Pin, |     pin::Pin, | ||||||
| @ -120,6 +121,40 @@ impl<T: ?Sized + AsyncSeekForward + Unpin> AsyncSeekForward for Box<T> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /// Extension trait for [`AsyncSeekForward`].
 | ||||||
|  | pub trait AsyncSeekForwardExt: AsyncSeekForward { | ||||||
|  |     /// Seek by the provided `offset` in the forwards direction, using the [`AsyncSeekForward`] trait.
 | ||||||
|  |     fn seek_forward(&mut self, offset: u64) -> SeekForwardFuture<'_, Self> | ||||||
|  |     where | ||||||
|  |         Self: Unpin, | ||||||
|  |     { | ||||||
|  |         SeekForwardFuture { | ||||||
|  |             seeker: self, | ||||||
|  |             offset, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<R: AsyncSeekForward + ?Sized> AsyncSeekForwardExt for R {} | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | #[must_use = "futures do nothing unless you `.await` or poll them"] | ||||||
|  | pub struct SeekForwardFuture<'a, S: Unpin + ?Sized> { | ||||||
|  |     seeker: &'a mut S, | ||||||
|  |     offset: u64, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<S: Unpin + ?Sized> Unpin for SeekForwardFuture<'_, S> {} | ||||||
|  | 
 | ||||||
|  | impl<S: AsyncSeekForward + Unpin + ?Sized> Future for SeekForwardFuture<'_, S> { | ||||||
|  |     type Output = futures_lite::io::Result<u64>; | ||||||
|  | 
 | ||||||
|  |     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||||||
|  |         let offset = self.offset; | ||||||
|  |         Pin::new(&mut *self.seeker).poll_seek_forward(cx, offset) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// A type returned from [`AssetReader::read`], which is used to read the contents of a file
 | /// A type returned from [`AssetReader::read`], which is used to read the contents of a file
 | ||||||
| /// (or virtual file) corresponding to an asset.
 | /// (or virtual file) corresponding to an asset.
 | ||||||
| ///
 | ///
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Ludwig DUBOS
						Ludwig DUBOS