@@ -7,10 +7,8 @@ use alloc::{
77 vec:: Vec ,
88} ;
99use async_lock:: { RwLock , RwLockWriteGuard } ;
10- use bevy_platform:: {
11- collections:: HashMap ,
12- sync:: { Mutex , PoisonError } ,
13- } ;
10+ use atomicow:: CowArc ;
11+ use bevy_platform:: sync:: { Mutex , PoisonError } ;
1412use bevy_reflect:: TypePath ;
1513use core:: marker:: PhantomData ;
1614use futures_lite:: AsyncWriteExt ;
@@ -25,8 +23,8 @@ use bevy_tasks::BoxedFuture;
2523use crate :: {
2624 io:: {
2725 memory:: { Dir , MemoryAssetReader , MemoryAssetWriter } ,
28- AssetReader , AssetReaderError , AssetSourceBuilder , AssetSourceEvent , AssetSourceId ,
29- AssetWatcher , PathStream , Reader ,
26+ AssetReader , AssetReaderError , AssetSourceBuilder , AssetSourceEvent , AssetWatcher ,
27+ PathStream , Reader ,
3028 } ,
3129 processor:: {
3230 AssetProcessor , LoadTransformAndSave , LogEntry , ProcessorState , ProcessorTransactionLog ,
@@ -35,7 +33,8 @@ use crate::{
3533 saver:: AssetSaver ,
3634 tests:: { run_app_until, CoolText , CoolTextLoader , CoolTextRon , SubText } ,
3735 transformer:: { AssetTransformer , TransformedAsset } ,
38- Asset , AssetApp , AssetLoader , AssetMode , AssetPath , AssetPlugin , LoadContext ,
36+ Asset , AssetApp , AssetLoader , AssetMode , AssetPath , AssetPlugin , DefaultAssetSource ,
37+ LoadContext ,
3938} ;
4039
4140#[ derive( Clone ) ]
@@ -49,7 +48,6 @@ struct AppWithProcessor {
4948 app : App ,
5049 source_gate : Arc < RwLock < ( ) > > ,
5150 default_source_dirs : ProcessingDirs ,
52- extra_sources_dirs : HashMap < String , ProcessingDirs > ,
5351}
5452
5553/// Similar to [`crate::io::gated::GatedReader`], but uses a lock instead of a channel to avoid
@@ -107,94 +105,83 @@ fn serialize_as_cool_text(text: &str) -> String {
107105 ron:: ser:: to_string_pretty ( & cool_text_ron, PrettyConfig :: new ( ) . new_line ( "\n " ) ) . unwrap ( )
108106}
109107
110- fn create_app_with_asset_processor ( extra_sources : & [ String ] ) -> AppWithProcessor {
111- let mut app = App :: new ( ) ;
112- let source_gate = Arc :: new ( RwLock :: new ( ( ) ) ) ;
113-
114- struct UnfinishedProcessingDirs {
115- source : Dir ,
116- processed : Dir ,
117- // The receiver channel for the source event sender for the unprocessed source.
118- source_event_sender_receiver :
119- async_channel:: Receiver < async_channel:: Sender < AssetSourceEvent > > ,
120- }
108+ /// The processing dirs that need to be "finished" before being used.
109+ struct UnfinishedProcessingDirs {
110+ /// The directory of the source assets.
111+ source : Dir ,
112+ /// The directory of the processed assets.
113+ processed : Dir ,
114+ /// The receiver channel for the source event sender for the unprocessed source.
115+ source_event_sender_receiver : async_channel:: Receiver < async_channel:: Sender < AssetSourceEvent > > ,
116+ }
121117
122- impl UnfinishedProcessingDirs {
123- fn finish ( self ) -> ProcessingDirs {
124- ProcessingDirs {
125- source : self . source ,
126- processed : self . processed ,
127- // The processor listens for events on the source unconditionally, and we enable
128- // watching for the processed source, so both of these channels will be filled.
129- source_event_sender : self . source_event_sender_receiver . recv_blocking ( ) . unwrap ( ) ,
130- }
118+ impl UnfinishedProcessingDirs {
119+ /// Attempts to finish the source by fetching the source event sender.
120+ ///
121+ /// This will block if called before adding the source.
122+ fn finish ( self ) -> ProcessingDirs {
123+ ProcessingDirs {
124+ source : self . source ,
125+ processed : self . processed ,
126+ // The processor listens for events on the source unconditionally, and we enable
127+ // watching for the processed source, so both of these channels will be filled.
128+ source_event_sender : self . source_event_sender_receiver . recv_blocking ( ) . unwrap ( ) ,
131129 }
132130 }
131+ }
133132
134- fn create_source (
135- app : & mut App ,
136- source_id : AssetSourceId < ' static > ,
137- source_gate : Arc < RwLock < ( ) > > ,
138- ) -> UnfinishedProcessingDirs {
139- let source_dir = Dir :: default ( ) ;
140- let processed_dir = Dir :: default ( ) ;
133+ /// Creates a source, including its processed and unprocessed directories, gated on `source_gate`.
134+ fn create_source ( source_gate : Arc < RwLock < ( ) > > ) -> ( AssetSourceBuilder , UnfinishedProcessingDirs ) {
135+ let source_dir = Dir :: default ( ) ;
136+ let processed_dir = Dir :: default ( ) ;
141137
142- let source_memory_reader = LockGatedReader :: new (
143- source_gate,
144- MemoryAssetReader {
145- root : source_dir. clone ( ) ,
146- } ,
147- ) ;
148- let processed_memory_reader = MemoryAssetReader {
149- root : processed_dir. clone ( ) ,
150- } ;
151- let processed_memory_writer = MemoryAssetWriter {
152- root : processed_dir. clone ( ) ,
153- } ;
138+ let source_memory_reader = LockGatedReader :: new (
139+ source_gate,
140+ MemoryAssetReader {
141+ root : source_dir. clone ( ) ,
142+ } ,
143+ ) ;
144+ let processed_memory_reader = MemoryAssetReader {
145+ root : processed_dir. clone ( ) ,
146+ } ;
147+ let processed_memory_writer = MemoryAssetWriter {
148+ root : processed_dir. clone ( ) ,
149+ } ;
154150
155- let ( source_event_sender_sender, source_event_sender_receiver) = async_channel:: bounded ( 1 ) ;
151+ let ( source_event_sender_sender, source_event_sender_receiver) = async_channel:: bounded ( 1 ) ;
156152
157- struct FakeWatcher ;
153+ struct FakeWatcher ;
158154
159- impl AssetWatcher for FakeWatcher { }
155+ impl AssetWatcher for FakeWatcher { }
160156
161- app. register_asset_source (
162- source_id,
163- AssetSourceBuilder :: new ( move || Box :: new ( source_memory_reader. clone ( ) ) )
164- . with_watcher ( move |sender : async_channel:: Sender < AssetSourceEvent > | {
165- source_event_sender_sender. send_blocking ( sender) . unwrap ( ) ;
166- Some ( Box :: new ( FakeWatcher ) )
167- } )
168- . with_processed_reader ( move || Box :: new ( processed_memory_reader. clone ( ) ) )
169- . with_processed_writer ( move |_| Some ( Box :: new ( processed_memory_writer. clone ( ) ) ) ) ,
170- ) ;
157+ let source_builder = AssetSourceBuilder :: new ( move || Box :: new ( source_memory_reader. clone ( ) ) )
158+ . with_watcher ( move |sender : async_channel:: Sender < AssetSourceEvent > | {
159+ source_event_sender_sender. send_blocking ( sender) . unwrap ( ) ;
160+ Some ( Box :: new ( FakeWatcher ) )
161+ } )
162+ . with_processed_reader ( move || Box :: new ( processed_memory_reader. clone ( ) ) )
163+ . with_processed_writer ( move |_| Some ( Box :: new ( processed_memory_writer. clone ( ) ) ) ) ;
171164
165+ (
166+ source_builder,
172167 UnfinishedProcessingDirs {
173168 source : source_dir,
174169 processed : processed_dir,
175170 source_event_sender_receiver,
176- }
177- }
171+ } ,
172+ )
173+ }
178174
179- let default_source_dirs = create_source ( & mut app, AssetSourceId :: Default , source_gate. clone ( ) ) ;
180-
181- let extra_sources_dirs = extra_sources
182- . iter ( )
183- . map ( |source_name| {
184- (
185- source_name. clone ( ) ,
186- create_source (
187- & mut app,
188- AssetSourceId :: Name ( source_name. clone ( ) . into ( ) ) ,
189- source_gate. clone ( ) ,
190- ) ,
191- )
192- } )
193- . collect :: < Vec < _ > > ( ) ;
175+ fn create_app_with_asset_processor ( ) -> AppWithProcessor {
176+ let mut app = App :: new ( ) ;
177+ let source_gate = Arc :: new ( RwLock :: new ( ( ) ) ) ;
178+
179+ let ( default_source_builder, default_source_dirs) = create_source ( source_gate. clone ( ) ) ;
194180
195181 app. add_plugins ( (
196182 TaskPoolPlugin :: default ( ) ,
197183 AssetPlugin {
184+ default_source : DefaultAssetSource :: FromBuilder ( Mutex :: new ( default_source_builder) ) ,
198185 mode : AssetMode :: Processed ,
199186 use_asset_processor_override : Some ( true ) ,
200187 watch_for_changes_override : Some ( true ) ,
@@ -248,19 +235,25 @@ fn create_app_with_asset_processor(extra_sources: &[String]) -> AppWithProcessor
248235 . set_log_factory ( Box :: new ( FakeTransactionLogFactory ) )
249236 . unwrap ( ) ;
250237
251- // Now that we've built the app, finish all the processing dirs .
238+ // Now that we've built the app, finish the default dir, and return it .
252239
253240 AppWithProcessor {
254241 app,
255242 source_gate,
256243 default_source_dirs : default_source_dirs. finish ( ) ,
257- extra_sources_dirs : extra_sources_dirs
258- . into_iter ( )
259- . map ( |( name, dirs) | ( name, dirs. finish ( ) ) )
260- . collect ( ) ,
261244 }
262245}
263246
247+ fn register_new_source (
248+ app : & mut App ,
249+ name : impl Into < CowArc < ' static , str > > ,
250+ source_gate : Arc < RwLock < ( ) > > ,
251+ ) -> ProcessingDirs {
252+ let ( source, processing_dirs) = create_source ( source_gate) ;
253+ app. register_asset_source ( name. into ( ) , source) ;
254+ processing_dirs. finish ( )
255+ }
256+
264257fn run_app_until_finished_processing ( app : & mut App , guard : RwLockWriteGuard < ' _ , ( ) > ) {
265258 let processor = app. world ( ) . resource :: < AssetProcessor > ( ) . clone ( ) ;
266259 // We can't just wait for the processor state to be finished since we could have already
@@ -373,8 +366,7 @@ fn no_meta_or_default_processor_copies_asset() {
373366 processed : processed_dir,
374367 ..
375368 } ,
376- ..
377- } = create_app_with_asset_processor ( & [ ] ) ;
369+ } = create_app_with_asset_processor ( ) ;
378370
379371 let guard = source_gate. write_blocking ( ) ;
380372
@@ -406,8 +398,7 @@ fn asset_processor_transforms_asset_default_processor() {
406398 processed : processed_dir,
407399 ..
408400 } ,
409- ..
410- } = create_app_with_asset_processor ( & [ ] ) ;
401+ } = create_app_with_asset_processor ( ) ;
411402
412403 type CoolTextProcessor = LoadTransformAndSave <
413404 CoolTextLoader ,
@@ -460,8 +451,7 @@ fn asset_processor_transforms_asset_with_meta() {
460451 processed : processed_dir,
461452 ..
462453 } ,
463- ..
464- } = create_app_with_asset_processor ( & [ ] ) ;
454+ } = create_app_with_asset_processor ( ) ;
465455
466456 type CoolTextProcessor = LoadTransformAndSave <
467457 CoolTextLoader ,
@@ -657,8 +647,7 @@ fn asset_processor_loading_can_read_processed_assets() {
657647 processed : processed_dir,
658648 ..
659649 } ,
660- ..
661- } = create_app_with_asset_processor ( & [ ] ) ;
650+ } = create_app_with_asset_processor ( ) ;
662651
663652 // This processor loads a gltf file, converts it to BSN and then saves out the BSN.
664653 type GltfProcessor = LoadTransformAndSave < FakeGltfLoader , GltfToBsn , FakeBsnSaver > ;
@@ -731,8 +720,7 @@ fn asset_processor_loading_can_read_source_assets() {
731720 processed : processed_dir,
732721 ..
733722 } ,
734- ..
735- } = create_app_with_asset_processor ( & [ ] ) ;
723+ } = create_app_with_asset_processor ( ) ;
736724
737725 #[ derive( Serialize , Deserialize ) ]
738726 struct FakeGltfxData {
@@ -927,18 +915,18 @@ fn asset_processor_processes_all_sources() {
927915 processed : default_processed_dir,
928916 source_event_sender : default_source_events,
929917 } ,
930- extra_sources_dirs ,
931- } = create_app_with_asset_processor ( & [ "custom_1" . into ( ) , "custom_2" . into ( ) ] ) ;
918+ } = create_app_with_asset_processor ( ) ;
919+
932920 let ProcessingDirs {
933921 source : custom_1_source_dir,
934922 processed : custom_1_processed_dir,
935923 source_event_sender : custom_1_source_events,
936- } = extra_sources_dirs [ "custom_1" ] . clone ( ) ;
924+ } = register_new_source ( & mut app , "custom_1" , source_gate . clone ( ) ) ;
937925 let ProcessingDirs {
938926 source : custom_2_source_dir,
939927 processed : custom_2_processed_dir,
940928 source_event_sender : custom_2_source_events,
941- } = extra_sources_dirs [ "custom_2" ] . clone ( ) ;
929+ } = register_new_source ( & mut app , "custom_2" , source_gate . clone ( ) ) ;
942930
943931 type AddTextProcessor = LoadTransformAndSave <
944932 CoolTextLoader ,
@@ -1043,13 +1031,12 @@ fn nested_loads_of_processed_asset_reprocesses_on_reload() {
10431031 processed : default_processed_dir,
10441032 source_event_sender : default_source_events,
10451033 } ,
1046- extra_sources_dirs,
1047- } = create_app_with_asset_processor ( & [ "custom" . into ( ) ] ) ;
1034+ } = create_app_with_asset_processor ( ) ;
10481035 let ProcessingDirs {
10491036 source : custom_source_dir,
10501037 processed : custom_processed_dir,
10511038 source_event_sender : custom_source_events,
1052- } = extra_sources_dirs [ "custom" ] . clone ( ) ;
1039+ } = register_new_source ( & mut app , "custom" , source_gate . clone ( ) ) ;
10531040
10541041 #[ derive( Serialize , Deserialize ) ]
10551042 enum NesterSerialized {
@@ -1261,8 +1248,7 @@ fn clears_invalid_data_from_processed_dir() {
12611248 processed : default_processed_dir,
12621249 ..
12631250 } ,
1264- ..
1265- } = create_app_with_asset_processor ( & [ ] ) ;
1251+ } = create_app_with_asset_processor ( ) ;
12661252
12671253 type CoolTextProcessor = LoadTransformAndSave <
12681254 CoolTextLoader ,
@@ -1367,8 +1353,7 @@ fn only_reprocesses_wrong_hash_on_startup() {
13671353 mut app,
13681354 source_gate,
13691355 default_source_dirs,
1370- ..
1371- } = create_app_with_asset_processor ( & [ ] ) ;
1356+ } = create_app_with_asset_processor ( ) ;
13721357 default_source_dir = default_source_dirs. source ;
13731358 default_processed_dir = default_source_dirs. processed ;
13741359
@@ -1450,16 +1435,16 @@ fn only_reprocesses_wrong_hash_on_startup() {
14501435 root : default_processed_dir. clone ( ) ,
14511436 } ;
14521437
1453- app. register_asset_source (
1454- AssetSourceId :: Default ,
1455- AssetSourceBuilder :: new ( move || Box :: new ( source_memory_reader. clone ( ) ) )
1456- . with_processed_reader ( move || Box :: new ( processed_memory_reader. clone ( ) ) )
1457- . with_processed_writer ( move |_| Some ( Box :: new ( processed_memory_writer. clone ( ) ) ) ) ,
1458- ) ;
1459-
14601438 app. add_plugins ( (
14611439 TaskPoolPlugin :: default ( ) ,
14621440 AssetPlugin {
1441+ default_source : DefaultAssetSource :: FromBuilder ( Mutex :: new (
1442+ AssetSourceBuilder :: new ( move || Box :: new ( source_memory_reader. clone ( ) ) )
1443+ . with_processed_reader ( move || Box :: new ( processed_memory_reader. clone ( ) ) )
1444+ . with_processed_writer ( move |_| {
1445+ Some ( Box :: new ( processed_memory_writer. clone ( ) ) )
1446+ } ) ,
1447+ ) ) ,
14631448 mode : AssetMode :: Processed ,
14641449 use_asset_processor_override : Some ( true ) ,
14651450 ..Default :: default ( )
0 commit comments