-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add directory related functions to AndroidAssetReader
#11495
Add directory related functions to AndroidAssetReader
#11495
Conversation
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
Co-authored-by: Kanabenki <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@esensar seems like I can't resolve the remaining threads from my previous review for some reason, but you should be able to.
Co-authored-by: François Mockers <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested it myself but given the constraints the code seems reasonable.
@mockersf Is this alright to merge? Sorry, I haven't checked it in a while and I saw this is still open today. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't test, but the code seems fine
@esensar thanks for the ping! sorry I let this PR slip through. The android build is failing, but should be an easy fix (just avoiding shadowing a variable, as in my suggestion) |
.get() | ||
.expect("Bevy must be setup with the #[bevy_main] macro on Android") | ||
.asset_manager(); | ||
// HACK: `AssetManager` does not provide a way to check if path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough
.filter_map(move |f| { | ||
let file_path = path.join(Path::new(f.to_str().unwrap())); | ||
// filter out meta files as they are not considered assets | ||
if let Some(ext) = file_path.extension().and_then(|e| e.to_str()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.as_asset_file()
or something could probably be its own function since that seems useful to have generally speaking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but I think it might be better to just extract out the "meta" file detection and filtering. I am worried that something like .as_asset_file()
might be confusing (since it would take a file path and then either return Some
or None
, depending on this condition - and that Some
value would be the original value unchanged).
Do you think that would make sense?
Ok(stream) | ||
let asset_manager = bevy_winit::ANDROID_APP | ||
.get() | ||
.expect("Bevy must be setup with the #[bevy_main] macro on Android") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add this expectation to the documentation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a message that is also used in bevy_winit
, so it is just reused here. I agree it would be good to add to the docs. I can add it separately to the android
page in the book (which is currently hidden, but I guess it is good to have it there so it is not forgotten once it gets published).
…1495) # Objective - Fixes bevyengine#9968 ## Solution - Uses [open_dir](https://docs.rs/ndk/latest/ndk/asset/struct.AssetManager.html#method.open_dir) to read directories and collects child list, since it can't be shared across threads. - For `is_directory`, uses result of [open](https://docs.rs/ndk/latest/ndk/asset/struct.AssetManager.html#method.open), which will fail for directories. I tried using the result of `open_dir` for this, but it was successful for files too, which made loading folders return empty lists, since `open_dir` was successful and treated all files as empty directories. - Ignoring `meta` files was copied from filesystem implementation --- ## Changelog - Fixed: Android's AssetReader implementation now supports read_directory and is_directory. ## Notes I noticed late that there was the bevyengine#9968 issue (I only noticed bevyengine#9591), so I have also missed that a PR was already open (bevyengine#9969). Feel free to copy over the fixes from this one over there. The only difference I notice between these 2, is that I have used `open` instead of `open_dir` for `is_directory` implementation. I have tried with `open_dir` too, but unfortunately that didn't work. I tested this on an actual device, using the mobile example, by making some minor changes: ```rust #[derive(Resource)] struct FolderAssets(Handle<LoadedFolder>); // the `bevy_main` proc_macro generates the required boilerplate for iOS and Android #[bevy_main] fn main() { // ... .add_systems(Startup, (setup_scene, load_music_files)) .add_systems( Update, // Removed the handle_lifetime since AudioBundle is added later (touch_camera, button_handler, setup_music), ); // ... } fn load_music_files(asset_server: Res<AssetServer>, mut commands: Commands) { let sounds = asset_server.load_folder("sounds"); commands.insert_resource(FolderAssets(sounds)); } fn setup_music( mut commands: Commands, folders: Res<Assets<LoadedFolder>>, mut loaded_event: EventReader<AssetEvent<LoadedFolder>>, ) { for event in loaded_event.read() { if let AssetEvent::LoadedWithDependencies { id } = event { if let Some(folder) = folders.get(*id) { warn!("Folder items: {:?}", folder.handles); if let Some(source) = folder.handles.first() { commands.spawn(AudioBundle { source: source.clone().typed::<AudioSource>(), settings: PlaybackSettings::LOOP, }); } } } } } ``` --------- Co-authored-by: Kanabenki <[email protected]> Co-authored-by: François Mockers <[email protected]>
Objective
Solution
is_directory
, uses result of open, which will fail for directories. I tried using the result ofopen_dir
for this, but it was successful for files too, which made loading folders return empty lists, sinceopen_dir
was successful and treated all files as empty directories.meta
files was copied from filesystem implementationChangelog
Notes
I noticed late that there was the #9968 issue (I only noticed #9591), so I have also missed that a PR was already open (#9969). Feel free to copy over the fixes from this one over there.
The only difference I notice between these 2, is that I have used
open
instead ofopen_dir
foris_directory
implementation. I have tried withopen_dir
too, but unfortunately that didn't work. I tested this on an actual device, using the mobile example, by making some minor changes: