Async loading wrapper
FutureAssetFetch
allows to asynchronously load requested bytes in async/await
futures. It's similar to DeferredAssetFetch
, although it expects provided
custom async function that will handle loading asset bytes with custom
async/await compatible libraries like tokio
.
use anput::bundle::DynamicBundle;
use keket::{
database::{AssetDatabase, path::AssetPathStatic},
fetch::{AssetBytesAreReadyToProcess, future::FutureAssetFetch},
protocol::bytes::BytesAssetProtocol,
};
use std::{error::Error, path::PathBuf};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut database = AssetDatabase::default()
.with_protocol(BytesAssetProtocol)
// Future asset fetch uses async function to handle providing
// asset bytes asynchronously with async/await.
.with_fetch(FutureAssetFetch::new(tokio_load_file_bundle));
let package = database.ensure("bytes://package.zip")?;
// Run maintain passes to load and process loaded bytes.
while !package.is_ready_to_use(&database) {
database.maintain()?;
tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
}
println!(
"Package byte size: {}",
package.access::<&Vec<u8>>(&database).len()
);
Ok(())
}
async fn tokio_load_file_bundle(path: AssetPathStatic) -> Result<DynamicBundle, Box<dyn Error>> {
let file_path = PathBuf::from("resources").join(path.path());
let bytes = tokio::fs::read(&file_path).await?;
let mut bundle = DynamicBundle::default();
bundle
.add_component(AssetBytesAreReadyToProcess(bytes))
.map_err(|_| format!("Failed to add bytes to bundle for asset: {path}"))?;
Ok(bundle)
}
And here is async function that handles loading bytes with tokio
:
use anput::bundle::DynamicBundle;
use keket::{
database::{AssetDatabase, path::AssetPathStatic},
fetch::{AssetBytesAreReadyToProcess, future::FutureAssetFetch},
protocol::bytes::BytesAssetProtocol,
};
use std::{error::Error, path::PathBuf};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut database = AssetDatabase::default()
.with_protocol(BytesAssetProtocol)
// Future asset fetch uses async function to handle providing
// asset bytes asynchronously with async/await.
.with_fetch(FutureAssetFetch::new(tokio_load_file_bundle));
let package = database.ensure("bytes://package.zip")?;
// Run maintain passes to load and process loaded bytes.
while !package.is_ready_to_use(&database) {
database.maintain()?;
tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
}
println!(
"Package byte size: {}",
package.access::<&Vec<u8>>(&database).len()
);
Ok(())
}
async fn tokio_load_file_bundle(path: AssetPathStatic) -> Result<DynamicBundle, Box<dyn Error>> {
let file_path = PathBuf::from("resources").join(path.path());
let bytes = tokio::fs::read(&file_path).await?;
let mut bundle = DynamicBundle::default();
bundle
.add_component(AssetBytesAreReadyToProcess(bytes))
.map_err(|_| format!("Failed to add bytes to bundle for asset: {path}"))?;
Ok(bundle)
}