@@ -46,8 +46,7 @@ pub use process::*;
4646use 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