core: Unify loader event handler and AVM2 data into MovieLoaderVMData
`AVM2Data` was always provided with `MovieLoaderEventHandler::Avm2LoaderInfo`, so we can unify them into a single enum.
This commit is contained in:
parent
16210cbcf6
commit
a387476de7
|
@ -10,6 +10,7 @@ use crate::backend::navigator::{NavigationMethod, Request};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use crate::display_object::{DisplayObject, MovieClip, TDisplayObject, TDisplayObjectContainer};
|
use crate::display_object::{DisplayObject, MovieClip, TDisplayObject, TDisplayObjectContainer};
|
||||||
use crate::ecma_conversions::{f64_to_wrapping_i32, f64_to_wrapping_u32};
|
use crate::ecma_conversions::{f64_to_wrapping_i32, f64_to_wrapping_u32};
|
||||||
|
use crate::loader::MovieLoaderVMData;
|
||||||
use crate::string::{AvmString, SwfStrExt as _, WStr, WString};
|
use crate::string::{AvmString, SwfStrExt as _, WStr, WString};
|
||||||
use crate::tag_utils::SwfSlice;
|
use crate::tag_utils::SwfSlice;
|
||||||
use crate::vminterface::Instantiator;
|
use crate::vminterface::Instantiator;
|
||||||
|
@ -1209,8 +1210,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
level,
|
level,
|
||||||
Request::get(url.to_string()),
|
Request::get(url.to_string()),
|
||||||
None,
|
None,
|
||||||
None,
|
MovieLoaderVMData::Avm1 { broadcaster: None },
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
self.context.navigator.spawn_future(future);
|
self.context.navigator.spawn_future(future);
|
||||||
}
|
}
|
||||||
|
@ -1340,8 +1340,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
clip_target,
|
clip_target,
|
||||||
request,
|
request,
|
||||||
None,
|
None,
|
||||||
None,
|
MovieLoaderVMData::Avm1 { broadcaster: None },
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
self.context.navigator.spawn_future(future);
|
self.context.navigator.spawn_future(future);
|
||||||
}
|
}
|
||||||
|
@ -1362,8 +1361,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
clip_target,
|
clip_target,
|
||||||
Request::get(url.to_utf8_lossy().into_owned()),
|
Request::get(url.to_utf8_lossy().into_owned()),
|
||||||
None,
|
None,
|
||||||
None,
|
MovieLoaderVMData::Avm1 { broadcaster: None },
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
self.context.navigator.spawn_future(future);
|
self.context.navigator.spawn_future(future);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1546,8 +1546,7 @@ fn load_movie<'gc>(
|
||||||
DisplayObject::MovieClip(target),
|
DisplayObject::MovieClip(target),
|
||||||
request,
|
request,
|
||||||
None,
|
None,
|
||||||
None,
|
crate::loader::MovieLoaderVMData::Avm1 { broadcaster: None },
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
activation.context.navigator.spawn_future(future);
|
activation.context.navigator.spawn_future(future);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::avm1::{ArrayObject, Object, Value};
|
||||||
use crate::backend::navigator::Request;
|
use crate::backend::navigator::Request;
|
||||||
use crate::context::GcContext;
|
use crate::context::GcContext;
|
||||||
use crate::display_object::{TDisplayObject, TDisplayObjectContainer};
|
use crate::display_object::{TDisplayObject, TDisplayObjectContainer};
|
||||||
use crate::loader::MovieLoaderEventHandler;
|
use crate::loader::MovieLoaderVMData;
|
||||||
|
|
||||||
const PROTO_DECLS: &[Declaration] = declare_properties! {
|
const PROTO_DECLS: &[Declaration] = declare_properties! {
|
||||||
"loadClip" => method(load_clip; DONT_ENUM | DONT_DELETE);
|
"loadClip" => method(load_clip; DONT_ENUM | DONT_DELETE);
|
||||||
|
@ -65,8 +65,9 @@ fn load_clip<'gc>(
|
||||||
target,
|
target,
|
||||||
Request::get(url.to_utf8_lossy().into_owned()),
|
Request::get(url.to_utf8_lossy().into_owned()),
|
||||||
None,
|
None,
|
||||||
Some(MovieLoaderEventHandler::Avm1Broadcast(this)),
|
MovieLoaderVMData::Avm1 {
|
||||||
None,
|
broadcaster: Some(this),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
activation.context.navigator.spawn_future(future);
|
activation.context.navigator.spawn_future(future);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::avm2_stub_method;
|
||||||
use crate::backend::navigator::{NavigationMethod, Request};
|
use crate::backend::navigator::{NavigationMethod, Request};
|
||||||
use crate::display_object::LoaderDisplay;
|
use crate::display_object::LoaderDisplay;
|
||||||
use crate::display_object::MovieClip;
|
use crate::display_object::MovieClip;
|
||||||
use crate::loader::{Avm2LoaderData, MovieLoaderEventHandler};
|
use crate::loader::MovieLoaderVMData;
|
||||||
use crate::tag_utils::SwfMovie;
|
use crate::tag_utils::SwfMovie;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -87,13 +87,13 @@ pub fn load<'gc>(
|
||||||
content.into(),
|
content.into(),
|
||||||
request,
|
request,
|
||||||
Some(url),
|
Some(url),
|
||||||
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)),
|
MovieLoaderVMData::Avm2 {
|
||||||
Some(Avm2LoaderData {
|
loader_info,
|
||||||
context,
|
context,
|
||||||
default_domain: activation
|
default_domain: activation
|
||||||
.caller_domain()
|
.caller_domain()
|
||||||
.expect("Missing caller domain in Loader.load"),
|
.expect("Missing caller domain in Loader.load"),
|
||||||
}),
|
},
|
||||||
);
|
);
|
||||||
activation.context.navigator.spawn_future(future);
|
activation.context.navigator.spawn_future(future);
|
||||||
}
|
}
|
||||||
|
@ -218,13 +218,13 @@ pub fn load_bytes<'gc>(
|
||||||
activation.context.player.clone(),
|
activation.context.player.clone(),
|
||||||
content.into(),
|
content.into(),
|
||||||
bytearray.bytes().to_vec(),
|
bytearray.bytes().to_vec(),
|
||||||
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)),
|
MovieLoaderVMData::Avm2 {
|
||||||
Some(Avm2LoaderData {
|
loader_info,
|
||||||
context,
|
context,
|
||||||
default_domain: activation
|
default_domain: activation
|
||||||
.caller_domain()
|
.caller_domain()
|
||||||
.expect("Missing caller domain in Loader.loadBytes"),
|
.expect("Missing caller domain in Loader.loadBytes"),
|
||||||
}),
|
},
|
||||||
);
|
);
|
||||||
activation.context.navigator.spawn_future(future);
|
activation.context.navigator.spawn_future(future);
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,7 +231,7 @@ impl<'gc> LoaderInfoObject<'gc> {
|
||||||
Some(LoaderStream::Swf(_, root)) => root
|
Some(LoaderStream::Swf(_, root)) => root
|
||||||
.as_movie_clip()
|
.as_movie_clip()
|
||||||
.map(|mc| mc.loaded_bytes() >= mc.total_bytes())
|
.map(|mc| mc.loaded_bytes() >= mc.total_bytes())
|
||||||
.unwrap_or(false),
|
.unwrap_or(true),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -260,16 +260,14 @@ impl<'gc> LoadManager<'gc> {
|
||||||
target_clip: DisplayObject<'gc>,
|
target_clip: DisplayObject<'gc>,
|
||||||
request: Request,
|
request: Request,
|
||||||
loader_url: Option<String>,
|
loader_url: Option<String>,
|
||||||
event_handler: Option<MovieLoaderEventHandler<'gc>>,
|
vm_data: MovieLoaderVMData<'gc>,
|
||||||
avm2_data: Option<Avm2LoaderData<'gc>>,
|
|
||||||
) -> OwnedFuture<(), Error> {
|
) -> OwnedFuture<(), Error> {
|
||||||
let loader = Loader::Movie {
|
let loader = Loader::Movie {
|
||||||
self_handle: None,
|
self_handle: None,
|
||||||
target_clip,
|
target_clip,
|
||||||
event_handler,
|
vm_data,
|
||||||
loader_status: LoaderStatus::Pending,
|
loader_status: LoaderStatus::Pending,
|
||||||
movie: None,
|
movie: None,
|
||||||
avm2_data,
|
|
||||||
};
|
};
|
||||||
let handle = self.add_loader(loader);
|
let handle = self.add_loader(loader);
|
||||||
let loader = self.get_loader_mut(handle).unwrap();
|
let loader = self.get_loader_mut(handle).unwrap();
|
||||||
|
@ -284,16 +282,14 @@ impl<'gc> LoadManager<'gc> {
|
||||||
player: Weak<Mutex<Player>>,
|
player: Weak<Mutex<Player>>,
|
||||||
target_clip: DisplayObject<'gc>,
|
target_clip: DisplayObject<'gc>,
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
event_handler: Option<MovieLoaderEventHandler<'gc>>,
|
vm_data: MovieLoaderVMData<'gc>,
|
||||||
avm2_data: Option<Avm2LoaderData<'gc>>,
|
|
||||||
) -> OwnedFuture<(), Error> {
|
) -> OwnedFuture<(), Error> {
|
||||||
let loader = Loader::Movie {
|
let loader = Loader::Movie {
|
||||||
self_handle: None,
|
self_handle: None,
|
||||||
target_clip,
|
target_clip,
|
||||||
event_handler,
|
vm_data,
|
||||||
loader_status: LoaderStatus::Pending,
|
loader_status: LoaderStatus::Pending,
|
||||||
movie: None,
|
movie: None,
|
||||||
avm2_data,
|
|
||||||
};
|
};
|
||||||
let handle = self.add_loader(loader);
|
let handle = self.add_loader(loader);
|
||||||
let loader = self.get_loader_mut(handle).unwrap();
|
let loader = self.get_loader_mut(handle).unwrap();
|
||||||
|
@ -472,19 +468,19 @@ pub enum LoaderStatus {
|
||||||
|
|
||||||
#[derive(Collect, Clone, Copy)]
|
#[derive(Collect, Clone, Copy)]
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
pub enum MovieLoaderEventHandler<'gc> {
|
pub enum MovieLoaderVMData<'gc> {
|
||||||
Avm1Broadcast(Object<'gc>),
|
Avm1 {
|
||||||
Avm2LoaderInfo(Avm2Object<'gc>),
|
broadcaster: Option<Object<'gc>>,
|
||||||
}
|
},
|
||||||
|
Avm2 {
|
||||||
|
loader_info: Avm2Object<'gc>,
|
||||||
|
|
||||||
#[derive(Collect, Clone, Copy)]
|
/// The context of the SWF being loaded.
|
||||||
#[collect(no_drop)]
|
context: Option<Avm2Object<'gc>>,
|
||||||
pub struct Avm2LoaderData<'gc> {
|
|
||||||
/// The context of the SWF being loaded.
|
|
||||||
pub context: Option<Avm2Object<'gc>>,
|
|
||||||
|
|
||||||
/// The default domain this SWF will use.
|
/// The default domain this SWF will use.
|
||||||
pub default_domain: Avm2Domain<'gc>,
|
default_domain: Avm2Domain<'gc>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct that holds garbage-collected pointers for asynchronous code.
|
/// A struct that holds garbage-collected pointers for asynchronous code.
|
||||||
|
@ -507,9 +503,8 @@ pub enum Loader<'gc> {
|
||||||
/// The target movie clip to load the movie into.
|
/// The target movie clip to load the movie into.
|
||||||
target_clip: DisplayObject<'gc>,
|
target_clip: DisplayObject<'gc>,
|
||||||
|
|
||||||
/// Event broadcaster (typically a `MovieClipLoader`) to fire events
|
// Virtual-machine specific data (AVM1 or AVM2)
|
||||||
/// into.
|
vm_data: MovieLoaderVMData<'gc>,
|
||||||
event_handler: Option<MovieLoaderEventHandler<'gc>>,
|
|
||||||
|
|
||||||
/// Indicates the completion status of this loader.
|
/// Indicates the completion status of this loader.
|
||||||
///
|
///
|
||||||
|
@ -527,9 +522,6 @@ pub enum Loader<'gc> {
|
||||||
/// completed and we expect the Player to periodically tick preload
|
/// completed and we expect the Player to periodically tick preload
|
||||||
/// until loading completes.
|
/// until loading completes.
|
||||||
movie: Option<Arc<SwfMovie>>,
|
movie: Option<Arc<SwfMovie>>,
|
||||||
|
|
||||||
/// AVM2 specific data for this SWF.
|
|
||||||
avm2_data: Option<Avm2LoaderData<'gc>>,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Loader that is loading form data into an AVM1 object scope.
|
/// Loader that is loading form data into an AVM1 object scope.
|
||||||
|
@ -1318,26 +1310,28 @@ impl<'gc> Loader<'gc> {
|
||||||
|
|
||||||
let me = me.unwrap();
|
let me = me.unwrap();
|
||||||
|
|
||||||
let (clip, event_handler) = match me {
|
let (clip, vm_data) = match me {
|
||||||
Loader::Movie {
|
Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
event_handler,
|
vm_data,
|
||||||
..
|
..
|
||||||
} => (*target_clip, *event_handler),
|
} => (*target_clip, *vm_data),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match event_handler {
|
match vm_data {
|
||||||
Some(MovieLoaderEventHandler::Avm1Broadcast(broadcaster)) => {
|
MovieLoaderVMData::Avm1 { broadcaster } => {
|
||||||
Avm1::run_stack_frame_for_method(
|
if let Some(broadcaster) = broadcaster {
|
||||||
clip,
|
Avm1::run_stack_frame_for_method(
|
||||||
broadcaster,
|
clip,
|
||||||
uc,
|
broadcaster,
|
||||||
"broadcastMessage".into(),
|
uc,
|
||||||
&["onLoadStart".into(), clip.object()],
|
"broadcastMessage".into(),
|
||||||
);
|
&["onLoadStart".into(), clip.object()],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) => {
|
MovieLoaderVMData::Avm2 { loader_info, .. } => {
|
||||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||||
|
|
||||||
// Update the LoadersTream - we still have a fake SwfMovie, but we now have the real target clip.
|
// Update the LoadersTream - we still have a fake SwfMovie, but we now have the real target clip.
|
||||||
|
@ -1356,7 +1350,6 @@ impl<'gc> Loader<'gc> {
|
||||||
let open_evt = Avm2EventObject::bare_default_event(&mut activation.context, "open");
|
let open_evt = Avm2EventObject::bare_default_event(&mut activation.context, "open");
|
||||||
Avm2::dispatch_event(uc, open_evt, loader_info);
|
Avm2::dispatch_event(uc, open_evt, loader_info);
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1379,22 +1372,25 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
player.lock().unwrap().update(|uc| {
|
player.lock().unwrap().update(|uc| {
|
||||||
let (clip, event_handler, avm2_data) = match uc.load_manager.get_loader(handle) {
|
let (clip, vm_data) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
event_handler,
|
vm_data,
|
||||||
avm2_data,
|
|
||||||
..
|
..
|
||||||
}) => (*target_clip, *event_handler, *avm2_data),
|
}) => (*target_clip, *vm_data),
|
||||||
None => return Err(Error::Cancelled),
|
None => return Err(Error::Cancelled),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||||
|
|
||||||
let domain = if let Some(avm2_data) = avm2_data {
|
let domain = if let MovieLoaderVMData::Avm2 {
|
||||||
let domain = avm2_data
|
context,
|
||||||
.context
|
default_domain,
|
||||||
|
..
|
||||||
|
} = vm_data
|
||||||
|
{
|
||||||
|
let domain = context
|
||||||
.and_then(|o| {
|
.and_then(|o| {
|
||||||
o.get_public_property("applicationDomain", &mut activation)
|
o.get_public_property("applicationDomain", &mut activation)
|
||||||
.ok()
|
.ok()
|
||||||
|
@ -1402,7 +1398,7 @@ impl<'gc> Loader<'gc> {
|
||||||
.and_then(|v| v.coerce_to_object(&mut activation).ok())
|
.and_then(|v| v.coerce_to_object(&mut activation).ok())
|
||||||
.and_then(|o| o.as_application_domain())
|
.and_then(|o| o.as_application_domain())
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
let parent_domain = avm2_data.default_domain;
|
let parent_domain = default_domain;
|
||||||
Avm2Domain::movie_domain(&mut activation, parent_domain)
|
Avm2Domain::movie_domain(&mut activation, parent_domain)
|
||||||
});
|
});
|
||||||
Some(domain)
|
Some(domain)
|
||||||
|
@ -1430,7 +1426,7 @@ impl<'gc> Loader<'gc> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) = event_handler {
|
if let MovieLoaderVMData::Avm2 { loader_info, .. } = vm_data {
|
||||||
// Update the LoaderStream - we now have a real SWF movie and a real target clip
|
// Update the LoaderStream - we now have a real SWF movie and a real target clip
|
||||||
loader_info
|
loader_info
|
||||||
.as_loader_info_object()
|
.as_loader_info_object()
|
||||||
|
@ -1458,9 +1454,7 @@ impl<'gc> Loader<'gc> {
|
||||||
|
|
||||||
if let Some(mc) = clip.as_movie_clip() {
|
if let Some(mc) = clip.as_movie_clip() {
|
||||||
let loader_info =
|
let loader_info =
|
||||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) =
|
if let MovieLoaderVMData::Avm2 { loader_info, .. } = vm_data {
|
||||||
event_handler
|
|
||||||
{
|
|
||||||
Some(*loader_info.as_loader_info_object().unwrap())
|
Some(*loader_info.as_loader_info_object().unwrap())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1570,31 +1564,33 @@ impl<'gc> Loader<'gc> {
|
||||||
|
|
||||||
let me = me.unwrap();
|
let me = me.unwrap();
|
||||||
|
|
||||||
let (clip, event_handler) = match me {
|
let (clip, vm_data) = match me {
|
||||||
Loader::Movie {
|
Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
event_handler,
|
vm_data,
|
||||||
..
|
..
|
||||||
} => (*target_clip, *event_handler),
|
} => (*target_clip, *vm_data),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match event_handler {
|
match vm_data {
|
||||||
Some(MovieLoaderEventHandler::Avm1Broadcast(broadcaster)) => {
|
MovieLoaderVMData::Avm1 { broadcaster } => {
|
||||||
Avm1::run_stack_frame_for_method(
|
if let Some(broadcaster) = broadcaster {
|
||||||
clip,
|
Avm1::run_stack_frame_for_method(
|
||||||
broadcaster,
|
clip,
|
||||||
uc,
|
broadcaster,
|
||||||
"broadcastMessage".into(),
|
uc,
|
||||||
&[
|
"broadcastMessage".into(),
|
||||||
"onLoadProgress".into(),
|
&[
|
||||||
clip.object(),
|
"onLoadProgress".into(),
|
||||||
cur_len.into(),
|
clip.object(),
|
||||||
total_len.into(),
|
cur_len.into(),
|
||||||
],
|
total_len.into(),
|
||||||
);
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) => {
|
MovieLoaderVMData::Avm2 { loader_info, .. } => {
|
||||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||||
|
|
||||||
let progress_evt = activation
|
let progress_evt = activation
|
||||||
|
@ -1615,7 +1611,6 @@ impl<'gc> Loader<'gc> {
|
||||||
|
|
||||||
Avm2::dispatch_event(uc, progress_evt, loader_info);
|
Avm2::dispatch_event(uc, progress_evt, loader_info);
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1627,23 +1622,22 @@ impl<'gc> Loader<'gc> {
|
||||||
uc: &mut UpdateContext<'_, 'gc>,
|
uc: &mut UpdateContext<'_, 'gc>,
|
||||||
dobj: Option<DisplayObject<'gc>>,
|
dobj: Option<DisplayObject<'gc>>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let (target_clip, event_handler, movie) = match uc.load_manager.get_loader_mut(handle) {
|
let (target_clip, vm_data, movie) = match uc.load_manager.get_loader_mut(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
movie,
|
movie,
|
||||||
event_handler,
|
vm_data,
|
||||||
..
|
..
|
||||||
}) => (*target_clip, *event_handler, movie.clone()),
|
}) => (*target_clip, *vm_data, movie.clone()),
|
||||||
None => return Err(Error::Cancelled),
|
None => return Err(Error::Cancelled),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let loader_info =
|
let loader_info = if let MovieLoaderVMData::Avm2 { loader_info, .. } = vm_data {
|
||||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) = event_handler {
|
Some(*loader_info.as_loader_info_object().unwrap())
|
||||||
Some(*loader_info.as_loader_info_object().unwrap())
|
} else {
|
||||||
} else {
|
None
|
||||||
None
|
};
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(loader_info) = loader_info {
|
if let Some(loader_info) = loader_info {
|
||||||
// Store the real movie into the `LoaderStream`, so that
|
// Store the real movie into the `LoaderStream`, so that
|
||||||
|
@ -1673,7 +1667,7 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) = event_handler {
|
if let MovieLoaderVMData::Avm2 { loader_info, .. } = vm_data {
|
||||||
let domain = uc
|
let domain = uc
|
||||||
.library
|
.library
|
||||||
.library_for_movie(movie.unwrap())
|
.library_for_movie(movie.unwrap())
|
||||||
|
@ -1707,23 +1701,25 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match event_handler {
|
match vm_data {
|
||||||
Some(MovieLoaderEventHandler::Avm1Broadcast(broadcaster)) => {
|
MovieLoaderVMData::Avm1 { broadcaster } => {
|
||||||
Avm1::run_stack_frame_for_method(
|
if let Some(broadcaster) = broadcaster {
|
||||||
target_clip,
|
Avm1::run_stack_frame_for_method(
|
||||||
broadcaster,
|
target_clip,
|
||||||
uc,
|
broadcaster,
|
||||||
"broadcastMessage".into(),
|
uc,
|
||||||
// TODO: Pass an actual httpStatus argument instead of 0.
|
"broadcastMessage".into(),
|
||||||
&["onLoadComplete".into(), target_clip.object(), 0.into()],
|
// TODO: Pass an actual httpStatus argument instead of 0.
|
||||||
);
|
&["onLoadComplete".into(), target_clip.object(), 0.into()],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// This is fired after we process the movie's first frame,
|
// This is fired after we process the movie's first frame,
|
||||||
// in `MovieClip.on_exit_frame`
|
// in `MovieClip.on_exit_frame`
|
||||||
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) => {
|
MovieLoaderVMData::Avm2 { loader_info, .. } => {
|
||||||
let loader_info_obj = loader_info.as_loader_info_object().unwrap();
|
let loader_info_obj = loader_info.as_loader_info_object().unwrap();
|
||||||
loader_info_obj.set_loader_stream(
|
loader_info_obj.set_loader_stream(
|
||||||
LoaderStream::Swf(target_clip.as_movie_clip().unwrap().movie(), target_clip),
|
LoaderStream::Swf(target_clip.as_movie_clip().unwrap().movie(), dobj.unwrap()),
|
||||||
uc.gc_context,
|
uc.gc_context,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1733,7 +1729,6 @@ impl<'gc> Loader<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Loader::Movie { loader_status, .. } = uc.load_manager.get_loader_mut(handle).unwrap()
|
if let Loader::Movie { loader_status, .. } = uc.load_manager.get_loader_mut(handle).unwrap()
|
||||||
|
@ -1758,31 +1753,33 @@ impl<'gc> Loader<'gc> {
|
||||||
//error types we can actually inspect.
|
//error types we can actually inspect.
|
||||||
//This also can get errors from decoding an invalid SWF file,
|
//This also can get errors from decoding an invalid SWF file,
|
||||||
//too. We should distinguish those to player code.
|
//too. We should distinguish those to player code.
|
||||||
let (clip, event_handler) = match uc.load_manager.get_loader_mut(handle) {
|
let (clip, vm_data) = match uc.load_manager.get_loader_mut(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
event_handler,
|
vm_data,
|
||||||
..
|
..
|
||||||
}) => (*target_clip, *event_handler),
|
}) => (*target_clip, *vm_data),
|
||||||
None => return Err(Error::Cancelled),
|
None => return Err(Error::Cancelled),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match event_handler {
|
match vm_data {
|
||||||
Some(MovieLoaderEventHandler::Avm1Broadcast(broadcaster)) => {
|
MovieLoaderVMData::Avm1 { broadcaster } => {
|
||||||
Avm1::run_stack_frame_for_method(
|
if let Some(broadcaster) = broadcaster {
|
||||||
clip,
|
Avm1::run_stack_frame_for_method(
|
||||||
broadcaster,
|
clip,
|
||||||
uc,
|
broadcaster,
|
||||||
"broadcastMessage".into(),
|
uc,
|
||||||
&[
|
"broadcastMessage".into(),
|
||||||
"onLoadError".into(),
|
&[
|
||||||
clip.object(),
|
"onLoadError".into(),
|
||||||
"LoadNeverCompleted".into(),
|
clip.object(),
|
||||||
],
|
"LoadNeverCompleted".into(),
|
||||||
);
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) => {
|
MovieLoaderVMData::Avm2 { loader_info, .. } => {
|
||||||
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
|
||||||
// FIXME - Match the exact error message generated by Flash
|
// FIXME - Match the exact error message generated by Flash
|
||||||
|
|
||||||
|
@ -1802,7 +1799,6 @@ impl<'gc> Loader<'gc> {
|
||||||
|
|
||||||
Avm2::dispatch_event(uc, io_error_evt, loader_info);
|
Avm2::dispatch_event(uc, io_error_evt, loader_info);
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Loader::Movie { loader_status, .. } = uc.load_manager.get_loader_mut(handle).unwrap()
|
if let Loader::Movie { loader_status, .. } = uc.load_manager.get_loader_mut(handle).unwrap()
|
||||||
|
@ -1819,13 +1815,13 @@ impl<'gc> Loader<'gc> {
|
||||||
///
|
///
|
||||||
/// Used to fire listener events on clips and terminate completed loaders.
|
/// Used to fire listener events on clips and terminate completed loaders.
|
||||||
fn movie_clip_loaded(&mut self, queue: &mut ActionQueue<'gc>) -> bool {
|
fn movie_clip_loaded(&mut self, queue: &mut ActionQueue<'gc>) -> bool {
|
||||||
let (clip, event_handler, loader_status) = match self {
|
let (clip, vm_data, loader_status) = match self {
|
||||||
Loader::Movie {
|
Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
event_handler,
|
vm_data,
|
||||||
loader_status,
|
loader_status,
|
||||||
..
|
..
|
||||||
} => (*target_clip, *event_handler, *loader_status),
|
} => (*target_clip, *vm_data, *loader_status),
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1835,7 +1831,10 @@ impl<'gc> Loader<'gc> {
|
||||||
LoaderStatus::Failed => true,
|
LoaderStatus::Failed => true,
|
||||||
LoaderStatus::Succeeded => {
|
LoaderStatus::Succeeded => {
|
||||||
// AVM2 is handled separately
|
// AVM2 is handled separately
|
||||||
if let Some(MovieLoaderEventHandler::Avm1Broadcast(broadcaster)) = event_handler {
|
if let MovieLoaderVMData::Avm1 {
|
||||||
|
broadcaster: Some(broadcaster),
|
||||||
|
} = vm_data
|
||||||
|
{
|
||||||
queue.queue_action(
|
queue.queue_action(
|
||||||
clip,
|
clip,
|
||||||
ActionType::Method {
|
ActionType::Method {
|
||||||
|
|
Loading…
Reference in New Issue