Skip to content

Commit 759aa2c

Browse files
committed
Fix the processor init deleting directories while it's walking the paths.
1 parent d61134a commit 759aa2c

File tree

1 file changed

+18
-9
lines changed
  • crates/bevy_asset/src/processor

1 file changed

+18
-9
lines changed

crates/bevy_asset/src/processor/mod.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ pub use process::*;
4646
use crate::{
4747
io::{
4848
AssetReaderError, AssetSource, AssetSourceBuilders, AssetSourceEvent, AssetSourceId,
49-
AssetSources, AssetWriterError, ErasedAssetReader, ErasedAssetWriter,
50-
MissingAssetSourceError,
49+
AssetSources, AssetWriterError, ErasedAssetReader, MissingAssetSourceError,
5150
},
5251
meta::{
5352
get_asset_hash, get_full_asset_hash, AssetAction, AssetActionMinimal, AssetHash, AssetMeta,
@@ -746,9 +745,9 @@ impl AssetProcessor {
746745
/// folders when they are discovered.
747746
async fn get_asset_paths(
748747
reader: &dyn ErasedAssetReader,
749-
clean_empty_folders_writer: Option<&dyn ErasedAssetWriter>,
750748
path: PathBuf,
751749
paths: &mut Vec<PathBuf>,
750+
mut empty_dirs: Option<&mut Vec<PathBuf>>,
752751
) -> Result<bool, AssetReaderError> {
753752
if reader.is_directory(&path).await? {
754753
let mut path_stream = reader.read_directory(&path).await?;
@@ -757,18 +756,19 @@ impl AssetProcessor {
757756
while let Some(child_path) = path_stream.next().await {
758757
contains_files |= Box::pin(get_asset_paths(
759758
reader,
760-
clean_empty_folders_writer,
761759
child_path,
762760
paths,
761+
empty_dirs.as_deref_mut(),
763762
))
764763
.await?;
765764
}
765+
// Add the current directory after all its subdirectories so we delete any empty
766+
// subdirectories before the current directory.
766767
if !contains_files
767768
&& path.parent().is_some()
768-
&& let Some(writer) = clean_empty_folders_writer
769+
&& let Some(empty_dirs) = empty_dirs.as_deref_mut()
769770
{
770-
// it is ok for this to fail as it is just a cleanup job.
771-
let _ = writer.remove_empty_directory(&path).await;
771+
empty_dirs.push(path);
772772
}
773773
Ok(contains_files)
774774
} else {
@@ -787,23 +787,32 @@ impl AssetProcessor {
787787
let mut unprocessed_paths = Vec::new();
788788
get_asset_paths(
789789
source.reader(),
790-
None,
791790
PathBuf::from(""),
792791
&mut unprocessed_paths,
792+
None,
793793
)
794794
.await
795795
.map_err(InitializeError::FailedToReadSourcePaths)?;
796796

797797
let mut processed_paths = Vec::new();
798+
let mut empty_dirs = Vec::new();
798799
get_asset_paths(
799800
processed_reader,
800-
Some(processed_writer),
801801
PathBuf::from(""),
802802
&mut processed_paths,
803+
Some(&mut empty_dirs),
803804
)
804805
.await
805806
.map_err(InitializeError::FailedToReadDestinationPaths)?;
806807

808+
// Remove any empty directories from the processed path. Note: this has to happen after
809+
// we fetch all the paths, otherwise the path stream can skip over paths
810+
// (we're modifying a collection while iterating through it).
811+
for empty_dir in empty_dirs {
812+
// We don't care if this succeeds, since it's just a cleanup task. It is best-effort
813+
let _ = processed_writer.remove_empty_directory(&empty_dir).await;
814+
}
815+
807816
for path in unprocessed_paths {
808817
asset_infos.get_or_insert(AssetPath::from(path).with_source(source.id()));
809818
}

0 commit comments

Comments
 (0)