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>],
) -> Result<Value<'gc>, 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<Value<'gc>, 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)

View File

@ -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

View File

@ -8,7 +8,7 @@ pub fn get_bytes_loaded<'gc>(
_args: &[Value<'gc>],
) -> Result<Value<'gc>, 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<Value<'gc>, 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)

View File

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

View File

@ -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<GcCell<'gc, NetStream>> {
fn as_netstream(self) -> Option<NetStream<'gc>> {
Some(self.0.read().ns)
}
}

View File

@ -107,7 +107,7 @@ pub enum VideoSource<'gc> {
movie: Arc<SwfMovie>,
/// 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<usize>,
@ -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);

View File

@ -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<Mutex<Player>>,
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<Handle>,
/// 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);
}
}

View File

@ -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<GcCell<'gc, NetStream>>,
playing_streams: Vec<NetStream<'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
/// 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<u8>,
}
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<u8>) {
self.buffer.append(data);
pub fn load_buffer(self, gc_context: MutationContext<'gc, '_>, data: &mut Vec<u8>) {
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()
}
}