@@ -31,8 +31,8 @@ use crate::drawing::Drawing;
31
31
use crate :: events:: { ButtonKeyCode , ClipEvent , ClipEventResult } ;
32
32
use crate :: font:: { Font , FontType } ;
33
33
use crate :: limits:: ExecutionLimit ;
34
+ use crate :: loader:: Loader ;
34
35
use crate :: loader:: { self , ContentType } ;
35
- use crate :: loader:: { LoadManager , Loader } ;
36
36
use crate :: prelude:: * ;
37
37
use crate :: streams:: NetStream ;
38
38
use crate :: string:: { AvmString , SwfStrExt as _, WStr , WString } ;
@@ -191,6 +191,10 @@ pub struct MovieClipData<'gc> {
191
191
192
192
// If this movie was loaded from ImportAssets(2), this will be the parent movie.
193
193
importer_movie : Option < Arc < SwfMovie > > ,
194
+
195
+ /// If this movie is currently executing an ImportAssets/2.
196
+ /// If true, this movie should **not** execute, and should be considered as still loading.
197
+ awaiting_import : bool ,
194
198
}
195
199
196
200
impl < ' gc > MovieClip < ' gc > {
@@ -227,6 +231,7 @@ impl<'gc> MovieClip<'gc> {
227
231
queued_tags : HashMap :: new ( ) ,
228
232
attached_audio : None ,
229
233
importer_movie : None ,
234
+ awaiting_import : false ,
230
235
} ,
231
236
) )
232
237
}
@@ -269,6 +274,7 @@ impl<'gc> MovieClip<'gc> {
269
274
queued_tags : HashMap :: new ( ) ,
270
275
attached_audio : None ,
271
276
importer_movie : None ,
277
+ awaiting_import : false ,
272
278
} ,
273
279
) ) ;
274
280
clip. set_avm2_class ( gc_context, Some ( class) ) ;
@@ -314,6 +320,7 @@ impl<'gc> MovieClip<'gc> {
314
320
queued_tags : HashMap :: new ( ) ,
315
321
attached_audio : None ,
316
322
importer_movie : None ,
323
+ awaiting_import : false ,
317
324
} ,
318
325
) )
319
326
}
@@ -369,6 +376,7 @@ impl<'gc> MovieClip<'gc> {
369
376
queued_tags : HashMap :: new ( ) ,
370
377
attached_audio : None ,
371
378
importer_movie : Some ( parent. clone ( ) ) ,
379
+ awaiting_import : false ,
372
380
} ,
373
381
) ) ;
374
382
@@ -435,6 +443,7 @@ impl<'gc> MovieClip<'gc> {
435
443
queued_tags : HashMap :: new ( ) ,
436
444
attached_audio : None ,
437
445
importer_movie : None ,
446
+ awaiting_import : false ,
438
447
} ,
439
448
) ) ;
440
449
@@ -522,6 +531,11 @@ impl<'gc> MovieClip<'gc> {
522
531
) -> bool {
523
532
{
524
533
let read = self . 0 . read ( ) ;
534
+ if read. awaiting_import {
535
+ // No matter how much of this movie we have loaded, we must not continue preloading
536
+ // until the import is finished.
537
+ return false ;
538
+ }
525
539
if read. static_data . preload_progress . read ( ) . next_preload_chunk
526
540
>= read. static_data . swf . len ( ) as u64
527
541
{
@@ -757,14 +771,12 @@ impl<'gc> MovieClip<'gc> {
757
771
. write ( context. gc_context )
758
772
. define_binary_data ( context, reader) ,
759
773
TagCode :: ImportAssets => {
760
- self . 0
761
- . write ( context. gc_context )
762
- . import_assets ( context, reader, chunk_limit)
774
+ self . import_assets ( context, reader, chunk_limit) ?;
775
+ return Ok ( ControlFlow :: Exit ) ;
763
776
}
764
777
TagCode :: ImportAssets2 => {
765
- self . 0
766
- . write ( context. gc_context )
767
- . import_assets_2 ( context, reader, chunk_limit)
778
+ self . import_assets_2 ( context, reader, chunk_limit) ?;
779
+ return Ok ( ControlFlow :: Exit ) ;
768
780
}
769
781
TagCode :: DoAbc | TagCode :: DoAbc2 => self . preload_bytecode_tag (
770
782
tag_code,
@@ -796,7 +808,8 @@ impl<'gc> MovieClip<'gc> {
796
808
} else {
797
809
Ok ( true )
798
810
} ;
799
- let is_finished = end_tag_found || result. is_err ( ) || !result. unwrap_or_default ( ) ;
811
+ let is_finished = !self . 0 . read ( ) . awaiting_import
812
+ && ( end_tag_found || result. is_err ( ) || !result. unwrap_or_default ( ) ) ;
800
813
801
814
self . 0
802
815
. write ( context. gc_context )
@@ -1260,6 +1273,10 @@ impl<'gc> MovieClip<'gc> {
1260
1273
. unwrap_or_default ( )
1261
1274
}
1262
1275
1276
+ pub fn finish_importing ( self , gc_context : & Mutation < ' gc > ) {
1277
+ self . 0 . write ( gc_context) . awaiting_import = false ;
1278
+ }
1279
+
1263
1280
/// This sets the current preload frame of this MovieClipto a given number (resulting
1264
1281
/// in the _framesloaded / framesLoaded property being the given number - 1).
1265
1282
pub fn set_cur_preload_frame ( self , gc_context : & Mutation < ' gc > , cur_preload_frame : u16 ) {
@@ -4129,72 +4146,6 @@ impl<'gc, 'a> MovieClipData<'gc> {
4129
4146
}
4130
4147
}
4131
4148
4132
- #[ inline]
4133
- fn import_assets (
4134
- & mut self ,
4135
- context : & mut UpdateContext < ' _ , ' gc > ,
4136
- reader : & mut SwfStream < ' a > ,
4137
- chunk_limit : & mut ExecutionLimit ,
4138
- ) -> Result < ( ) , Error > {
4139
- let import_assets = reader. read_import_assets ( ) ?;
4140
- self . import_assets_load (
4141
- context,
4142
- reader,
4143
- import_assets. 0 ,
4144
- import_assets. 1 ,
4145
- chunk_limit,
4146
- )
4147
- }
4148
-
4149
- #[ inline]
4150
- fn import_assets_2 (
4151
- & mut self ,
4152
- context : & mut UpdateContext < ' _ , ' gc > ,
4153
- reader : & mut SwfStream < ' a > ,
4154
- chunk_limit : & mut ExecutionLimit ,
4155
- ) -> Result < ( ) , Error > {
4156
- let import_assets = reader. read_import_assets_2 ( ) ?;
4157
- self . import_assets_load (
4158
- context,
4159
- reader,
4160
- import_assets. 0 ,
4161
- import_assets. 1 ,
4162
- chunk_limit,
4163
- )
4164
- }
4165
-
4166
- #[ inline]
4167
- fn import_assets_load (
4168
- & mut self ,
4169
- context : & mut UpdateContext < ' _ , ' gc > ,
4170
- reader : & mut SwfStream < ' a > ,
4171
- url : & swf:: SwfStr ,
4172
- exported_assets : Vec < swf:: ExportedAsset > ,
4173
- _chunk_limit : & mut ExecutionLimit ,
4174
- ) -> Result < ( ) , Error > {
4175
- let library = context. library . library_for_movie_mut ( self . movie ( ) ) ;
4176
-
4177
- let asset_url = url. to_string_lossy ( UTF_8 ) ;
4178
-
4179
- let request = Request :: get ( asset_url) ;
4180
-
4181
- for asset in exported_assets {
4182
- let name = asset. name . decode ( reader. encoding ( ) ) ;
4183
- let name = AvmString :: new ( context. gc_context , name) ;
4184
- let id = asset. id ;
4185
- tracing:: debug!( "Importing asset: {} (ID: {})" , name, id) ;
4186
-
4187
- library. register_import ( name, id) ;
4188
- }
4189
-
4190
- let player = context. player . clone ( ) ;
4191
- let fut = LoadManager :: load_asset_movie ( player, request, self . movie ( ) ) ;
4192
-
4193
- context. navigator . spawn_future ( fut) ;
4194
-
4195
- Ok ( ( ) )
4196
- }
4197
-
4198
4149
#[ inline]
4199
4150
fn script_limits (
4200
4151
& mut self ,
@@ -4472,6 +4423,73 @@ impl<'gc, 'a> MovieClip<'gc> {
4472
4423
Ok ( ( ) )
4473
4424
}
4474
4425
4426
+ #[ inline]
4427
+ fn import_assets (
4428
+ self ,
4429
+ context : & mut UpdateContext < ' _ , ' gc > ,
4430
+ reader : & mut SwfStream < ' a > ,
4431
+ chunk_limit : & mut ExecutionLimit ,
4432
+ ) -> Result < ( ) , Error > {
4433
+ let import_assets = reader. read_import_assets ( ) ?;
4434
+ self . import_assets_load (
4435
+ context,
4436
+ reader,
4437
+ import_assets. 0 ,
4438
+ import_assets. 1 ,
4439
+ chunk_limit,
4440
+ )
4441
+ }
4442
+
4443
+ #[ inline]
4444
+ fn import_assets_2 (
4445
+ self ,
4446
+ context : & mut UpdateContext < ' _ , ' gc > ,
4447
+ reader : & mut SwfStream < ' a > ,
4448
+ chunk_limit : & mut ExecutionLimit ,
4449
+ ) -> Result < ( ) , Error > {
4450
+ let import_assets = reader. read_import_assets_2 ( ) ?;
4451
+ self . import_assets_load (
4452
+ context,
4453
+ reader,
4454
+ import_assets. 0 ,
4455
+ import_assets. 1 ,
4456
+ chunk_limit,
4457
+ )
4458
+ }
4459
+
4460
+ #[ inline]
4461
+ fn import_assets_load (
4462
+ self ,
4463
+ context : & mut UpdateContext < ' _ , ' gc > ,
4464
+ reader : & mut SwfStream < ' a > ,
4465
+ url : & swf:: SwfStr ,
4466
+ exported_assets : Vec < swf:: ExportedAsset > ,
4467
+ _chunk_limit : & mut ExecutionLimit ,
4468
+ ) -> Result < ( ) , Error > {
4469
+ let library = context. library . library_for_movie_mut ( self . movie ( ) ) ;
4470
+
4471
+ let asset_url = url. to_string_lossy ( UTF_8 ) ;
4472
+
4473
+ let request = Request :: get ( asset_url) ;
4474
+
4475
+ for asset in exported_assets {
4476
+ let name = asset. name . decode ( reader. encoding ( ) ) ;
4477
+ let name = AvmString :: new ( context. gc_context , name) ;
4478
+ let id = asset. id ;
4479
+ tracing:: debug!( "Importing asset: {} (ID: {})" , name, id) ;
4480
+
4481
+ library. register_import ( name, id) ;
4482
+ }
4483
+
4484
+ let player = context. player . clone ( ) ;
4485
+ self . 0 . write ( context. gc_context ) . awaiting_import = true ;
4486
+ let fut = context. load_manager . load_asset_movie ( player, request, self ) ;
4487
+
4488
+ context. navigator . spawn_future ( fut) ;
4489
+
4490
+ Ok ( ( ) )
4491
+ }
4492
+
4475
4493
// Flash Player handles SymbolClass tags and eager (non-lazy) DoAbc2 tags in an unusual way:
4476
4494
// During the first time that a given frame is executed:
4477
4495
// 1. All Abc/DoAbc2 tags have their ABC files parsed and loaded. No script initializers are run yet.
0 commit comments