From 8f08dcd4eff149ac9d05106bae7cadda5628580d Mon Sep 17 00:00:00 2001 From: Masahiro Honma Date: Tue, 4 Jun 2024 08:05:45 +0900 Subject: [PATCH 1/3] feat: use AssetWriter for dynamic asset paths --- src/lib.rs | 3 --- src/systems.rs | 28 +++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3a23fa9..76e98bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,9 +67,6 @@ impl SlippyTilesSettings { /// Used to initialize slippy tile settings without using default values. /// Will also create the tiles directory immediately. pub fn new(endpoint: &str, tiles_directory: &str) -> SlippyTilesSettings { - // Need to ensure tiles folder exists. - std::fs::create_dir_all(format!("assets/{tiles_directory}")).unwrap(); - SlippyTilesSettings { endpoint: endpoint.to_owned(), tiles_directory: PathBuf::from(tiles_directory), diff --git a/src/systems.rs b/src/systems.rs index f925f95..6454023 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -1,4 +1,5 @@ use bevy::{ + asset::{io::AssetSourceId, AssetServer, AsyncWriteExt as _}, ecs::event::EventReader, prelude::{debug, EventWriter, Res, ResMut}, tasks::{futures_lite::future, IoTaskPool, Task}, @@ -18,6 +19,7 @@ pub fn download_slippy_tiles( slippy_tiles_settings: Res, mut slippy_tile_download_status: ResMut, mut slippy_tile_download_tasks: ResMut, + asset_server: Res, ) { for download_slippy_tile in download_slippy_tile_events.read() { let radius = download_slippy_tile.radius.0; @@ -32,6 +34,7 @@ pub fn download_slippy_tiles( &slippy_tiles_settings, &mut slippy_tile_download_tasks, &mut slippy_tile_download_status, + &asset_server, ); } } @@ -45,6 +48,7 @@ fn handle_download_slippy_tile_event( slippy_tiles_settings: &Res, slippy_tile_download_tasks: &mut ResMut, slippy_tile_download_status: &mut ResMut, + asset_server: &AssetServer, ) { let spc = SlippyTileCoordinates { x, y }; let tiles_directory = slippy_tiles_settings.get_tiles_directory_string(); @@ -83,6 +87,7 @@ fn handle_download_slippy_tile_event( filename, slippy_tile_download_tasks, slippy_tile_download_status, + asset_server, ); }, // Cache can be used and we have the file on disk. @@ -122,8 +127,16 @@ fn download_and_track_slippy_tile( filename: String, slippy_tile_download_tasks: &mut ResMut, slippy_tile_download_status: &mut ResMut, + asset_server: &AssetServer, ) { - let task = download_slippy_tile(spc, zoom_level, tile_size, endpoint, filename.clone()); + let task = download_slippy_tile( + spc, + zoom_level, + tile_size, + endpoint, + filename.clone(), + asset_server, + ); slippy_tile_download_tasks.insert(spc.x, spc.y, zoom_level, tile_size, task); slippy_tile_download_status.insert_with_coords( spc, @@ -140,13 +153,14 @@ fn download_slippy_tile( tile_size: TileSize, endpoint: String, filename: String, + asset_server: &AssetServer, ) -> Task { debug!( "Fetching map tile at position {:?} with zoom level {:?} from {:?}", spc, zoom_level, endpoint ); let tile_url = get_tile_url(endpoint, tile_size, zoom_level, spc.x, spc.y); - spawn_slippy_tile_download_task(tile_url, filename) + spawn_slippy_tile_download_task(tile_url, filename, asset_server) } fn get_tile_url( @@ -169,8 +183,10 @@ fn get_tile_url( fn spawn_slippy_tile_download_task( tile_url: String, filename: String, + asset_server: &AssetServer, ) -> Task { let thread_pool = IoTaskPool::get(); + let asset_server = asset_server.clone(); thread_pool.spawn(async move { let request = ehttp::Request { method: "GET".to_owned(), @@ -181,9 +197,11 @@ fn spawn_slippy_tile_download_task( let response = ehttp::fetch_async(request) .await .expect("Failed to fetch tile image"); - let mut content = std::io::Cursor::new(response.bytes); - let mut file_out = std::fs::File::create(format!("assets/{filename}")).unwrap(); - std::io::copy(&mut content, &mut file_out).unwrap(); + let asset_source = asset_server.get_source(AssetSourceId::Default).unwrap(); + let asset_writer = asset_source.writer().unwrap(); + let mut writer = asset_writer.write(Path::new(&filename)).await.unwrap(); + writer.write_all(&response.bytes).await.unwrap(); + writer.close().await.unwrap(); SlippyTileDownloadTaskResult { path: Path::new(&filename).to_path_buf(), } From b1949f8b8c271b09ea434909397788c15d4f6cc3 Mon Sep 17 00:00:00 2001 From: Masahiro Honma Date: Tue, 4 Jun 2024 08:25:32 +0900 Subject: [PATCH 2/3] feat: use AssetReader for dynamic asset paths --- src/systems.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/systems.rs b/src/systems.rs index 6454023..cf1ccf3 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -1,5 +1,8 @@ use bevy::{ - asset::{io::AssetSourceId, AssetServer, AsyncWriteExt as _}, + asset::{ + io::{AssetReaderError, AssetSourceId}, + AssetServer, AsyncWriteExt as _, + }, ecs::event::EventReader, prelude::{debug, EventWriter, Res, ResMut}, tasks::{futures_lite::future, IoTaskPool, Task}, @@ -64,7 +67,7 @@ fn handle_download_slippy_tile_event( download_slippy_tile_event.zoom_level, download_slippy_tile_event.tile_size, ); - let file_exists = std::path::Path::new(&format!("assets/{filename}")).exists(); + let file_exists = future::block_on(does_file_exist(asset_server, &filename)); match ( UseCache::new(download_slippy_tile_event.use_cache), AlreadyDownloaded::new(already_downloaded), @@ -119,6 +122,16 @@ fn get_tile_filename( ) } +async fn does_file_exist(asset_server: &AssetServer, filename: &str) -> bool { + let asset_source = asset_server.get_source(AssetSourceId::Default).unwrap(); + let asset_reader = asset_source.reader(); + match asset_reader.read(Path::new(filename)).await { + Ok(_) => true, + Err(AssetReaderError::NotFound(_)) => false, + Err(err) => panic!("failed to check if the file {} exists: {:?}", filename, err), + } +} + fn download_and_track_slippy_tile( spc: SlippyTileCoordinates, zoom_level: ZoomLevel, From 8407c50879f46fe7320d53b2c1fb9a43ea16387b Mon Sep 17 00:00:00 2001 From: Masahiro Honma Date: Tue, 4 Jun 2024 10:40:17 +0900 Subject: [PATCH 3/3] chore: suppress clippy warning for "too many arguments" --- src/systems.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/systems.rs b/src/systems.rs index cf1ccf3..8d5863e 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -132,6 +132,7 @@ async fn does_file_exist(asset_server: &AssetServer, filename: &str) -> bool { } } +#[allow(clippy::too_many_arguments)] fn download_and_track_slippy_tile( spc: SlippyTileCoordinates, zoom_level: ZoomLevel,