core: Store the root of each loaded movie and use it as a last-ditch way to get the root
This commit is contained in:
parent
9ded256c23
commit
6a9249e52f
|
@ -403,7 +403,7 @@ pub fn root<'gc>(
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
if let Some(dobj) = this.and_then(|this| this.as_display_object()) {
|
if let Some(dobj) = this.and_then(|this| this.as_display_object()) {
|
||||||
return Ok(dobj
|
return Ok(dobj
|
||||||
.avm2_root(&activation.context)
|
.avm2_root(&mut activation.context)
|
||||||
.map(|root| root.object2())
|
.map(|root| root.object2())
|
||||||
.unwrap_or(Value::Null));
|
.unwrap_or(Value::Null));
|
||||||
}
|
}
|
||||||
|
@ -558,7 +558,7 @@ pub fn loader_info<'gc>(
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
if let Some(dobj) = this.and_then(|this| this.as_display_object()) {
|
if let Some(dobj) = this.and_then(|this| this.as_display_object()) {
|
||||||
if let Some(root) = dobj.avm2_root(&activation.context) {
|
if let Some(root) = dobj.avm2_root(&mut activation.context) {
|
||||||
if DisplayObject::ptr_eq(root, dobj) {
|
if DisplayObject::ptr_eq(root, dobj) {
|
||||||
let movie = dobj.movie();
|
let movie = dobj.movie();
|
||||||
|
|
||||||
|
|
|
@ -1254,7 +1254,7 @@ pub trait TDisplayObject<'gc>:
|
||||||
///
|
///
|
||||||
/// This function implements the AVM2 concept of root clips. For the AVM1
|
/// This function implements the AVM2 concept of root clips. For the AVM1
|
||||||
/// version, see `avm1_root`.
|
/// version, see `avm1_root`.
|
||||||
fn avm2_root(&self, context: &UpdateContext<'_, 'gc, '_>) -> Option<DisplayObject<'gc>> {
|
fn avm2_root(&self, context: &mut UpdateContext<'_, 'gc, '_>) -> Option<DisplayObject<'gc>> {
|
||||||
let mut parent = Some((*self).into());
|
let mut parent = Some((*self).into());
|
||||||
|
|
||||||
while let Some(p) = parent {
|
while let Some(p) = parent {
|
||||||
|
@ -1280,17 +1280,8 @@ pub trait TDisplayObject<'gc>:
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.or_else(|| {
|
parent.or_else(|| {
|
||||||
if let Avm1Value::Object(object) = self.object() {
|
let movie = self.movie()?;
|
||||||
object.as_display_object()
|
context.library.library_for_movie_mut(movie).root()
|
||||||
} else if let Avm2Value::Object(object) = self.object2() {
|
|
||||||
if self.is_on_stage(context) {
|
|
||||||
object.as_display_object()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,9 @@ pub struct MovieLibrary<'gc> {
|
||||||
/// Shared reference to the constructor registry used for this movie.
|
/// Shared reference to the constructor registry used for this movie.
|
||||||
/// Should be `None` if this is an AVM2 movie.
|
/// Should be `None` if this is an AVM2 movie.
|
||||||
avm1_constructor_registry: Option<Gc<'gc, Avm1ConstructorRegistry<'gc>>>,
|
avm1_constructor_registry: Option<Gc<'gc, Avm1ConstructorRegistry<'gc>>>,
|
||||||
|
|
||||||
|
/// The root display object for this movie.
|
||||||
|
root: Option<DisplayObject<'gc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> MovieLibrary<'gc> {
|
impl<'gc> MovieLibrary<'gc> {
|
||||||
|
@ -155,6 +158,7 @@ impl<'gc> MovieLibrary<'gc> {
|
||||||
avm_type,
|
avm_type,
|
||||||
avm2_domain: None,
|
avm2_domain: None,
|
||||||
avm1_constructor_registry: None,
|
avm1_constructor_registry: None,
|
||||||
|
root: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +365,18 @@ impl<'gc> MovieLibrary<'gc> {
|
||||||
pub fn avm2_domain(&self) -> Avm2Domain<'gc> {
|
pub fn avm2_domain(&self) -> Avm2Domain<'gc> {
|
||||||
self.avm2_domain.unwrap()
|
self.avm2_domain.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve the root display object that was created to represent the
|
||||||
|
/// movie being loaded.
|
||||||
|
pub fn root(&self) -> Option<DisplayObject<'gc>> {
|
||||||
|
self.root
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the root display object that was created to represent the
|
||||||
|
/// movie being loaded.
|
||||||
|
pub fn set_root(&mut self, root: DisplayObject<'gc>) {
|
||||||
|
self.root = Some(root);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Symbol library for multiple movies.
|
/// Symbol library for multiple movies.
|
||||||
|
|
|
@ -488,12 +488,6 @@ impl<'gc> Loader<'gc> {
|
||||||
.lock()
|
.lock()
|
||||||
.expect("Could not lock player!!")
|
.expect("Could not lock player!!")
|
||||||
.update(|uc| {
|
.update(|uc| {
|
||||||
let domain =
|
|
||||||
Avm2Domain::movie_domain(uc.gc_context, uc.avm2.global_domain());
|
|
||||||
uc.library
|
|
||||||
.library_for_movie_mut(movie.clone())
|
|
||||||
.set_avm2_domain(domain);
|
|
||||||
|
|
||||||
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
target_clip,
|
target_clip,
|
||||||
|
@ -504,6 +498,13 @@ impl<'gc> Loader<'gc> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let domain =
|
||||||
|
Avm2Domain::movie_domain(uc.gc_context, uc.avm2.global_domain());
|
||||||
|
let library = uc.library.library_for_movie_mut(movie.clone());
|
||||||
|
|
||||||
|
library.set_avm2_domain(domain);
|
||||||
|
library.set_root(clip);
|
||||||
|
|
||||||
if let Some(broadcaster) = broadcaster {
|
if let Some(broadcaster) = broadcaster {
|
||||||
Avm1::run_stack_frame_for_method(
|
Avm1::run_stack_frame_for_method(
|
||||||
clip,
|
clip,
|
||||||
|
|
|
@ -386,14 +386,14 @@ impl Player {
|
||||||
context.swf.height(),
|
context.swf.height(),
|
||||||
);
|
);
|
||||||
let domain = Avm2Domain::movie_domain(context.gc_context, context.avm2.global_domain());
|
let domain = Avm2Domain::movie_domain(context.gc_context, context.avm2.global_domain());
|
||||||
context
|
|
||||||
.library
|
|
||||||
.library_for_movie_mut(context.swf.clone())
|
|
||||||
.set_avm2_domain(domain);
|
|
||||||
|
|
||||||
let root: DisplayObject =
|
let root: DisplayObject =
|
||||||
MovieClip::from_movie(context.gc_context, context.swf.clone()).into();
|
MovieClip::from_movie(context.gc_context, context.swf.clone()).into();
|
||||||
|
|
||||||
|
let library = context.library.library_for_movie_mut(context.swf.clone());
|
||||||
|
|
||||||
|
library.set_avm2_domain(domain);
|
||||||
|
library.set_root(root);
|
||||||
|
|
||||||
root.set_depth(context.gc_context, 0);
|
root.set_depth(context.gc_context, 0);
|
||||||
let flashvars = if !context.swf.parameters().is_empty() {
|
let flashvars = if !context.swf.parameters().is_empty() {
|
||||||
let object = ScriptObject::object(context.gc_context, None);
|
let object = ScriptObject::object(context.gc_context, None);
|
||||||
|
|
Loading…
Reference in New Issue