core: Make the `NetStream`/AVM link bidirectional

This commit is contained in:
David Wendt 2023-04-21 20:15:46 -04:00 committed by kmeisthax
parent 067474dea5
commit da2ef5392e
3 changed files with 22 additions and 12 deletions

View File

@ -10,7 +10,7 @@ pub fn constructor<'gc>(
this: Object<'gc>, this: Object<'gc>,
_args: &[Value<'gc>], _args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> { ) -> Result<Value<'gc>, Error<'gc>> {
let netstream = NetStream::new(activation.context.gc_context); let netstream = NetStream::new(activation.context.gc_context, Some(this.into()));
this.set_native( this.set_native(
activation.context.gc_context, activation.context.gc_context,
NativeObject::NetStream(netstream), NativeObject::NetStream(netstream),

View File

@ -15,15 +15,16 @@ pub fn netstream_allocator<'gc>(
activation: &mut Activation<'_, 'gc>, activation: &mut Activation<'_, 'gc>,
) -> Result<Object<'gc>, Error<'gc>> { ) -> Result<Object<'gc>, Error<'gc>> {
let base = ScriptObjectData::new(class); let base = ScriptObjectData::new(class);
let ns = NetStream::new(activation.context.gc_context, None);
Ok(NetStreamObject(GcCell::allocate( let this: Object<'gc> = NetStreamObject(GcCell::allocate(
activation.context.gc_context, activation.context.gc_context,
NetStreamObjectData { NetStreamObjectData { base, ns },
base,
ns: NetStream::new(activation.context.gc_context),
},
)) ))
.into()) .into();
ns.set_avm_object(activation.context.gc_context, this.into());
Ok(this)
} }
#[derive(Clone, Collect, Copy)] #[derive(Clone, Collect, Copy)]

View File

@ -4,6 +4,7 @@ use crate::backend::navigator::Request;
use crate::context::UpdateContext; use crate::context::UpdateContext;
use crate::loader::Error; use crate::loader::Error;
use crate::string::AvmString; use crate::string::AvmString;
use crate::vminterface::AvmObject;
use flv_rs::{ use flv_rs::{
AudioData as FlvAudioData, Error as FlvError, FlvReader, Header as FlvHeader, AudioData as FlvAudioData, Error as FlvError, FlvReader, Header as FlvHeader,
ScriptData as FlvScriptData, Tag as FlvTag, TagData as FlvTagData, Value as FlvValue, 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. /// is intended to be a VM-agnostic version of those.
#[derive(Clone, Debug, Collect, Copy)] #[derive(Clone, Debug, Collect, Copy)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct NetStream<'gc>(GcCell<'gc, NetStreamData>); pub struct NetStream<'gc>(GcCell<'gc, NetStreamData<'gc>>);
impl<'gc> PartialEq for NetStream<'gc> { impl<'gc> PartialEq for NetStream<'gc> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
@ -136,8 +137,8 @@ pub enum NetStreamType {
} }
#[derive(Clone, Debug, Collect)] #[derive(Clone, Debug, Collect)]
#[collect(require_static)] #[collect(no_drop)]
pub struct NetStreamData { pub struct NetStreamData<'gc> {
/// All data currently loaded in the stream. /// All data currently loaded in the stream.
buffer: Vec<u8>, buffer: Vec<u8>,
@ -167,10 +168,13 @@ pub struct NetStreamData {
/// Any `Video`s on the stage will display the bitmap here when attached to /// Any `Video`s on the stage will display the bitmap here when attached to
/// this `NetStream`. /// this `NetStream`.
last_decoded_bitmap: Option<BitmapInfo>, last_decoded_bitmap: Option<BitmapInfo>,
/// The AVM side of this stream.
avm_object: Option<AvmObject<'gc>>,
} }
impl<'gc> NetStream<'gc> { impl<'gc> NetStream<'gc> {
pub fn new(gc_context: MutationContext<'gc, '_>) -> Self { pub fn new(gc_context: MutationContext<'gc, '_>, avm_object: Option<AvmObject<'gc>>) -> Self {
Self(GcCell::allocate( Self(GcCell::allocate(
gc_context, gc_context,
NetStreamData { NetStreamData {
@ -180,10 +184,15 @@ impl<'gc> NetStream<'gc> {
stream_type: None, stream_type: None,
stream_time: 0.0, stream_time: 0.0,
last_decoded_bitmap: None, 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<u8>) { pub fn load_buffer(self, gc_context: MutationContext<'gc, '_>, data: &mut Vec<u8>) {
self.0.write(gc_context).buffer.append(data); self.0.write(gc_context).buffer.append(data);
} }