Skip to content

Commit 2d16183

Browse files
committed
core: Pause preloading until an ImportAssets is finished, + test
1 parent fe08638 commit 2d16183

File tree

9 files changed

+209
-129
lines changed

9 files changed

+209
-129
lines changed

core/src/display_object/movie_clip.rs

Lines changed: 92 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ use crate::drawing::Drawing;
3131
use crate::events::{ButtonKeyCode, ClipEvent, ClipEventResult};
3232
use crate::font::{Font, FontType};
3333
use crate::limits::ExecutionLimit;
34+
use crate::loader::Loader;
3435
use crate::loader::{self, ContentType};
35-
use crate::loader::{LoadManager, Loader};
3636
use crate::prelude::*;
3737
use crate::streams::NetStream;
3838
use crate::string::{AvmString, SwfStrExt as _, WStr, WString};
@@ -191,6 +191,10 @@ pub struct MovieClipData<'gc> {
191191

192192
// If this movie was loaded from ImportAssets(2), this will be the parent movie.
193193
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,
194198
}
195199

196200
impl<'gc> MovieClip<'gc> {
@@ -227,6 +231,7 @@ impl<'gc> MovieClip<'gc> {
227231
queued_tags: HashMap::new(),
228232
attached_audio: None,
229233
importer_movie: None,
234+
awaiting_import: false,
230235
},
231236
))
232237
}
@@ -269,6 +274,7 @@ impl<'gc> MovieClip<'gc> {
269274
queued_tags: HashMap::new(),
270275
attached_audio: None,
271276
importer_movie: None,
277+
awaiting_import: false,
272278
},
273279
));
274280
clip.set_avm2_class(gc_context, Some(class));
@@ -314,6 +320,7 @@ impl<'gc> MovieClip<'gc> {
314320
queued_tags: HashMap::new(),
315321
attached_audio: None,
316322
importer_movie: None,
323+
awaiting_import: false,
317324
},
318325
))
319326
}
@@ -369,6 +376,7 @@ impl<'gc> MovieClip<'gc> {
369376
queued_tags: HashMap::new(),
370377
attached_audio: None,
371378
importer_movie: Some(parent.clone()),
379+
awaiting_import: false,
372380
},
373381
));
374382

@@ -435,6 +443,7 @@ impl<'gc> MovieClip<'gc> {
435443
queued_tags: HashMap::new(),
436444
attached_audio: None,
437445
importer_movie: None,
446+
awaiting_import: false,
438447
},
439448
));
440449

@@ -522,6 +531,11 @@ impl<'gc> MovieClip<'gc> {
522531
) -> bool {
523532
{
524533
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+
}
525539
if read.static_data.preload_progress.read().next_preload_chunk
526540
>= read.static_data.swf.len() as u64
527541
{
@@ -757,14 +771,12 @@ impl<'gc> MovieClip<'gc> {
757771
.write(context.gc_context)
758772
.define_binary_data(context, reader),
759773
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);
763776
}
764777
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);
768780
}
769781
TagCode::DoAbc | TagCode::DoAbc2 => self.preload_bytecode_tag(
770782
tag_code,
@@ -796,7 +808,8 @@ impl<'gc> MovieClip<'gc> {
796808
} else {
797809
Ok(true)
798810
};
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());
800813

801814
self.0
802815
.write(context.gc_context)
@@ -1260,6 +1273,10 @@ impl<'gc> MovieClip<'gc> {
12601273
.unwrap_or_default()
12611274
}
12621275

1276+
pub fn finish_importing(self, gc_context: &Mutation<'gc>) {
1277+
self.0.write(gc_context).awaiting_import = false;
1278+
}
1279+
12631280
/// This sets the current preload frame of this MovieClipto a given number (resulting
12641281
/// in the _framesloaded / framesLoaded property being the given number - 1).
12651282
pub fn set_cur_preload_frame(self, gc_context: &Mutation<'gc>, cur_preload_frame: u16) {
@@ -4129,72 +4146,6 @@ impl<'gc, 'a> MovieClipData<'gc> {
41294146
}
41304147
}
41314148

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-
41984149
#[inline]
41994150
fn script_limits(
42004151
&mut self,
@@ -4472,6 +4423,73 @@ impl<'gc, 'a> MovieClip<'gc> {
44724423
Ok(())
44734424
}
44744425

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+
44754493
// Flash Player handles SymbolClass tags and eager (non-lazy) DoAbc2 tags in an unusual way:
44764494
// During the first time that a given frame is executed:
44774495
// 1. All Abc/DoAbc2 tags have their ABC files parsed and loaded. No script initializers are run yet.

0 commit comments

Comments
 (0)