core: Refactor `movie_loader` and its `loadBytes` variant to call into the same code.
This commit is contained in:
parent
86ecf6076e
commit
8f5afe09a1
|
@ -708,120 +708,22 @@ impl<'gc> Loader<'gc> {
|
|||
})?;
|
||||
|
||||
match fetch.await {
|
||||
Ok(response) => {
|
||||
let sniffed_type = ContentType::sniff(&response.body);
|
||||
let mut length = response.body.len();
|
||||
|
||||
if replacing_root_movie {
|
||||
sniffed_type.expect(ContentType::Swf)?;
|
||||
Ok(response) if replacing_root_movie => {
|
||||
ContentType::sniff(&response.body).expect(ContentType::Swf)?;
|
||||
|
||||
let movie =
|
||||
SwfMovie::from_data(&response.body, Some(response.url), loader_url)?;
|
||||
player.lock().unwrap().set_root_movie(movie);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
player.lock().unwrap().update(|uc| {
|
||||
let (clip, event_handler) = match uc.load_manager.get_loader(handle) {
|
||||
Some(Loader::Movie {
|
||||
target_clip,
|
||||
event_handler,
|
||||
..
|
||||
}) => (*target_clip, *event_handler),
|
||||
None => return Err(Error::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if let ContentType::Unknown = sniffed_type {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(_)) = event_handler {
|
||||
// Flash always fires an initial 'progress' event with
|
||||
// bytesLoaded=0 and bytesTotal set to the proper value.
|
||||
// This only seems to happen for an AVM2 event handler
|
||||
Loader::movie_loader_progress(handle, uc, 0, length)?;
|
||||
}
|
||||
|
||||
match sniffed_type {
|
||||
ContentType::Swf => {
|
||||
let movie = Arc::new(SwfMovie::from_data(
|
||||
Ok(response) => {
|
||||
Loader::movie_loader_data(
|
||||
handle,
|
||||
player,
|
||||
&response.body,
|
||||
Some(response.url),
|
||||
loader_url,
|
||||
)?);
|
||||
|
||||
match uc.load_manager.get_loader_mut(handle) {
|
||||
Some(Loader::Movie {
|
||||
movie: old,
|
||||
loader_status,
|
||||
..
|
||||
}) => {
|
||||
*loader_status = LoaderStatus::Parsing;
|
||||
*old = Some(movie.clone())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||
let parent_domain = activation.avm2().global_domain();
|
||||
let domain =
|
||||
Avm2Domain::movie_domain(&mut activation, parent_domain);
|
||||
activation
|
||||
.context
|
||||
.library
|
||||
.library_for_movie_mut(movie.clone())
|
||||
.set_avm2_domain(domain);
|
||||
|
||||
if let Some(mut mc) = clip.as_movie_clip() {
|
||||
let loader_info = if let Some(
|
||||
MovieLoaderEventHandler::Avm2LoaderInfo(loader_info),
|
||||
) = event_handler
|
||||
{
|
||||
Some(*loader_info.as_loader_info_object().unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Store our downloaded `SwfMovie` into our target `MovieClip`,
|
||||
// and initialize it.
|
||||
|
||||
mc.replace_with_movie(
|
||||
&mut activation.context,
|
||||
Some(movie),
|
||||
loader_info,
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE: Certain tests specifically expect small files to preload immediately
|
||||
Loader::preload_tick(
|
||||
handle,
|
||||
uc,
|
||||
&mut ExecutionLimit::with_max_actions_and_time(
|
||||
10000,
|
||||
Duration::from_millis(1),
|
||||
),
|
||||
)?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
ContentType::Gif | ContentType::Jpeg | ContentType::Png => {
|
||||
let bitmap = uc.renderer.register_bitmap_jpeg_2(&response.body)?;
|
||||
let bitmap_obj =
|
||||
Bitmap::new(uc, 0, bitmap.handle, bitmap.width, bitmap.height);
|
||||
|
||||
if let Some(mc) = clip.as_movie_clip() {
|
||||
mc.replace_at_depth(uc, bitmap_obj.into(), 1);
|
||||
}
|
||||
}
|
||||
ContentType::Unknown => {}
|
||||
}
|
||||
|
||||
Loader::movie_loader_progress(handle, uc, length, length)?;
|
||||
Loader::movie_loader_complete(handle, uc)?;
|
||||
|
||||
Ok(())
|
||||
})?; //TODO: content sniffing errors need to be reported somehow
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Error during movie loading: {:?}", e);
|
||||
|
@ -870,115 +772,15 @@ impl<'gc> Loader<'gc> {
|
|||
Ok(())
|
||||
})?;
|
||||
|
||||
let sniffed_type = ContentType::sniff(&bytes);
|
||||
let mut length = bytes.len();
|
||||
|
||||
if replacing_root_movie {
|
||||
sniffed_type.expect(ContentType::Swf)?;
|
||||
ContentType::sniff(&bytes).expect(ContentType::Swf)?;
|
||||
|
||||
let movie = SwfMovie::from_data(&bytes, None, None)?;
|
||||
let movie = SwfMovie::from_data(&bytes, Some("file:///".into()), None)?;
|
||||
player.lock().unwrap().set_root_movie(movie);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
player.lock().unwrap().update(|uc| {
|
||||
let (clip, event_handler) = match uc.load_manager.get_loader(handle) {
|
||||
Some(Loader::Movie {
|
||||
target_clip,
|
||||
event_handler,
|
||||
..
|
||||
}) => (*target_clip, *event_handler),
|
||||
None => return Err(Error::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if let ContentType::Unknown = sniffed_type {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(_)) = event_handler {
|
||||
// Flash always fires an initial 'progress' event with
|
||||
// bytesLoaded=0 and bytesTotal set to the proper value.
|
||||
// This only seems to happen for an AVM2 event handler
|
||||
Loader::movie_loader_progress(handle, uc, 0, length)?;
|
||||
}
|
||||
|
||||
match sniffed_type {
|
||||
ContentType::Swf => {
|
||||
let movie = Arc::new(SwfMovie::from_data(&bytes, None, None)?);
|
||||
|
||||
match uc.load_manager.get_loader_mut(handle) {
|
||||
Some(Loader::Movie {
|
||||
movie: old,
|
||||
loader_status,
|
||||
..
|
||||
}) => {
|
||||
*loader_status = LoaderStatus::Parsing;
|
||||
*old = Some(movie.clone())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||
let parent_domain = activation.avm2().global_domain();
|
||||
let domain = Avm2Domain::movie_domain(&mut activation, parent_domain);
|
||||
activation
|
||||
.context
|
||||
.library
|
||||
.library_for_movie_mut(movie.clone())
|
||||
.set_avm2_domain(domain);
|
||||
|
||||
if let Some(mut mc) = clip.as_movie_clip() {
|
||||
let loader_info =
|
||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) =
|
||||
event_handler
|
||||
{
|
||||
Some(*loader_info.as_loader_info_object().unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Store our downloaded `SwfMovie` into our target `MovieClip`,
|
||||
// and initialize it.
|
||||
|
||||
mc.replace_with_movie(
|
||||
&mut activation.context,
|
||||
Some(movie),
|
||||
loader_info,
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE: Certain tests specifically expect small files to preload immediately
|
||||
Loader::preload_tick(
|
||||
handle,
|
||||
uc,
|
||||
&mut ExecutionLimit::with_max_actions_and_time(
|
||||
10000,
|
||||
Duration::from_millis(1),
|
||||
),
|
||||
)?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
ContentType::Gif | ContentType::Jpeg | ContentType::Png => {
|
||||
let bitmap = uc.renderer.register_bitmap_jpeg_2(&bytes)?;
|
||||
let bitmap_obj =
|
||||
Bitmap::new(uc, 0, bitmap.handle, bitmap.width, bitmap.height);
|
||||
|
||||
if let Some(mc) = clip.as_movie_clip() {
|
||||
mc.replace_at_depth(uc, bitmap_obj.into(), 1);
|
||||
}
|
||||
}
|
||||
ContentType::Unknown => {}
|
||||
}
|
||||
|
||||
Loader::movie_loader_progress(handle, uc, length, length)?;
|
||||
Loader::movie_loader_complete(handle, uc)?;
|
||||
|
||||
Ok(())
|
||||
})?; //TODO: content sniffing errors need to be reported somehow
|
||||
|
||||
Ok(())
|
||||
Loader::movie_loader_data(handle, player, &bytes, Some("file:///".into()), None)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1455,6 +1257,110 @@ impl<'gc> Loader<'gc> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Load data into a movie loader.
|
||||
fn movie_loader_data(
|
||||
handle: Handle,
|
||||
player: Arc<Mutex<Player>>,
|
||||
data: &[u8],
|
||||
url: Option<String>,
|
||||
loader_url: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
let sniffed_type = ContentType::sniff(data);
|
||||
let mut length = data.len();
|
||||
|
||||
player.lock().unwrap().update(|uc| {
|
||||
let (clip, event_handler) = match uc.load_manager.get_loader(handle) {
|
||||
Some(Loader::Movie {
|
||||
target_clip,
|
||||
event_handler,
|
||||
..
|
||||
}) => (*target_clip, *event_handler),
|
||||
None => return Err(Error::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if let ContentType::Unknown = sniffed_type {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(_)) = event_handler {
|
||||
// Flash always fires an initial 'progress' event with
|
||||
// bytesLoaded=0 and bytesTotal set to the proper value.
|
||||
// This only seems to happen for an AVM2 event handler
|
||||
Loader::movie_loader_progress(handle, uc, 0, length)?;
|
||||
}
|
||||
|
||||
match sniffed_type {
|
||||
ContentType::Swf => {
|
||||
let movie = Arc::new(SwfMovie::from_data(data, url, loader_url)?);
|
||||
|
||||
match uc.load_manager.get_loader_mut(handle) {
|
||||
Some(Loader::Movie {
|
||||
movie: old,
|
||||
loader_status,
|
||||
..
|
||||
}) => {
|
||||
*loader_status = LoaderStatus::Parsing;
|
||||
*old = Some(movie.clone())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||
let parent_domain = activation.avm2().global_domain();
|
||||
let domain = Avm2Domain::movie_domain(&mut activation, parent_domain);
|
||||
activation
|
||||
.context
|
||||
.library
|
||||
.library_for_movie_mut(movie.clone())
|
||||
.set_avm2_domain(domain);
|
||||
|
||||
if let Some(mut mc) = clip.as_movie_clip() {
|
||||
let loader_info =
|
||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) =
|
||||
event_handler
|
||||
{
|
||||
Some(*loader_info.as_loader_info_object().unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Store our downloaded `SwfMovie` into our target `MovieClip`,
|
||||
// and initialize it.
|
||||
|
||||
mc.replace_with_movie(&mut activation.context, Some(movie), loader_info);
|
||||
}
|
||||
|
||||
// NOTE: Certain tests specifically expect small files to preload immediately
|
||||
Loader::preload_tick(
|
||||
handle,
|
||||
uc,
|
||||
&mut ExecutionLimit::with_max_actions_and_time(
|
||||
10000,
|
||||
Duration::from_millis(1),
|
||||
),
|
||||
)?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
ContentType::Gif | ContentType::Jpeg | ContentType::Png => {
|
||||
let bitmap = uc.renderer.register_bitmap_jpeg_2(&data)?;
|
||||
let bitmap_obj = Bitmap::new(uc, 0, bitmap.handle, bitmap.width, bitmap.height);
|
||||
|
||||
if let Some(mc) = clip.as_movie_clip() {
|
||||
mc.replace_at_depth(uc, bitmap_obj.into(), 1);
|
||||
}
|
||||
}
|
||||
ContentType::Unknown => {}
|
||||
}
|
||||
|
||||
Loader::movie_loader_progress(handle, uc, length, length)?;
|
||||
Loader::movie_loader_complete(handle, uc)?;
|
||||
|
||||
Ok(())
|
||||
}) //TODO: content sniffing errors need to be reported somehow
|
||||
}
|
||||
|
||||
/// Report a movie loader progress event to script code.
|
||||
///
|
||||
/// The current and total length are always reported as compressed lengths.
|
||||
|
|
Loading…
Reference in New Issue