From da2ef5392ec702b78d3eecfdf2bc55db446d1d26 Mon Sep 17 00:00:00 2001 From: David Wendt Date: Fri, 21 Apr 2023 20:15:46 -0400 Subject: [PATCH] core: Make the `NetStream`/AVM link bidirectional --- core/src/avm1/globals/netstream.rs | 2 +- core/src/avm2/object/netstream_object.rs | 15 ++++++++------- core/src/streams.rs | 17 +++++++++++++---- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/core/src/avm1/globals/netstream.rs b/core/src/avm1/globals/netstream.rs index 9806a7bcc..20e4a161c 100644 --- a/core/src/avm1/globals/netstream.rs +++ b/core/src/avm1/globals/netstream.rs @@ -10,7 +10,7 @@ pub fn constructor<'gc>( this: Object<'gc>, _args: &[Value<'gc>], ) -> Result, Error<'gc>> { - let netstream = NetStream::new(activation.context.gc_context); + let netstream = NetStream::new(activation.context.gc_context, Some(this.into())); this.set_native( activation.context.gc_context, NativeObject::NetStream(netstream), diff --git a/core/src/avm2/object/netstream_object.rs b/core/src/avm2/object/netstream_object.rs index 393fc7436..6a7fdbe51 100644 --- a/core/src/avm2/object/netstream_object.rs +++ b/core/src/avm2/object/netstream_object.rs @@ -15,15 +15,16 @@ pub fn netstream_allocator<'gc>( activation: &mut Activation<'_, 'gc>, ) -> Result, Error<'gc>> { let base = ScriptObjectData::new(class); - - Ok(NetStreamObject(GcCell::allocate( + let ns = NetStream::new(activation.context.gc_context, None); + let this: Object<'gc> = NetStreamObject(GcCell::allocate( activation.context.gc_context, - NetStreamObjectData { - base, - ns: NetStream::new(activation.context.gc_context), - }, + NetStreamObjectData { base, ns }, )) - .into()) + .into(); + + ns.set_avm_object(activation.context.gc_context, this.into()); + + Ok(this) } #[derive(Clone, Collect, Copy)] diff --git a/core/src/streams.rs b/core/src/streams.rs index a4e233b3d..c9b802fcd 100644 --- a/core/src/streams.rs +++ b/core/src/streams.rs @@ -4,6 +4,7 @@ use crate::backend::navigator::Request; use crate::context::UpdateContext; use crate::loader::Error; use crate::string::AvmString; +use crate::vminterface::AvmObject; use flv_rs::{ AudioData as FlvAudioData, Error as FlvError, FlvReader, Header as FlvHeader, ScriptData as FlvScriptData, Tag as FlvTag, TagData as FlvTagData, Value as FlvValue, @@ -107,7 +108,7 @@ impl<'gc> StreamManager<'gc> { /// is intended to be a VM-agnostic version of those. #[derive(Clone, Debug, Collect, Copy)] #[collect(no_drop)] -pub struct NetStream<'gc>(GcCell<'gc, NetStreamData>); +pub struct NetStream<'gc>(GcCell<'gc, NetStreamData<'gc>>); impl<'gc> PartialEq for NetStream<'gc> { fn eq(&self, other: &Self) -> bool { @@ -136,8 +137,8 @@ pub enum NetStreamType { } #[derive(Clone, Debug, Collect)] -#[collect(require_static)] -pub struct NetStreamData { +#[collect(no_drop)] +pub struct NetStreamData<'gc> { /// All data currently loaded in the stream. buffer: Vec, @@ -167,10 +168,13 @@ pub struct NetStreamData { /// Any `Video`s on the stage will display the bitmap here when attached to /// this `NetStream`. last_decoded_bitmap: Option, + + /// The AVM side of this stream. + avm_object: Option>, } impl<'gc> NetStream<'gc> { - pub fn new(gc_context: MutationContext<'gc, '_>) -> Self { + pub fn new(gc_context: MutationContext<'gc, '_>, avm_object: Option>) -> Self { Self(GcCell::allocate( gc_context, NetStreamData { @@ -180,10 +184,15 @@ impl<'gc> NetStream<'gc> { stream_type: None, stream_time: 0.0, last_decoded_bitmap: None, + avm_object, }, )) } + pub fn set_avm_object(self, gc_context: MutationContext<'gc, '_>, avm_object: AvmObject<'gc>) { + self.0.write(gc_context).avm_object = Some(avm_object); + } + pub fn load_buffer(self, gc_context: MutationContext<'gc, '_>, data: &mut Vec) { self.0.write(gc_context).buffer.append(data); }