avm2: Store symbol / class relationships using the class constructor, not the prototype.
This commit is contained in:
parent
0ee9e0f820
commit
f33976f4c0
|
@ -21,19 +21,24 @@ pub fn instance_init<'gc>(
|
|||
this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
if let Some(this) = this {
|
||||
if let Some(mut this) = this {
|
||||
activation.super_init(this, &[])?;
|
||||
|
||||
if this.as_display_object().is_none() {
|
||||
let proto = this.proto();
|
||||
let constructor = this
|
||||
.get_property(
|
||||
this,
|
||||
&QName::new(Namespace::public(), "constructor"),
|
||||
activation,
|
||||
)?
|
||||
.coerce_to_object(activation)?;
|
||||
|
||||
if let Some((movie, symbol)) = proto.and_then(|proto| {
|
||||
activation
|
||||
.context
|
||||
.library
|
||||
.avm2_constructor_registry()
|
||||
.proto_symbol(proto)
|
||||
}) {
|
||||
if let Some((movie, symbol)) = activation
|
||||
.context
|
||||
.library
|
||||
.avm2_constructor_registry()
|
||||
.constr_symbol(constructor)
|
||||
{
|
||||
let mut child = activation
|
||||
.context
|
||||
.library
|
||||
|
|
|
@ -586,26 +586,12 @@ impl<'gc> MovieClip<'gc> {
|
|||
.and_then(|v| v.coerce_to_object(&mut activation));
|
||||
|
||||
match constr {
|
||||
Ok(mut constr) => {
|
||||
let proto = constr
|
||||
.get_property(
|
||||
constr,
|
||||
&Avm2QName::new(Avm2Namespace::public(), "prototype"),
|
||||
&mut activation,
|
||||
)
|
||||
.and_then(|v| v.coerce_to_object(&mut activation));
|
||||
match proto {
|
||||
Ok(proto) => activation
|
||||
.context
|
||||
.library
|
||||
.avm2_constructor_registry_mut()
|
||||
.set_proto_symbol(proto, movie.clone(), id),
|
||||
Err(e) => log::warn!(
|
||||
"Got AVM2 error {} when getting prototype of symbol class {}",
|
||||
e,
|
||||
class_name
|
||||
),
|
||||
};
|
||||
Ok(constr) => {
|
||||
activation
|
||||
.context
|
||||
.library
|
||||
.avm2_constructor_registry_mut()
|
||||
.set_constr_symbol(constr, movie.clone(), id);
|
||||
|
||||
let library = activation
|
||||
.context
|
||||
|
|
|
@ -79,17 +79,17 @@ impl WeakElement for WeakMovieSymbol {
|
|||
}
|
||||
}
|
||||
|
||||
/// The mappings between prototypes and library characters defined by
|
||||
/// The mappings between constructors and library characters defined by
|
||||
/// `SymbolClass`.
|
||||
pub struct Avm2ConstructorRegistry<'gc> {
|
||||
/// A list of AVM2 class prototypes and the character IDs they are expected
|
||||
/// A list of AVM2 class constructors and the character IDs they are expected
|
||||
/// to instantiate.
|
||||
proto_map: WeakValueHashMap<Avm2Object<'gc>, WeakMovieSymbol>,
|
||||
constr_map: WeakValueHashMap<Avm2Object<'gc>, WeakMovieSymbol>,
|
||||
}
|
||||
|
||||
unsafe impl Collect for Avm2ConstructorRegistry<'_> {
|
||||
fn trace(&self, cc: gc_arena::CollectionContext) {
|
||||
for (k, _) in self.proto_map.iter() {
|
||||
for (k, _) in self.constr_map.iter() {
|
||||
k.trace(cc);
|
||||
}
|
||||
}
|
||||
|
@ -104,29 +104,29 @@ impl Default for Avm2ConstructorRegistry<'_> {
|
|||
impl<'gc> Avm2ConstructorRegistry<'gc> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
proto_map: WeakValueHashMap::new(),
|
||||
constr_map: WeakValueHashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve the library symbol for a given AVM2 prototype.
|
||||
/// Retrieve the library symbol for a given AVM2 class constructor.
|
||||
///
|
||||
/// A value of `None` indicates that this AVM2 class is not associated with
|
||||
/// a library symbol.
|
||||
pub fn proto_symbol(&self, proto: Avm2Object<'gc>) -> Option<(Arc<SwfMovie>, CharacterId)> {
|
||||
match self.proto_map.get(&proto) {
|
||||
pub fn constr_symbol(&self, proto: Avm2Object<'gc>) -> Option<(Arc<SwfMovie>, CharacterId)> {
|
||||
match self.constr_map.get(&proto) {
|
||||
Some(MovieSymbol(movie, symbol)) => Some((movie, symbol)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Associate an AVM2 prototype with a given library symbol.
|
||||
pub fn set_proto_symbol(
|
||||
/// Associate an AVM2 class constructor with a given library symbol.
|
||||
pub fn set_constr_symbol(
|
||||
&mut self,
|
||||
proto: Avm2Object<'gc>,
|
||||
movie: Arc<SwfMovie>,
|
||||
symbol: CharacterId,
|
||||
) {
|
||||
self.proto_map.insert(proto, MovieSymbol(movie, symbol));
|
||||
self.constr_map.insert(proto, MovieSymbol(movie, symbol));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue