avm2: Convert SharedObject to AS3
This commit is contained in:
parent
f3ebb0c297
commit
e90d595cb3
|
@ -86,7 +86,6 @@ pub struct SystemClasses<'gc> {
|
||||||
pub bitmapdata: ClassObject<'gc>,
|
pub bitmapdata: ClassObject<'gc>,
|
||||||
pub date: ClassObject<'gc>,
|
pub date: ClassObject<'gc>,
|
||||||
pub qname: ClassObject<'gc>,
|
pub qname: ClassObject<'gc>,
|
||||||
pub sharedobject: ClassObject<'gc>,
|
|
||||||
pub mouseevent: ClassObject<'gc>,
|
pub mouseevent: ClassObject<'gc>,
|
||||||
pub progressevent: ClassObject<'gc>,
|
pub progressevent: ClassObject<'gc>,
|
||||||
pub textevent: ClassObject<'gc>,
|
pub textevent: ClassObject<'gc>,
|
||||||
|
@ -172,7 +171,6 @@ impl<'gc> SystemClasses<'gc> {
|
||||||
bitmapdata: object,
|
bitmapdata: object,
|
||||||
date: object,
|
date: object,
|
||||||
qname: object,
|
qname: object,
|
||||||
sharedobject: object,
|
|
||||||
mouseevent: object,
|
mouseevent: object,
|
||||||
progressevent: object,
|
progressevent: object,
|
||||||
textevent: object,
|
textevent: object,
|
||||||
|
@ -572,14 +570,6 @@ pub fn load_player_globals<'gc>(
|
||||||
script
|
script
|
||||||
);
|
);
|
||||||
|
|
||||||
// package `flash.net`
|
|
||||||
avm2_system_class!(
|
|
||||||
sharedobject,
|
|
||||||
activation,
|
|
||||||
flash::net::sharedobject::create_class(mc),
|
|
||||||
script
|
|
||||||
);
|
|
||||||
|
|
||||||
// package `flash.text`
|
// package `flash.text`
|
||||||
avm2_system_class!(
|
avm2_system_class!(
|
||||||
textfield,
|
textfield,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::avm2::object::TObject;
|
||||||
use crate::avm2::{Activation, Error, Multiname, Object, Value};
|
use crate::avm2::{Activation, Error, Multiname, Object, Value};
|
||||||
|
|
||||||
pub mod object_encoding;
|
pub mod object_encoding;
|
||||||
pub mod sharedobject;
|
pub mod shared_object;
|
||||||
pub mod url_loader;
|
pub mod url_loader;
|
||||||
|
|
||||||
/// Implements `flash.net.navigateToURL`
|
/// Implements `flash.net.navigateToURL`
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
package flash.net
|
||||||
|
{
|
||||||
|
import flash.events.EventDispatcher;
|
||||||
|
|
||||||
|
namespace ruffle = "__ruffle__";
|
||||||
|
|
||||||
|
public class SharedObject extends EventDispatcher
|
||||||
|
{
|
||||||
|
public function SharedObject()
|
||||||
|
{
|
||||||
|
this.data = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: We currently always use AMF3 serialization.
|
||||||
|
// If you implement the `defaultObjectEncoding` or `objectEncoding`,
|
||||||
|
// you will need to adjust the serialization and deserialization code
|
||||||
|
// to work with AMF0.
|
||||||
|
|
||||||
|
native public static function getLocal(name:String, localPath:String = null, secure:Boolean = false): SharedObject;
|
||||||
|
|
||||||
|
native public function flush(minDiskSpace:int = 0) : String;
|
||||||
|
native public function close() : void;
|
||||||
|
native public function clear() : void;
|
||||||
|
|
||||||
|
// note: this is supposed to be a read-only property
|
||||||
|
public var data: Object;
|
||||||
|
|
||||||
|
// note: this is supposed to be a read-only property
|
||||||
|
public var size: uint;
|
||||||
|
|
||||||
|
ruffle var _ruffleName: String;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,49 +1,17 @@
|
||||||
//! `flash.net.SharedObject` builtin/prototype
|
//! `flash.net.SharedObject` builtin/prototype
|
||||||
|
|
||||||
use crate::avm2::class::{Class, ClassAttributes};
|
|
||||||
use crate::avm2::method::{Method, NativeMethodImpl};
|
|
||||||
use crate::avm2::object::TObject;
|
use crate::avm2::object::TObject;
|
||||||
use crate::avm2::traits::Trait;
|
|
||||||
use crate::avm2::Multiname;
|
use crate::avm2::Multiname;
|
||||||
use crate::avm2::{Activation, Error, Namespace, Object, QName, Value};
|
use crate::avm2::{Activation, Error, Namespace, Object, Value};
|
||||||
use crate::display_object::DisplayObject;
|
use crate::display_object::DisplayObject;
|
||||||
use crate::display_object::TDisplayObject;
|
use crate::display_object::TDisplayObject;
|
||||||
use crate::string::AvmString;
|
use crate::string::AvmString;
|
||||||
use flash_lso::types::{AMFVersion, Lso};
|
use flash_lso::types::{AMFVersion, Lso};
|
||||||
use gc_arena::{GcCell, MutationContext};
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
fn instance_init<'gc>(
|
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
|
||||||
this: Option<Object<'gc>>,
|
|
||||||
_args: &[Value<'gc>],
|
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
|
||||||
if let Some(mut this) = this {
|
|
||||||
activation.super_init(this, &[])?;
|
|
||||||
|
|
||||||
let data = activation
|
|
||||||
.context
|
|
||||||
.avm2
|
|
||||||
.classes()
|
|
||||||
.object
|
|
||||||
.construct(activation, &[])?;
|
|
||||||
this.set_property(&Multiname::public("data"), data.into(), activation)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Value::Undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn class_init<'gc>(
|
|
||||||
_activation: &mut Activation<'_, 'gc, '_>,
|
|
||||||
_this: Option<Object<'gc>>,
|
|
||||||
_args: &[Value<'gc>],
|
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
|
||||||
Ok(Value::Undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_local<'gc>(
|
pub fn get_local<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
_this: Option<Object<'gc>>,
|
this: Option<Object<'gc>>,
|
||||||
args: &[Value<'gc>],
|
args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
// TODO: It appears that Flash does some kind of escaping here:
|
// TODO: It appears that Flash does some kind of escaping here:
|
||||||
|
@ -169,11 +137,11 @@ pub fn get_local<'gc>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data property only should exist when created with getLocal/Remote
|
// Data property only should exist when created with getLocal/Remote
|
||||||
let constructor = activation.avm2().classes().sharedobject;
|
let sharedobject_cls = this.unwrap(); // `this` of a static method is the class
|
||||||
let mut this = constructor.construct(activation, &[])?;
|
let mut this = sharedobject_cls.construct(activation, &[])?;
|
||||||
|
|
||||||
// Set the internal name
|
// Set the internal name
|
||||||
let ruffle_name = Multiname::new(Namespace::Private("".into()), "_ruffleName");
|
let ruffle_name = Multiname::new(Namespace::Namespace("__ruffle__".into()), "_ruffleName");
|
||||||
this.set_property(
|
this.set_property(
|
||||||
&ruffle_name,
|
&ruffle_name,
|
||||||
AvmString::new_utf8(activation.context.gc_context, &full_name).into(),
|
AvmString::new_utf8(activation.context.gc_context, &full_name).into(),
|
||||||
|
@ -218,7 +186,7 @@ pub fn flush<'gc>(
|
||||||
.get_property(&Multiname::public("data"), activation)?
|
.get_property(&Multiname::public("data"), activation)?
|
||||||
.coerce_to_object(activation)?;
|
.coerce_to_object(activation)?;
|
||||||
|
|
||||||
let ruffle_name = Multiname::new(Namespace::Private("".into()), "_ruffleName");
|
let ruffle_name = Multiname::new(Namespace::Namespace("__ruffle__".into()), "_ruffleName");
|
||||||
let name = this
|
let name = this
|
||||||
.get_property(&ruffle_name, activation)?
|
.get_property(&ruffle_name, activation)?
|
||||||
.coerce_to_string(activation)?;
|
.coerce_to_string(activation)?;
|
||||||
|
@ -260,50 +228,3 @@ pub fn clear<'gc>(
|
||||||
log::warn!("SharedObject.clear - not yet implemented");
|
log::warn!("SharedObject.clear - not yet implemented");
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct `SharedObject`'s class.
|
|
||||||
/// NOTE: We currently always use AMF3 serialization.
|
|
||||||
/// If you implement the `defaultObjectEncoding` or `objectEncoding`,
|
|
||||||
/// you will need to adjust the serialization and deserialization code
|
|
||||||
/// to work with AMF0.
|
|
||||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
|
||||||
let class = Class::new(
|
|
||||||
QName::new(Namespace::package("flash.net"), "SharedObject"),
|
|
||||||
Some(Multiname::new(
|
|
||||||
Namespace::package("flash.events"),
|
|
||||||
"EventDispatcher",
|
|
||||||
)),
|
|
||||||
Method::from_builtin(instance_init, "<SharedObject instance initializer>", mc),
|
|
||||||
Method::from_builtin(class_init, "<SharedObject class initializer>", mc),
|
|
||||||
mc,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut write = class.write(mc);
|
|
||||||
write.set_attributes(ClassAttributes::SEALED);
|
|
||||||
|
|
||||||
write.define_instance_trait(Trait::from_slot(
|
|
||||||
QName::new(Namespace::public(), "data"),
|
|
||||||
Multiname::public("Object"),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
write.define_instance_trait(Trait::from_slot(
|
|
||||||
QName::new(Namespace::public(), "size"),
|
|
||||||
Multiname::public("uint"),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
write.define_instance_trait(Trait::from_slot(
|
|
||||||
QName::new(Namespace::private(""), "_ruffleName"),
|
|
||||||
Multiname::public("String"),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
const PUBLIC_CLASS_METHODS: &[(&str, NativeMethodImpl)] = &[("getLocal", get_local)];
|
|
||||||
write.define_public_builtin_class_methods(mc, PUBLIC_CLASS_METHODS);
|
|
||||||
|
|
||||||
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] =
|
|
||||||
&[("flush", flush), ("close", close), ("clear", clear)];
|
|
||||||
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
|
|
||||||
class
|
|
||||||
}
|
|
|
@ -178,6 +178,7 @@ include "flash/net/NetGroupReplicationStrategy.as"
|
||||||
include "flash/net/NetGroupSendMode.as"
|
include "flash/net/NetGroupSendMode.as"
|
||||||
include "flash/net/NetGroupSendResult.as"
|
include "flash/net/NetGroupSendResult.as"
|
||||||
include "flash/net/ObjectEncoding.as"
|
include "flash/net/ObjectEncoding.as"
|
||||||
|
include "flash/net/SharedObject.as"
|
||||||
include "flash/net/SharedObjectFlushStatus.as"
|
include "flash/net/SharedObjectFlushStatus.as"
|
||||||
include "flash/net/URLLoader.as"
|
include "flash/net/URLLoader.as"
|
||||||
include "flash/net/URLLoaderDataFormat.as"
|
include "flash/net/URLLoaderDataFormat.as"
|
||||||
|
|
|
@ -1805,7 +1805,7 @@ impl Player {
|
||||||
let mut avm2_activation =
|
let mut avm2_activation =
|
||||||
Avm2Activation::from_nothing(avm1_activation.context.reborrow());
|
Avm2Activation::from_nothing(avm1_activation.context.reborrow());
|
||||||
for so in avm2_activation.context.avm2_shared_objects.clone().values() {
|
for so in avm2_activation.context.avm2_shared_objects.clone().values() {
|
||||||
if let Err(e) = crate::avm2::globals::flash::net::sharedobject::flush(
|
if let Err(e) = crate::avm2::globals::flash::net::shared_object::flush(
|
||||||
&mut avm2_activation,
|
&mut avm2_activation,
|
||||||
Some(*so),
|
Some(*so),
|
||||||
&[],
|
&[],
|
||||||
|
|
Loading…
Reference in New Issue