avm1: Migrate `SharedObject` to `NativeObject`
This commit is contained in:
parent
268403faad
commit
151ad97686
|
@ -61,6 +61,15 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.2"
|
||||
|
@ -78,9 +87,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
|
|||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.16"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||
checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9"
|
||||
|
||||
[[package]]
|
||||
name = "alsa"
|
||||
|
@ -999,9 +1008,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.3"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
|
||||
checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
|
@ -1009,9 +1018,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.3"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
|
||||
checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
|
@ -1022,9 +1031,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.3"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
||||
checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
|
@ -1932,11 +1941,11 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
|||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.11"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1391ab1f92ffcc08911957149833e682aa3fe252b9f45f966d2ef972274c97df"
|
||||
checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"aho-corasick 0.7.20",
|
||||
"bstr",
|
||||
"fnv",
|
||||
"log",
|
||||
|
@ -2361,9 +2370,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
|
@ -2660,9 +2669,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lyon_path"
|
||||
version = "1.0.4"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca507745ba7ccbc76e5c44e7b63b1a29d2b0d6126f375806a5bbaf657c7d6c45"
|
||||
checksum = "7da8358c012e5651e4619cfd0b5b75c0f77866181a01b0909aab4bae14adf660"
|
||||
dependencies = [
|
||||
"lyon_geom",
|
||||
"num-traits",
|
||||
|
@ -3435,9 +3444,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6"
|
||||
checksum = "d220334a184db82b31b83f5ff093e3315280fb2b6bbc032022b2304a509aab7a"
|
||||
|
||||
[[package]]
|
||||
name = "pp-rs"
|
||||
|
@ -3668,9 +3677,9 @@ version = "1.9.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"aho-corasick 1.0.2",
|
||||
"memchr",
|
||||
"regex-automata 0.3.3",
|
||||
"regex-automata 0.3.2",
|
||||
"regex-syntax 0.7.4",
|
||||
]
|
||||
|
||||
|
@ -3685,11 +3694,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.3"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
|
||||
checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"aho-corasick 1.0.2",
|
||||
"memchr",
|
||||
"regex-syntax 0.7.4",
|
||||
]
|
||||
|
@ -4158,15 +4167,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
|
@ -4228,9 +4237,9 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
|
|||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.18"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
|
@ -4277,9 +4286,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.103"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b"
|
||||
checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"itoa",
|
||||
|
@ -4813,9 +4822,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.14"
|
||||
version = "0.19.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
|
||||
checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"serde",
|
||||
|
@ -5036,9 +5045,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.11"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
|
@ -5451,9 +5460,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wide"
|
||||
version = "0.7.11"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f"
|
||||
checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"safe_arch",
|
||||
|
@ -5701,9 +5710,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.0"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
|
||||
checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
@ -32,7 +32,6 @@ pub use error::Error;
|
|||
pub use flv::FlvValueAvm1Ext;
|
||||
pub use function::{Executable, ExecutionReason};
|
||||
pub use globals::context_menu::make_context_menu_state;
|
||||
pub use globals::shared_object::flush;
|
||||
pub use globals::sound::start as start_sound;
|
||||
pub use globals::system::SystemProperties;
|
||||
pub use object::array_object::ArrayObject;
|
||||
|
|
|
@ -487,7 +487,6 @@ pub struct SystemPrototypes<'gc> {
|
|||
pub rectangle: Object<'gc>,
|
||||
pub rectangle_constructor: Object<'gc>,
|
||||
pub transform_constructor: Object<'gc>,
|
||||
pub shared_object: Object<'gc>,
|
||||
pub shared_object_constructor: Object<'gc>,
|
||||
pub color_transform: Object<'gc>,
|
||||
pub color_transform_constructor: Object<'gc>,
|
||||
|
@ -924,14 +923,11 @@ pub fn create_globals<'gc>(
|
|||
globals.define_value(gc_context, "Boolean", boolean.into(), Attribute::DONT_ENUM);
|
||||
globals.define_value(gc_context, "Date", date.into(), Attribute::DONT_ENUM);
|
||||
|
||||
let shared_object_proto = shared_object::create_proto(context, object_proto, function_proto);
|
||||
|
||||
let shared_obj =
|
||||
shared_object::create_shared_object_object(context, shared_object_proto, function_proto);
|
||||
let shared_object = shared_object::create_constructor(context, object_proto, function_proto);
|
||||
globals.define_value(
|
||||
gc_context,
|
||||
"SharedObject",
|
||||
shared_obj.into(),
|
||||
shared_object.into(),
|
||||
Attribute::DONT_ENUM,
|
||||
);
|
||||
|
||||
|
@ -1082,8 +1078,7 @@ pub fn create_globals<'gc>(
|
|||
rectangle: rectangle_proto,
|
||||
rectangle_constructor: rectangle,
|
||||
transform_constructor: transform,
|
||||
shared_object: shared_object_proto,
|
||||
shared_object_constructor: shared_obj,
|
||||
shared_object_constructor: shared_object,
|
||||
color_transform: color_transform_proto,
|
||||
color_transform_constructor: color_transform,
|
||||
context_menu: context_menu_proto,
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use crate::avm1::activation::Activation;
|
||||
use crate::avm1::error::Error;
|
||||
use crate::avm1::function::{Executable, FunctionObject};
|
||||
use crate::avm1::object::shared_object::SharedObject;
|
||||
use crate::avm1::object::NativeObject;
|
||||
use crate::avm1::property::Attribute;
|
||||
use crate::avm1::function::FunctionObject;
|
||||
use crate::avm1::property_decl::{define_properties_on, Declaration};
|
||||
use crate::avm1::{Object, ScriptObject, TObject, Value};
|
||||
use crate::avm1::{
|
||||
Activation, Attribute, Error, Executable, NativeObject, Object, ScriptObject, TObject, Value,
|
||||
};
|
||||
use crate::avm1_stub;
|
||||
use crate::context::GcContext;
|
||||
use crate::display_object::TDisplayObject;
|
||||
|
@ -13,9 +10,28 @@ use crate::string::AvmString;
|
|||
use flash_lso::amf0::read::AMF0Decoder;
|
||||
use flash_lso::amf0::writer::{Amf0Writer, CacheKey, ObjWriter};
|
||||
use flash_lso::types::{Lso, Reference, Value as AmfValue};
|
||||
use gc_arena::{Collect, GcCell};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Default, Clone, Collect)]
|
||||
#[collect(require_static)]
|
||||
pub struct SharedObject {
|
||||
/// The local name of this shared object
|
||||
name: Option<String>,
|
||||
// In future this will also handle remote SharedObjects
|
||||
}
|
||||
|
||||
impl SharedObject {
|
||||
fn name(&self) -> String {
|
||||
self.name.clone().unwrap_or_default()
|
||||
}
|
||||
|
||||
fn set_name(&mut self, name: String) {
|
||||
self.name = Some(name);
|
||||
}
|
||||
}
|
||||
|
||||
const PROTO_DECLS: &[Declaration] = declare_properties! {
|
||||
"clear" => method(clear; DONT_ENUM | DONT_DELETE);
|
||||
"close" => method(close; DONT_ENUM | DONT_DELETE);
|
||||
|
@ -33,12 +49,9 @@ const OBJECT_DECLS: &[Declaration] = declare_properties! {
|
|||
"getDiskUsage" => method(get_disk_usage; DONT_ENUM);
|
||||
"getLocal" => method(get_local);
|
||||
"getRemote" => method(get_remote);
|
||||
"getMaxSize" => method(get_max_size);
|
||||
"addListener" => method(add_listener);
|
||||
"removeListener" => method(remove_listener);
|
||||
};
|
||||
|
||||
pub fn delete_all<'gc>(
|
||||
fn delete_all<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -47,7 +60,7 @@ pub fn delete_all<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn get_disk_usage<'gc>(
|
||||
fn get_disk_usage<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -259,7 +272,7 @@ fn new_lso<'gc>(activation: &mut Activation<'_, 'gc>, name: &str, data: Object<'
|
|||
)
|
||||
}
|
||||
|
||||
pub fn get_local<'gc>(
|
||||
fn get_local<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
|
@ -389,8 +402,11 @@ pub fn get_local<'gc>(
|
|||
.coerce_to_object(activation);
|
||||
|
||||
// Set the internal name
|
||||
let obj_so = this.as_shared_object().unwrap();
|
||||
obj_so.set_name(activation.context.gc_context, full_name.clone());
|
||||
if let NativeObject::SharedObject(shared_object) = this.native() {
|
||||
shared_object
|
||||
.write(activation.context.gc_context)
|
||||
.set_name(full_name.clone());
|
||||
}
|
||||
|
||||
let mut data = Value::Undefined;
|
||||
|
||||
|
@ -426,7 +442,7 @@ pub fn get_local<'gc>(
|
|||
Ok(this.into())
|
||||
}
|
||||
|
||||
pub fn get_remote<'gc>(
|
||||
fn get_remote<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -435,51 +451,7 @@ pub fn get_remote<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn get_max_size<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
avm1_stub!(activation, "SharedObject", "getMaxSize");
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn add_listener<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
avm1_stub!(activation, "SharedObject", "addListener");
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn remove_listener<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
avm1_stub!(activation, "SharedObject", "removeListener");
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn create_shared_object_object<'gc>(
|
||||
context: &mut GcContext<'_, 'gc>,
|
||||
shared_object_proto: Object<'gc>,
|
||||
fn_proto: Object<'gc>,
|
||||
) -> Object<'gc> {
|
||||
let shared_obj = FunctionObject::constructor(
|
||||
context.gc_context,
|
||||
Executable::Native(constructor),
|
||||
constructor_to_fn!(constructor),
|
||||
fn_proto,
|
||||
shared_object_proto,
|
||||
);
|
||||
let object = shared_obj.raw_script_object();
|
||||
define_properties_on(OBJECT_DECLS, context, object, fn_proto);
|
||||
shared_obj
|
||||
}
|
||||
|
||||
pub fn clear<'gc>(
|
||||
fn clear<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -490,15 +462,15 @@ pub fn clear<'gc>(
|
|||
data.delete(activation, *k);
|
||||
}
|
||||
|
||||
let so = this.as_shared_object().unwrap();
|
||||
let name = so.get_name();
|
||||
|
||||
if let NativeObject::SharedObject(shared_object) = this.native() {
|
||||
let name = shared_object.read().name();
|
||||
activation.context.storage.remove_key(&name);
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn close<'gc>(
|
||||
fn close<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -507,7 +479,7 @@ pub fn close<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn connect<'gc>(
|
||||
fn connect<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -516,14 +488,16 @@ pub fn connect<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn flush<'gc>(
|
||||
pub(crate) fn flush<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let NativeObject::SharedObject(shared_object) = this.native() else {
|
||||
return Ok(Value::Undefined);
|
||||
};
|
||||
let name = shared_object.read().name();
|
||||
let data = this.get("data", activation)?.coerce_to_object(activation);
|
||||
let this_obj = this.as_shared_object().unwrap();
|
||||
let name = this_obj.get_name();
|
||||
let mut lso = new_lso(activation, &name, data);
|
||||
flash_lso::write::write_to_bytes(&mut lso).unwrap_or_default();
|
||||
// Flash does not write empty LSOs to disk
|
||||
|
@ -535,14 +509,16 @@ pub fn flush<'gc>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_size<'gc>(
|
||||
fn get_size<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let NativeObject::SharedObject(shared_object) = this.native() else {
|
||||
return Ok(Value::Undefined);
|
||||
};
|
||||
let name = shared_object.read().name();
|
||||
let data = this.get("data", activation)?.coerce_to_object(activation);
|
||||
let this_obj = this.as_shared_object().unwrap();
|
||||
let name = this_obj.get_name();
|
||||
let mut lso = new_lso(activation, &name, data);
|
||||
// Flash returns 0 for empty LSOs, but the actual number of bytes (including the header) otherwise
|
||||
if lso.body.is_empty() {
|
||||
|
@ -553,7 +529,7 @@ pub fn get_size<'gc>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn send<'gc>(
|
||||
fn send<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -562,7 +538,7 @@ pub fn send<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn set_fps<'gc>(
|
||||
fn set_fps<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -571,7 +547,7 @@ pub fn set_fps<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn on_status<'gc>(
|
||||
fn on_status<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -580,7 +556,7 @@ pub fn on_status<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn on_sync<'gc>(
|
||||
fn on_sync<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
|
@ -589,21 +565,40 @@ pub fn on_sync<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn create_proto<'gc>(
|
||||
fn constructor<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
this.set_native(
|
||||
activation.context.gc_context,
|
||||
NativeObject::SharedObject(GcCell::new(
|
||||
activation.context.gc_context,
|
||||
Default::default(),
|
||||
)),
|
||||
);
|
||||
Ok(this.into())
|
||||
}
|
||||
|
||||
pub fn create_constructor<'gc>(
|
||||
context: &mut GcContext<'_, 'gc>,
|
||||
proto: Object<'gc>,
|
||||
fn_proto: Object<'gc>,
|
||||
) -> Object<'gc> {
|
||||
let shared_obj = SharedObject::empty_shared_obj(context.gc_context, proto);
|
||||
let object = shared_obj.raw_script_object();
|
||||
define_properties_on(PROTO_DECLS, context, object, fn_proto);
|
||||
shared_obj.into()
|
||||
}
|
||||
|
||||
pub fn constructor<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
Ok(this.into())
|
||||
let shared_object_proto = ScriptObject::new(context.gc_context, Some(proto));
|
||||
define_properties_on(PROTO_DECLS, context, shared_object_proto, fn_proto);
|
||||
let constructor = FunctionObject::constructor(
|
||||
context.gc_context,
|
||||
Executable::Native(constructor),
|
||||
constructor_to_fn!(constructor),
|
||||
fn_proto,
|
||||
shared_object_proto.into(),
|
||||
);
|
||||
define_properties_on(
|
||||
OBJECT_DECLS,
|
||||
context,
|
||||
constructor.raw_script_object(),
|
||||
fn_proto,
|
||||
);
|
||||
constructor
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ use crate::avm1::globals::displacement_map_filter::DisplacementMapFilter;
|
|||
use crate::avm1::globals::drop_shadow_filter::DropShadowFilter;
|
||||
use crate::avm1::globals::glow_filter::GlowFilter;
|
||||
use crate::avm1::globals::gradient_filter::GradientFilter;
|
||||
use crate::avm1::globals::shared_object::SharedObject;
|
||||
use crate::avm1::globals::transform::TransformObject;
|
||||
use crate::avm1::globals::xml::Xml;
|
||||
use crate::avm1::object::array_object::ArrayObject;
|
||||
use crate::avm1::object::shared_object::SharedObject;
|
||||
use crate::avm1::object::super_object::SuperObject;
|
||||
use crate::avm1::object::value_object::ValueObject;
|
||||
use crate::avm1::{Activation, Attribute, Error, ScriptObject, SoundObject, StageObject, Value};
|
||||
|
@ -32,7 +32,6 @@ use std::fmt::Debug;
|
|||
pub mod array_object;
|
||||
mod custom_object;
|
||||
pub mod script_object;
|
||||
pub mod shared_object;
|
||||
pub mod sound_object;
|
||||
pub mod stage_object;
|
||||
pub mod super_object;
|
||||
|
@ -59,6 +58,7 @@ pub enum NativeObject<'gc> {
|
|||
BitmapData(BitmapDataWrapper<'gc>),
|
||||
Xml(Xml<'gc>),
|
||||
XmlNode(XmlNode<'gc>),
|
||||
SharedObject(GcCell<'gc, SharedObject>),
|
||||
}
|
||||
|
||||
/// Represents an object that can be directly interacted with by the AVM
|
||||
|
@ -75,7 +75,6 @@ pub enum NativeObject<'gc> {
|
|||
SuperObject(SuperObject<'gc>),
|
||||
ValueObject(ValueObject<'gc>),
|
||||
FunctionObject(FunctionObject<'gc>),
|
||||
SharedObject(SharedObject<'gc>),
|
||||
}
|
||||
)]
|
||||
pub trait TObject<'gc>: 'gc + Collect + Into<Object<'gc>> + Clone + Copy {
|
||||
|
@ -591,11 +590,6 @@ pub trait TObject<'gc>: 'gc + Collect + Into<Object<'gc>> + Clone + Copy {
|
|||
None
|
||||
}
|
||||
|
||||
/// Get the underlying `SharedObject`, if it exists
|
||||
fn as_shared_object(&self) -> Option<SharedObject<'gc>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const ObjectPtr;
|
||||
|
||||
/// Check if this object is in the prototype chain of the specified test object.
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
use crate::impl_custom_object;
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
|
||||
use crate::avm1::{Object, ScriptObject, TObject};
|
||||
use std::fmt;
|
||||
|
||||
/// A SharedObject
|
||||
#[derive(Clone, Copy, Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct SharedObject<'gc>(GcCell<'gc, SharedObjectData<'gc>>);
|
||||
|
||||
#[derive(Clone, Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct SharedObjectData<'gc> {
|
||||
/// The underlying script object.
|
||||
base: ScriptObject<'gc>,
|
||||
|
||||
/// The local name of this shared object
|
||||
name: Option<String>,
|
||||
// In future this will also handle remote SharedObjects
|
||||
}
|
||||
|
||||
impl fmt::Debug for SharedObject<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let this = self.0.read();
|
||||
f.debug_struct("SharedObject")
|
||||
.field("name", &this.name)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> SharedObject<'gc> {
|
||||
pub fn empty_shared_obj(gc_context: MutationContext<'gc, '_>, proto: Object<'gc>) -> Self {
|
||||
SharedObject(GcCell::new(
|
||||
gc_context,
|
||||
SharedObjectData {
|
||||
base: ScriptObject::new(gc_context, Some(proto)),
|
||||
name: None,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn set_name(&self, gc_context: MutationContext<'gc, '_>, name: String) {
|
||||
self.0.write(gc_context).name = Some(name);
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> String {
|
||||
self.0.read().name.as_ref().cloned().unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for SharedObject<'gc> {
|
||||
impl_custom_object!(base {
|
||||
bare_object(as_shared_object -> SharedObject::empty_shared_obj);
|
||||
});
|
||||
}
|
|
@ -1987,7 +1987,9 @@ impl Player {
|
|||
Activation::try_from_stub(context.reborrow(), ActivationIdentifier::root("[Flush]"))
|
||||
{
|
||||
for so in avm1_activation.context.avm1_shared_objects.clone().values() {
|
||||
if let Err(e) = crate::avm1::flush(&mut avm1_activation, *so, &[]) {
|
||||
if let Err(e) =
|
||||
crate::avm1::globals::shared_object::flush(&mut avm1_activation, *so, &[])
|
||||
{
|
||||
tracing::error!("Error flushing AVM1 shared object `{:?}`: {:?}", so, e);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue