core: Stub implementation of NetStream loading.
The actual use cases for `NetStream` almost certainly require streaming download but I'm not ready to implement that just yet.
This commit is contained in:
parent
db7ff77c4e
commit
38ed0dada4
|
@ -22,11 +22,12 @@ use crate::events::ClipEvent;
|
|||
use crate::frame_lifecycle::catchup_display_object_to_frame;
|
||||
use crate::limits::ExecutionLimit;
|
||||
use crate::player::Player;
|
||||
use crate::streams::NetStream;
|
||||
use crate::string::AvmString;
|
||||
use crate::tag_utils::SwfMovie;
|
||||
use crate::vminterface::Instantiator;
|
||||
use encoding_rs::UTF_8;
|
||||
use gc_arena::{Collect, CollectionContext};
|
||||
use gc_arena::{Collect, CollectionContext, GcCell};
|
||||
use generational_arena::{Arena, Index};
|
||||
use ruffle_render::utils::{determine_jpeg_tag_format, JpegTagFormat};
|
||||
use std::fmt;
|
||||
|
@ -148,6 +149,9 @@ pub enum Error {
|
|||
#[error("Non-sound loader spawned as sound loader")]
|
||||
NotSoundLoader,
|
||||
|
||||
#[error("Non-NetStream loader spawned as NetStream loader")]
|
||||
NotNetStreamLoader,
|
||||
|
||||
#[error("Could not fetch: {0}")]
|
||||
FetchError(String),
|
||||
|
||||
|
@ -211,7 +215,8 @@ impl<'gc> LoadManager<'gc> {
|
|||
| Loader::LoadVars { self_handle, .. }
|
||||
| Loader::LoadURLLoader { self_handle, .. }
|
||||
| Loader::SoundAvm1 { self_handle, .. }
|
||||
| Loader::SoundAvm2 { self_handle, .. } => *self_handle = Some(handle),
|
||||
| Loader::SoundAvm2 { self_handle, .. }
|
||||
| Loader::NetStream { self_handle, .. } => *self_handle = Some(handle),
|
||||
}
|
||||
handle
|
||||
}
|
||||
|
@ -404,6 +409,21 @@ impl<'gc> LoadManager<'gc> {
|
|||
loader.sound_loader_avm2(player, request)
|
||||
}
|
||||
|
||||
pub fn load_netstream(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
target_stream: GcCell<'gc, NetStream>,
|
||||
request: Request,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let loader = Loader::NetStream {
|
||||
self_handle: None,
|
||||
target_stream,
|
||||
};
|
||||
let handle = self.add_loader(loader);
|
||||
let loader = self.get_loader_mut(handle).unwrap();
|
||||
loader.stream_loader(player, request)
|
||||
}
|
||||
|
||||
/// Process tags on all loaders in the Parsing phase.
|
||||
///
|
||||
/// Returns true if *all* loaders finished preloading.
|
||||
|
@ -561,6 +581,16 @@ pub enum Loader<'gc> {
|
|||
/// The target AVM1 object to load the audio into.
|
||||
target_object: Avm2Object<'gc>,
|
||||
},
|
||||
|
||||
/// Loader that is buffering video or audio into a NetStream.
|
||||
NetStream {
|
||||
/// The handle to refer to this loader instance.
|
||||
#[collect(require_static)]
|
||||
self_handle: Option<Handle>,
|
||||
|
||||
/// The stream to buffer data into.
|
||||
target_stream: GcCell<'gc, NetStream>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'gc> Loader<'gc> {
|
||||
|
@ -1308,6 +1338,48 @@ impl<'gc> Loader<'gc> {
|
|||
})
|
||||
}
|
||||
|
||||
fn stream_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
request: Request,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let handle = match self {
|
||||
Loader::SoundAvm2 { self_handle, .. } => {
|
||||
self_handle.expect("Loader not self-introduced")
|
||||
}
|
||||
_ => return Box::pin(async { Err(Error::NotLoadDataLoader) }),
|
||||
};
|
||||
|
||||
let player = player
|
||||
.upgrade()
|
||||
.expect("Could not upgrade weak reference to player");
|
||||
|
||||
Box::pin(async move {
|
||||
let fetch = player.lock().unwrap().navigator().fetch(request);
|
||||
let response = fetch.await;
|
||||
|
||||
player.lock().unwrap().update(|uc| {
|
||||
let loader = uc.load_manager.get_loader(handle);
|
||||
let stream = match loader {
|
||||
Some(&Loader::NetStream { target_stream, .. }) => target_stream,
|
||||
None => return Err(Error::Cancelled),
|
||||
_ => return Err(Error::NotNetStreamLoader),
|
||||
};
|
||||
|
||||
match response {
|
||||
Ok(mut response) => {
|
||||
stream.write(uc.gc_context).load_buffer(&mut response.body);
|
||||
}
|
||||
Err(err) => {
|
||||
stream.write(uc.gc_context).report_error(err);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Report a movie loader start event to script code.
|
||||
fn movie_loader_start(handle: Index, uc: &mut UpdateContext<'_, 'gc>) -> Result<(), Error> {
|
||||
let me = uc.load_manager.get_loader_mut(handle);
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
use crate::loader::Error;
|
||||
use gc_arena::Collect;
|
||||
|
||||
/// A stream representing download of some (audiovisual) data.
|
||||
#[derive(Clone, Debug, Collect)]
|
||||
#[collect(require_static)]
|
||||
pub struct NetStream {}
|
||||
pub struct NetStream {
|
||||
/// All data currently loaded in the stream.
|
||||
buffer: Vec<u8>,
|
||||
}
|
||||
|
||||
impl NetStream {
|
||||
pub fn load_buffer(&mut self, data: &mut Vec<u8>) {
|
||||
self.buffer.append(data);
|
||||
}
|
||||
|
||||
pub fn report_error(&mut self, _error: Error) {
|
||||
//TODO: Report an `asyncError` to AVM1 or 2.
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue