avm1: Object.watch is case insensitive on SWFv6
This commit is contained in:
parent
8a0430d744
commit
a1ff80bb18
|
@ -231,17 +231,23 @@ impl<'gc> TObject<'gc> for ColorTransformObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.base()
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.base().remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.base().remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn has_property(
|
||||
|
|
|
@ -626,16 +626,23 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.base.set_watcher(gc_context, name, callback, user_data);
|
||||
self.base
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.base.remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.base.remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn has_property(
|
||||
|
|
|
@ -188,7 +188,7 @@ fn watch<'gc>(
|
|||
};
|
||||
let user_data = args.get(2).cloned().unwrap_or(Value::Undefined);
|
||||
|
||||
this.set_watcher(context.gc_context, name, callback, user_data);
|
||||
this.set_watcher(activation, context.gc_context, name, callback, user_data);
|
||||
|
||||
Ok(true.into())
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ fn unwatch<'gc>(
|
|||
return Ok(false.into());
|
||||
};
|
||||
|
||||
let result = this.remove_watcher(context.gc_context, name);
|
||||
let result = this.remove_watcher(activation, context.gc_context, name);
|
||||
|
||||
Ok(result.into())
|
||||
}
|
||||
|
|
|
@ -264,6 +264,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
/// The property does not need to exist at the time of this being called.
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
|
@ -274,7 +275,12 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
///
|
||||
/// The return value will indicate if there was a watcher present before this method was
|
||||
/// called.
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool;
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool;
|
||||
|
||||
/// Checks if the object has a given named property.
|
||||
fn has_property(
|
||||
|
|
|
@ -8,7 +8,6 @@ use core::fmt;
|
|||
use enumset::EnumSet;
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub const TYPE_OF_OBJECT: &str = "object";
|
||||
|
||||
|
@ -73,7 +72,7 @@ pub struct ScriptObjectData<'gc> {
|
|||
interfaces: Vec<Object<'gc>>,
|
||||
type_of: &'static str,
|
||||
array: ArrayStorage<'gc>,
|
||||
watchers: HashMap<String, Watcher<'gc>>,
|
||||
watchers: PropertyMap<Watcher<'gc>>,
|
||||
}
|
||||
|
||||
unsafe impl<'gc> Collect for ScriptObjectData<'gc> {
|
||||
|
@ -110,7 +109,7 @@ impl<'gc> ScriptObject<'gc> {
|
|||
values: PropertyMap::new(),
|
||||
array: ArrayStorage::Properties { length: 0 },
|
||||
interfaces: vec![],
|
||||
watchers: HashMap::new(),
|
||||
watchers: PropertyMap::new(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -127,7 +126,7 @@ impl<'gc> ScriptObject<'gc> {
|
|||
values: PropertyMap::new(),
|
||||
array: ArrayStorage::Vector(Vec::new()),
|
||||
interfaces: vec![],
|
||||
watchers: HashMap::new(),
|
||||
watchers: PropertyMap::new(),
|
||||
},
|
||||
));
|
||||
object.sync_native_property("length", gc_context, Some(0.into()), false);
|
||||
|
@ -147,7 +146,7 @@ impl<'gc> ScriptObject<'gc> {
|
|||
values: PropertyMap::new(),
|
||||
array: ArrayStorage::Properties { length: 0 },
|
||||
interfaces: vec![],
|
||||
watchers: HashMap::new(),
|
||||
watchers: PropertyMap::new(),
|
||||
},
|
||||
))
|
||||
.into()
|
||||
|
@ -167,7 +166,7 @@ impl<'gc> ScriptObject<'gc> {
|
|||
values: PropertyMap::new(),
|
||||
array: ArrayStorage::Properties { length: 0 },
|
||||
interfaces: vec![],
|
||||
watchers: HashMap::new(),
|
||||
watchers: PropertyMap::new(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -309,7 +308,12 @@ impl<'gc> ScriptObject<'gc> {
|
|||
//we'd resolve and return up there, but we have borrows that need
|
||||
//to end before we can do so.
|
||||
if !worked {
|
||||
let watcher = self.0.read().watchers.get(name).cloned();
|
||||
let watcher = self
|
||||
.0
|
||||
.read()
|
||||
.watchers
|
||||
.get(name, activation.is_case_sensitive())
|
||||
.cloned();
|
||||
let mut return_value = Ok(());
|
||||
if let Some(watcher) = watcher {
|
||||
let old_value = self.get(name, activation, context)?;
|
||||
|
@ -557,19 +561,30 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.0
|
||||
.write(gc_context)
|
||||
.watchers
|
||||
.insert(name.to_string(), Watcher::new(callback, user_data));
|
||||
self.0.write(gc_context).watchers.insert(
|
||||
&name,
|
||||
Watcher::new(callback, user_data),
|
||||
activation.is_case_sensitive(),
|
||||
);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
let old = self.0.write(gc_context).watchers.remove(name.as_ref());
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
let old = self
|
||||
.0
|
||||
.write(gc_context)
|
||||
.watchers
|
||||
.remove(name.as_ref(), activation.is_case_sensitive());
|
||||
old.is_some()
|
||||
}
|
||||
|
||||
|
|
|
@ -193,17 +193,23 @@ impl<'gc> TObject<'gc> for SharedObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.base()
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.base().remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.base().remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn has_property(
|
||||
|
|
|
@ -253,17 +253,23 @@ impl<'gc> TObject<'gc> for SoundObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.base()
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.base().remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.base().remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn has_property(
|
||||
|
|
|
@ -334,6 +334,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
|
@ -342,11 +343,19 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
|||
self.0
|
||||
.read()
|
||||
.base
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.0.read().base.remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.0
|
||||
.read()
|
||||
.base
|
||||
.remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn has_property(
|
||||
|
|
|
@ -239,6 +239,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
_gc_context: MutationContext<'gc, '_>,
|
||||
_name: Cow<str>,
|
||||
_callback: Executable<'gc>,
|
||||
|
@ -247,7 +248,12 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
|
|||
//`super` cannot have properties defined on it
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, _gc_context: MutationContext<'gc, '_>, _name: Cow<str>) -> bool {
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
_gc_context: MutationContext<'gc, '_>,
|
||||
_name: Cow<str>,
|
||||
) -> bool {
|
||||
//`super` cannot have properties defined on it
|
||||
false
|
||||
}
|
||||
|
|
|
@ -233,6 +233,7 @@ impl<'gc> TObject<'gc> for ValueObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
|
@ -241,14 +242,19 @@ impl<'gc> TObject<'gc> for ValueObject<'gc> {
|
|||
self.0
|
||||
.read()
|
||||
.base
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.0
|
||||
.write(gc_context)
|
||||
.base
|
||||
.remove_watcher(gc_context, name)
|
||||
.remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn define_value(
|
||||
|
|
|
@ -159,17 +159,23 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.base()
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.base().remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.base().remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn define_value(
|
||||
|
|
|
@ -157,17 +157,23 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.base()
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.base().remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.base().remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn define_value(
|
||||
|
|
|
@ -147,17 +147,23 @@ impl<'gc> TObject<'gc> for XMLObject<'gc> {
|
|||
|
||||
fn set_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
callback: Executable<'gc>,
|
||||
user_data: Value<'gc>,
|
||||
) {
|
||||
self.base()
|
||||
.set_watcher(gc_context, name, callback, user_data);
|
||||
.set_watcher(activation, gc_context, name, callback, user_data);
|
||||
}
|
||||
|
||||
fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow<str>) -> bool {
|
||||
self.base().remove_watcher(gc_context, name)
|
||||
fn remove_watcher(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
name: Cow<str>,
|
||||
) -> bool {
|
||||
self.base().remove_watcher(activation, gc_context, name)
|
||||
}
|
||||
|
||||
fn define_value(
|
||||
|
|
Loading…
Reference in New Issue