avm2: Basic FileReference object boilerplate

This commit is contained in:
Tom Schuster 2023-11-25 13:19:03 +01:00
parent 430463ecd3
commit e7b8b75d07
6 changed files with 85 additions and 1 deletions

View File

@ -167,6 +167,7 @@ pub struct SystemClasses<'gc> {
pub shaderfilter: ClassObject<'gc>,
pub statusevent: ClassObject<'gc>,
pub contextmenuevent: ClassObject<'gc>,
pub filereference: ClassObject<'gc>,
pub font: ClassObject<'gc>,
pub textline: ClassObject<'gc>,
pub sampledataevent: ClassObject<'gc>,
@ -296,6 +297,7 @@ impl<'gc> SystemClasses<'gc> {
shaderfilter: object,
statusevent: object,
contextmenuevent: object,
filereference: object,
font: object,
textline: object,
sampledataevent: object,
@ -806,6 +808,7 @@ fn load_playerglobal<'gc>(
("flash.media", "SoundTransform", soundtransform),
("flash.media", "Video", video),
("flash.net", "URLVariables", urlvariables),
("flash.net", "FileReference", filereference),
("flash.utils", "ByteArray", bytearray),
("flash.system", "ApplicationDomain", application_domain),
("flash.text", "Font", font),

View File

@ -5,6 +5,7 @@ use crate::avm2::object::TObject;
use crate::avm2::{Activation, Error, Object, Value};
pub mod local_connection;
pub mod file_reference;
pub mod net_connection;
pub mod net_stream;
pub mod object_encoding;

View File

@ -4,6 +4,7 @@ package flash.net
import flash.utils.ByteArray;
import __ruffle__.stub_method;
[Ruffle(InstanceAllocator)]
public class FileReference extends EventDispatcher
{
private var _creationDate: Date;

View File

@ -0,0 +1 @@
pub use crate::avm2::object::file_reference_allocator;

View File

@ -40,6 +40,7 @@ mod dispatch_object;
mod domain_object;
mod error_object;
mod event_object;
mod file_reference_object;
mod font_object;
mod function_object;
mod index_buffer_3d_object;
@ -87,6 +88,7 @@ pub use crate::avm2::object::domain_object::{
};
pub use crate::avm2::object::error_object::{error_allocator, ErrorObject, ErrorObjectWeak};
pub use crate::avm2::object::event_object::{event_allocator, EventObject, EventObjectWeak};
pub use crate::avm2::object::file_reference_object::{file_reference_allocator, FileReferenceObject, FileReferenceObjectWeak};
pub use crate::avm2::object::font_object::{font_allocator, FontObject, FontObjectWeak};
pub use crate::avm2::object::function_object::{
function_allocator, FunctionObject, FunctionObjectWeak,
@ -191,8 +193,9 @@ use crate::font::Font;
ResponderObject(ResponderObject<'gc>),
ShaderDataObject(ShaderDataObject<'gc>),
SocketObject(SocketObject<'gc>),
FileReferenceObject(FileReferenceObject<'gc>),
FontObject(FontObject<'gc>),
LocalConnectionObject(LocalConnectionObject<'gc>)
LocalConnectionObject(LocalConnectionObject<'gc>),
}
)]
pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy {
@ -1420,6 +1423,10 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
fn as_local_connection_object(&self) -> Option<LocalConnectionObject<'gc>> {
None
}
fn as_file_reference(&self) -> Option<FileReferenceObject<'gc>> {
None
}
}
pub enum ObjectPtr {}
@ -1468,6 +1475,7 @@ impl<'gc> Object<'gc> {
Self::ResponderObject(o) => WeakObject::ResponderObject(ResponderObjectWeak(GcCell::downgrade(o.0))),
Self::ShaderDataObject(o) => WeakObject::ShaderDataObject(ShaderDataObjectWeak(Gc::downgrade(o.0))),
Self::SocketObject(o) => WeakObject::SocketObject(SocketObjectWeak(Gc::downgrade(o.0))),
Self::FileReferenceObject(o) => WeakObject::FileReferenceObject(FileReferenceObjectWeak(Gc::downgrade(o.0))),
Self::FontObject(o) => WeakObject::FontObject(FontObjectWeak(GcCell::downgrade(o.0))),
Self::LocalConnectionObject(o) => WeakObject::LocalConnectionObject(LocalConnectionObjectWeak(GcCell::downgrade(o.0))),
}
@ -1528,6 +1536,7 @@ pub enum WeakObject<'gc> {
ResponderObject(ResponderObjectWeak<'gc>),
ShaderDataObject(ShaderDataObjectWeak<'gc>),
SocketObject(SocketObjectWeak<'gc>),
FileReferenceObject(FileReferenceObjectWeak<'gc>),
FontObject(FontObjectWeak<'gc>),
LocalConnectionObject(LocalConnectionObjectWeak<'gc>),
}
@ -1571,6 +1580,7 @@ impl<'gc> WeakObject<'gc> {
Self::ResponderObject(o) => ResponderObject(o.0.upgrade(mc)?).into(),
Self::ShaderDataObject(o) => ShaderDataObject(o.0.upgrade(mc)?).into(),
Self::SocketObject(o) => SocketObject(o.0.upgrade(mc)?).into(),
Self::FileReferenceObject(o) => FileReferenceObject(o.0.upgrade(mc)?).into(),
Self::FontObject(o) => FontObject(o.0.upgrade(mc)?).into(),
Self::LocalConnectionObject(o) => LocalConnectionObject(o.0.upgrade(mc)?).into(),
})

View File

@ -0,0 +1,68 @@
use crate::avm2::object::script_object::ScriptObjectData;
use crate::avm2::object::{ClassObject, Object, ObjectPtr, TObject};
use crate::avm2::value::Value;
use crate::avm2::{Activation, Error};
use gc_arena::barrier::unlock;
use gc_arena::{lock::RefLock, Collect, Gc};
use gc_arena::{GcWeak, Mutation};
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::fmt;
pub fn file_reference_allocator<'gc>(
class: ClassObject<'gc>,
activation: &mut Activation<'_, 'gc>,
) -> Result<Object<'gc>, Error<'gc>> {
let base = ScriptObjectData::new(class).into();
Ok(FileReferenceObject(Gc::new(
activation.context.gc(),
FileReferenceObjectData {
base,
},
))
.into())
}
#[derive(Clone, Collect, Copy)]
#[collect(no_drop)]
pub struct FileReferenceObject<'gc>(pub Gc<'gc, FileReferenceObjectData<'gc>>);
#[derive(Clone, Collect, Copy, Debug)]
#[collect(no_drop)]
pub struct FileReferenceObjectWeak<'gc>(pub GcWeak<'gc, FileReferenceObjectData<'gc>>);
impl<'gc> TObject<'gc> for FileReferenceObject<'gc> {
fn base(&self) -> Ref<ScriptObjectData<'gc>> {
self.0.base.borrow()
}
fn base_mut(&self, mc: &Mutation<'gc>) -> RefMut<ScriptObjectData<'gc>> {
unlock!(Gc::write(mc, self.0), FileReferenceObjectData, base).borrow_mut()
}
fn as_ptr(&self) -> *const ObjectPtr {
Gc::as_ptr(self.0) as *const ObjectPtr
}
fn value_of(&self, _mc: &Mutation<'gc>) -> Result<Value<'gc>, Error<'gc>> {
Ok(Value::Object(Object::from(*self)))
}
fn as_file_reference(&self) -> Option<FileReferenceObject<'gc>> {
Some(*self)
}
}
#[derive(Collect)]
#[collect(no_drop)]
pub struct FileReferenceObjectData<'gc> {
/// Base script object
base: RefLock<ScriptObjectData<'gc>>,
}
impl fmt::Debug for FileReferenceObject<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "FileReferenceObject")
}
}