core: `NetStream` should be a self-owning pointer type.

This commit is contained in:
David Wendt 2023-03-22 20:21:55 -04:00 committed by kmeisthax
parent c104413e85
commit 273b0a4a76
8 changed files with 34 additions and 31 deletions

View File

@ -30,7 +30,7 @@ fn get_bytes_loaded<'gc>(
_args: &[Value<'gc>], _args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> { ) -> Result<Value<'gc>, Error<'gc>> {
if let NativeObject::NetStream(ns) = this.native() { if let NativeObject::NetStream(ns) = this.native() {
return Ok(ns.read().bytes_loaded().into()); return Ok(ns.bytes_loaded().into());
} }
Ok(Value::Undefined) Ok(Value::Undefined)
@ -42,7 +42,7 @@ fn get_bytes_total<'gc>(
_args: &[Value<'gc>], _args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> { ) -> Result<Value<'gc>, Error<'gc>> {
if let NativeObject::NetStream(ns) = this.native() { if let NativeObject::NetStream(ns) = this.native() {
return Ok(ns.read().bytes_total().into()); return Ok(ns.bytes_loaded().into());
} }
Ok(Value::Undefined) Ok(Value::Undefined)

View File

@ -60,7 +60,7 @@ pub enum NativeObject<'gc> {
BevelFilter(GcCell<'gc, BevelFilterObject>), BevelFilter(GcCell<'gc, BevelFilterObject>),
ColorTransform(GcCell<'gc, ColorTransformObject>), ColorTransform(GcCell<'gc, ColorTransformObject>),
TextFormat(GcCell<'gc, TextFormat>), TextFormat(GcCell<'gc, TextFormat>),
NetStream(GcCell<'gc, NetStream>), NetStream(NetStream<'gc>),
} }
/// Represents an object that can be directly interacted with by the AVM /// Represents an object that can be directly interacted with by the AVM

View File

@ -8,7 +8,7 @@ pub fn get_bytes_loaded<'gc>(
_args: &[Value<'gc>], _args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> { ) -> Result<Value<'gc>, Error<'gc>> {
if let Some(ns) = this.and_then(|o| o.as_netstream()) { 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) Ok(Value::Undefined)
@ -20,7 +20,7 @@ pub fn get_bytes_total<'gc>(
_args: &[Value<'gc>], _args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> { ) -> Result<Value<'gc>, Error<'gc>> {
if let Some(ns) = this.and_then(|o| o.as_netstream()) { 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) Ok(Value::Undefined)

View File

@ -1298,7 +1298,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
None None
} }
fn as_netstream(self) -> Option<GcCell<'gc, NetStream>> { fn as_netstream(self) -> Option<NetStream<'gc>> {
None None
} }
} }

View File

@ -34,7 +34,7 @@ pub struct NetStreamObject<'gc>(GcCell<'gc, NetStreamObjectData<'gc>>);
#[collect(no_drop)] #[collect(no_drop)]
pub struct NetStreamObjectData<'gc> { pub struct NetStreamObjectData<'gc> {
base: ScriptObjectData<'gc>, base: ScriptObjectData<'gc>,
ns: GcCell<'gc, NetStream>, ns: NetStream<'gc>,
} }
impl<'gc> TObject<'gc> for NetStreamObject<'gc> { impl<'gc> TObject<'gc> for NetStreamObject<'gc> {
@ -54,7 +54,7 @@ impl<'gc> TObject<'gc> for NetStreamObject<'gc> {
Ok(Value::Object((*self).into())) Ok(Value::Object((*self).into()))
} }
fn as_netstream(self) -> Option<GcCell<'gc, NetStream>> { fn as_netstream(self) -> Option<NetStream<'gc>> {
Some(self.0.read().ns) Some(self.0.read().ns)
} }
} }

View File

@ -107,7 +107,7 @@ pub enum VideoSource<'gc> {
movie: Arc<SwfMovie>, movie: Arc<SwfMovie>,
/// The stream the video is downloaded from. /// The stream the video is downloaded from.
stream: GcCell<'gc, NetStream>, stream: NetStream<'gc>,
/// The number of frames in the source media, if known. /// The number of frames in the source media, if known.
num_frames: Option<usize>, num_frames: Option<usize>,
@ -150,11 +150,7 @@ impl<'gc> Video<'gc> {
/// Convert this Video into a NetStream sourced video. /// Convert this Video into a NetStream sourced video.
/// ///
/// Existing video state related to the old video stream will be dropped. /// Existing video state related to the old video stream will be dropped.
pub fn attach_netstream( pub fn attach_netstream(self, context: &mut UpdateContext<'_, 'gc>, stream: NetStream<'gc>) {
self,
context: &mut UpdateContext<'_, 'gc>,
stream: GcCell<'gc, NetStream>,
) {
let movie = self.movie(); let movie = self.movie();
let mut video = self.0.write(context.gc_context); let mut video = self.0.write(context.gc_context);

View File

@ -27,7 +27,7 @@ use crate::string::AvmString;
use crate::tag_utils::SwfMovie; use crate::tag_utils::SwfMovie;
use crate::vminterface::Instantiator; use crate::vminterface::Instantiator;
use encoding_rs::UTF_8; use encoding_rs::UTF_8;
use gc_arena::{Collect, CollectionContext, GcCell}; use gc_arena::{Collect, CollectionContext};
use generational_arena::{Arena, Index}; use generational_arena::{Arena, Index};
use ruffle_render::utils::{determine_jpeg_tag_format, JpegTagFormat}; use ruffle_render::utils::{determine_jpeg_tag_format, JpegTagFormat};
use std::fmt; use std::fmt;
@ -412,7 +412,7 @@ impl<'gc> LoadManager<'gc> {
pub fn load_netstream( pub fn load_netstream(
&mut self, &mut self,
player: Weak<Mutex<Player>>, player: Weak<Mutex<Player>>,
target_stream: GcCell<'gc, NetStream>, target_stream: NetStream<'gc>,
request: Request, request: Request,
) -> OwnedFuture<(), Error> { ) -> OwnedFuture<(), Error> {
let loader = Loader::NetStream { let loader = Loader::NetStream {
@ -589,7 +589,7 @@ pub enum Loader<'gc> {
self_handle: Option<Handle>, self_handle: Option<Handle>,
/// The stream to buffer data into. /// 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 { match response {
Ok(mut 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) => { Err(err) => {
stream.write(uc.gc_context).report_error(err); stream.report_error(err);
} }
} }

View File

@ -16,7 +16,7 @@ pub struct StreamManager<'gc> {
/// ///
/// This is not the total list of all created NetStreams; only the ones /// This is not the total list of all created NetStreams; only the ones
/// that have been configured to play media. /// that have been configured to play media.
playing_streams: Vec<GcCell<'gc, NetStream>>, playing_streams: Vec<NetStream<'gc>>,
} }
impl<'gc> Default for StreamManager<'gc> { 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 /// It corresponds directly to the AVM1 and AVM2 `NetStream` classes; it's API
/// 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)]
#[collect(no_drop)]
pub struct NetStream<'gc>(GcCell<'gc, NetStreamData>);
#[derive(Clone, Debug, Collect)] #[derive(Clone, Debug, Collect)]
#[collect(require_static)] #[collect(require_static)]
pub struct NetStream { pub struct NetStreamData {
/// All data currently loaded in the stream. /// All data currently loaded in the stream.
buffer: Vec<u8>, buffer: Vec<u8>,
} }
impl NetStream { impl<'gc> NetStream<'gc> {
pub fn new<'gc>(gc_context: MutationContext<'gc, '_>) -> GcCell<'gc, Self> { pub fn new(gc_context: MutationContext<'gc, '_>) -> Self {
GcCell::allocate(gc_context, NetStream { buffer: Vec::new() }) Self(GcCell::allocate(
gc_context,
NetStreamData { buffer: Vec::new() },
))
} }
pub fn load_buffer(&mut self, data: &mut Vec<u8>) { pub fn load_buffer(self, gc_context: MutationContext<'gc, '_>, data: &mut Vec<u8>) {
self.buffer.append(data); 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. //TODO: Report an `asyncError` to AVM1 or 2.
} }
pub fn bytes_loaded(&self) -> usize { pub fn bytes_loaded(self) -> usize {
self.buffer.len() self.0.read().buffer.len()
} }
pub fn bytes_total(&self) -> usize { pub fn bytes_total(self) -> usize {
self.buffer.len() self.0.read().buffer.len()
} }
} }