diff --git a/core/src/avm1/globals/netstream.rs b/core/src/avm1/globals/netstream.rs index c444c7d62..26cec511b 100644 --- a/core/src/avm1/globals/netstream.rs +++ b/core/src/avm1/globals/netstream.rs @@ -30,7 +30,7 @@ fn get_bytes_loaded<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let NativeObject::NetStream(ns) = this.native() { - return Ok(ns.read().bytes_loaded().into()); + return Ok(ns.bytes_loaded().into()); } Ok(Value::Undefined) @@ -42,7 +42,7 @@ fn get_bytes_total<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let NativeObject::NetStream(ns) = this.native() { - return Ok(ns.read().bytes_total().into()); + return Ok(ns.bytes_loaded().into()); } Ok(Value::Undefined) diff --git a/core/src/avm1/object.rs b/core/src/avm1/object.rs index 120535ed2..8441dfbd7 100644 --- a/core/src/avm1/object.rs +++ b/core/src/avm1/object.rs @@ -60,7 +60,7 @@ pub enum NativeObject<'gc> { BevelFilter(GcCell<'gc, BevelFilterObject>), ColorTransform(GcCell<'gc, ColorTransformObject>), TextFormat(GcCell<'gc, TextFormat>), - NetStream(GcCell<'gc, NetStream>), + NetStream(NetStream<'gc>), } /// Represents an object that can be directly interacted with by the AVM diff --git a/core/src/avm2/globals/flash/net/net_stream.rs b/core/src/avm2/globals/flash/net/net_stream.rs index 7c6d83e8d..97a2a2d72 100644 --- a/core/src/avm2/globals/flash/net/net_stream.rs +++ b/core/src/avm2/globals/flash/net/net_stream.rs @@ -8,7 +8,7 @@ pub fn get_bytes_loaded<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let Some(ns) = this.and_then(|o| o.as_netstream()) { - return Ok(ns.read().bytes_loaded().into()); + return Ok(ns.bytes_loaded().into()); } Ok(Value::Undefined) @@ -20,7 +20,7 @@ pub fn get_bytes_total<'gc>( _args: &[Value<'gc>], ) -> Result, Error<'gc>> { if let Some(ns) = this.and_then(|o| o.as_netstream()) { - return Ok(ns.read().bytes_total().into()); + return Ok(ns.bytes_total().into()); } Ok(Value::Undefined) diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index 5a436fc05..b18da115e 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -1298,7 +1298,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy None } - fn as_netstream(self) -> Option> { + fn as_netstream(self) -> Option> { None } } diff --git a/core/src/avm2/object/netstream_object.rs b/core/src/avm2/object/netstream_object.rs index aed22219e..c83005bb6 100644 --- a/core/src/avm2/object/netstream_object.rs +++ b/core/src/avm2/object/netstream_object.rs @@ -34,7 +34,7 @@ pub struct NetStreamObject<'gc>(GcCell<'gc, NetStreamObjectData<'gc>>); #[collect(no_drop)] pub struct NetStreamObjectData<'gc> { base: ScriptObjectData<'gc>, - ns: GcCell<'gc, NetStream>, + ns: NetStream<'gc>, } impl<'gc> TObject<'gc> for NetStreamObject<'gc> { @@ -54,7 +54,7 @@ impl<'gc> TObject<'gc> for NetStreamObject<'gc> { Ok(Value::Object((*self).into())) } - fn as_netstream(self) -> Option> { + fn as_netstream(self) -> Option> { Some(self.0.read().ns) } } diff --git a/core/src/display_object/video.rs b/core/src/display_object/video.rs index cb1542237..c704452db 100644 --- a/core/src/display_object/video.rs +++ b/core/src/display_object/video.rs @@ -107,7 +107,7 @@ pub enum VideoSource<'gc> { movie: Arc, /// The stream the video is downloaded from. - stream: GcCell<'gc, NetStream>, + stream: NetStream<'gc>, /// The number of frames in the source media, if known. num_frames: Option, @@ -150,11 +150,7 @@ impl<'gc> Video<'gc> { /// Convert this Video into a NetStream sourced video. /// /// Existing video state related to the old video stream will be dropped. - pub fn attach_netstream( - self, - context: &mut UpdateContext<'_, 'gc>, - stream: GcCell<'gc, NetStream>, - ) { + pub fn attach_netstream(self, context: &mut UpdateContext<'_, 'gc>, stream: NetStream<'gc>) { let movie = self.movie(); let mut video = self.0.write(context.gc_context); diff --git a/core/src/loader.rs b/core/src/loader.rs index 1318a7e37..fc2d83658 100644 --- a/core/src/loader.rs +++ b/core/src/loader.rs @@ -27,7 +27,7 @@ use crate::string::AvmString; use crate::tag_utils::SwfMovie; use crate::vminterface::Instantiator; use encoding_rs::UTF_8; -use gc_arena::{Collect, CollectionContext, GcCell}; +use gc_arena::{Collect, CollectionContext}; use generational_arena::{Arena, Index}; use ruffle_render::utils::{determine_jpeg_tag_format, JpegTagFormat}; use std::fmt; @@ -412,7 +412,7 @@ impl<'gc> LoadManager<'gc> { pub fn load_netstream( &mut self, player: Weak>, - target_stream: GcCell<'gc, NetStream>, + target_stream: NetStream<'gc>, request: Request, ) -> OwnedFuture<(), Error> { let loader = Loader::NetStream { @@ -589,7 +589,7 @@ pub enum Loader<'gc> { self_handle: Option, /// The stream to buffer data into. - target_stream: GcCell<'gc, NetStream>, + target_stream: NetStream<'gc>, }, } @@ -1368,10 +1368,10 @@ impl<'gc> Loader<'gc> { match response { Ok(mut response) => { - stream.write(uc.gc_context).load_buffer(&mut response.body); + stream.load_buffer(uc.gc_context, &mut response.body); } Err(err) => { - stream.write(uc.gc_context).report_error(err); + stream.report_error(err); } } diff --git a/core/src/streams.rs b/core/src/streams.rs index d93029e14..137abf678 100644 --- a/core/src/streams.rs +++ b/core/src/streams.rs @@ -16,7 +16,7 @@ pub struct StreamManager<'gc> { /// /// This is not the total list of all created NetStreams; only the ones /// that have been configured to play media. - playing_streams: Vec>, + playing_streams: Vec>, } impl<'gc> Default for StreamManager<'gc> { @@ -56,31 +56,38 @@ impl<'gc> StreamManager<'gc> { /// /// It corresponds directly to the AVM1 and AVM2 `NetStream` classes; it's API /// 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>); + #[derive(Clone, Debug, Collect)] #[collect(require_static)] -pub struct NetStream { +pub struct NetStreamData { /// All data currently loaded in the stream. buffer: Vec, } -impl NetStream { - pub fn new<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Self> { - GcCell::allocate(gc_context, NetStream { buffer: Vec::new() }) +impl<'gc> NetStream<'gc> { + pub fn new(gc_context: MutationContext<'gc, '_>) -> Self { + Self(GcCell::allocate( + gc_context, + NetStreamData { buffer: Vec::new() }, + )) } - pub fn load_buffer(&mut self, data: &mut Vec) { - self.buffer.append(data); + pub fn load_buffer(self, gc_context: MutationContext<'gc, '_>, data: &mut Vec) { + self.0.write(gc_context).buffer.append(data); } - pub fn report_error(&mut self, _error: Error) { + pub fn report_error(self, _error: Error) { //TODO: Report an `asyncError` to AVM1 or 2. } - pub fn bytes_loaded(&self) -> usize { - self.buffer.len() + pub fn bytes_loaded(self) -> usize { + self.0.read().buffer.len() } - pub fn bytes_total(&self) -> usize { - self.buffer.len() + pub fn bytes_total(self) -> usize { + self.0.read().buffer.len() } }