core: Introduce LoaderError to all Loader methods
This commit is contained in:
parent
abeece7e78
commit
0f1eef9022
|
@ -1,5 +1,6 @@
|
|||
//! Browser-related platform functions
|
||||
|
||||
use crate::loader::LoaderError;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fs;
|
||||
use std::future::Future;
|
||||
|
@ -11,8 +12,6 @@ use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
|
|||
use std::time::Duration;
|
||||
use swf::avm1::types::SendVarsMethod;
|
||||
|
||||
pub type Error = Box<dyn std::error::Error>;
|
||||
|
||||
/// Enumerates all possible navigation methods.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum NavigationMethod {
|
||||
|
@ -118,7 +117,11 @@ pub trait NavigatorBackend {
|
|||
);
|
||||
|
||||
/// Fetch data at a given URL and return it some time in the future.
|
||||
fn fetch(&self, url: &str, request_options: RequestOptions) -> OwnedFuture<Vec<u8>, Error>;
|
||||
fn fetch(
|
||||
&self,
|
||||
url: &str,
|
||||
request_options: RequestOptions,
|
||||
) -> OwnedFuture<Vec<u8>, LoaderError>;
|
||||
|
||||
/// Get the amount of time since the SWF was launched.
|
||||
/// Used by the `getTimer` ActionScript call.
|
||||
|
@ -132,16 +135,16 @@ pub trait NavigatorBackend {
|
|||
///
|
||||
/// TODO: For some reason, `wasm_bindgen_futures` wants unpinnable futures.
|
||||
/// This seems highly limiting.
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), Error>);
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), LoaderError>);
|
||||
}
|
||||
|
||||
/// A null implementation of an event loop that only supports blocking.
|
||||
pub struct NullExecutor {
|
||||
/// The list of outstanding futures spawned on this executor.
|
||||
futures_queue: VecDeque<OwnedFuture<(), Error>>,
|
||||
futures_queue: VecDeque<OwnedFuture<(), LoaderError>>,
|
||||
|
||||
/// The source of any additional futures.
|
||||
channel: Receiver<OwnedFuture<(), Error>>,
|
||||
channel: Receiver<OwnedFuture<(), LoaderError>>,
|
||||
}
|
||||
|
||||
unsafe fn do_nothing(_data: *const ()) {}
|
||||
|
@ -157,7 +160,7 @@ impl NullExecutor {
|
|||
///
|
||||
/// The sender yielded as part of construction should be given to a
|
||||
/// `NullNavigatorBackend` so that it can spawn futures on this executor.
|
||||
pub fn new() -> (Self, Sender<OwnedFuture<(), Error>>) {
|
||||
pub fn new() -> (Self, Sender<OwnedFuture<(), LoaderError>>) {
|
||||
let (send, recv) = channel();
|
||||
|
||||
(
|
||||
|
@ -191,7 +194,7 @@ impl NullExecutor {
|
|||
/// stop polling futures and return that error. Otherwise, it will yield
|
||||
/// `Ok`, indicating that no errors occured. More work may still be
|
||||
/// available,
|
||||
pub fn poll_all(&mut self) -> Result<(), Error> {
|
||||
pub fn poll_all(&mut self) -> Result<(), LoaderError> {
|
||||
self.flush_channel();
|
||||
|
||||
let mut unfinished_futures = VecDeque::new();
|
||||
|
@ -226,7 +229,7 @@ impl NullExecutor {
|
|||
}
|
||||
|
||||
/// Block until all futures complete or an error occurs.
|
||||
pub fn block_all(&mut self) -> Result<(), Error> {
|
||||
pub fn block_all(&mut self) -> Result<(), LoaderError> {
|
||||
while self.has_work() {
|
||||
self.poll_all()?;
|
||||
}
|
||||
|
@ -241,7 +244,7 @@ impl NullExecutor {
|
|||
/// futures and runs them to completion, blockingly.
|
||||
pub struct NullNavigatorBackend {
|
||||
/// The channel upon which all spawned futures will be sent.
|
||||
channel: Option<Sender<OwnedFuture<(), Error>>>,
|
||||
channel: Option<Sender<OwnedFuture<(), LoaderError>>>,
|
||||
|
||||
/// The base path for all relative fetches.
|
||||
relative_base_path: PathBuf,
|
||||
|
@ -260,7 +263,7 @@ impl NullNavigatorBackend {
|
|||
/// Construct a navigator backend with fetch and async capability.
|
||||
pub fn with_base_path<P: AsRef<Path>>(
|
||||
path: P,
|
||||
channel: Sender<OwnedFuture<(), Error>>,
|
||||
channel: Sender<OwnedFuture<(), LoaderError>>,
|
||||
) -> Self {
|
||||
let mut relative_base_path = PathBuf::new();
|
||||
|
||||
|
@ -288,18 +291,18 @@ impl NavigatorBackend for NullNavigatorBackend {
|
|||
) {
|
||||
}
|
||||
|
||||
fn fetch(&self, url: &str, _opts: RequestOptions) -> OwnedFuture<Vec<u8>, Error> {
|
||||
fn fetch(&self, url: &str, _opts: RequestOptions) -> OwnedFuture<Vec<u8>, LoaderError> {
|
||||
let mut path = self.relative_base_path.clone();
|
||||
path.push(url);
|
||||
|
||||
Box::pin(async move { fs::read(path).map_err(|e| e.into()) })
|
||||
Box::pin(async move { fs::read(path).map_err(LoaderError::NetworkError) })
|
||||
}
|
||||
|
||||
fn time_since_launch(&mut self) -> Duration {
|
||||
Duration::from_millis(0)
|
||||
}
|
||||
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), Error>) {
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), LoaderError>) {
|
||||
if let Some(channel) = self.channel.as_ref() {
|
||||
channel.send(future).unwrap();
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ mod drawing;
|
|||
pub mod events;
|
||||
mod font;
|
||||
mod library;
|
||||
mod loader;
|
||||
pub mod loader;
|
||||
mod player;
|
||||
mod prelude;
|
||||
mod property_map;
|
||||
|
|
|
@ -9,12 +9,39 @@ use crate::tag_utils::SwfMovie;
|
|||
use crate::xml::XMLNode;
|
||||
use gc_arena::{Collect, CollectionContext};
|
||||
use generational_arena::{Arena, Index};
|
||||
use std::fmt;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::sync::{Arc, Mutex, Weak};
|
||||
use url::form_urlencoded;
|
||||
|
||||
pub type Handle = Index;
|
||||
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
#[derive(Debug)]
|
||||
pub enum LoaderError {
|
||||
Cancelled,
|
||||
NotMovieLoader,
|
||||
NotFormLoader,
|
||||
NotXmlLoader,
|
||||
InvalidSwf(crate::tag_utils::Error),
|
||||
InvalidXmlEncoding(FromUtf8Error),
|
||||
NetworkError(std::io::Error),
|
||||
Avm1Error(Box<dyn std::error::Error>),
|
||||
}
|
||||
|
||||
impl fmt::Display for LoaderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
LoaderError::Cancelled => f.write_str("Load cancelled"),
|
||||
LoaderError::NotMovieLoader => f.write_str("Non-movie loader spawned as movie loader"),
|
||||
LoaderError::NotFormLoader => f.write_str("Non-form loader spawned as form loader"),
|
||||
LoaderError::NotXmlLoader => f.write_str("Non-XML loader spawned as XML loader"),
|
||||
LoaderError::InvalidSwf(error) => write!(f, "Invalid SWF: {}", error),
|
||||
LoaderError::InvalidXmlEncoding(error) => write!(f, "Invalid XML encoding: {}", error),
|
||||
LoaderError::NetworkError(error) => write!(f, "Network error: {}", error),
|
||||
LoaderError::Avm1Error(error) => write!(f, "Could not run avm1 script: {}", error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds all in-progress loads for the player.
|
||||
pub struct LoadManager<'gc>(Arena<Loader<'gc>>);
|
||||
|
@ -66,9 +93,9 @@ impl<'gc> LoadManager<'gc> {
|
|||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
target_clip: DisplayObject<'gc>,
|
||||
fetch: OwnedFuture<Vec<u8>, Error>,
|
||||
fetch: OwnedFuture<Vec<u8>, LoaderError>,
|
||||
target_broadcaster: Option<Object<'gc>>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
) -> OwnedFuture<(), LoaderError> {
|
||||
let loader = Loader::Movie {
|
||||
self_handle: None,
|
||||
target_clip,
|
||||
|
@ -112,8 +139,8 @@ impl<'gc> LoadManager<'gc> {
|
|||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
target_object: Object<'gc>,
|
||||
fetch: OwnedFuture<Vec<u8>, Error>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
fetch: OwnedFuture<Vec<u8>, LoaderError>,
|
||||
) -> OwnedFuture<(), LoaderError> {
|
||||
let loader = Loader::Form {
|
||||
self_handle: None,
|
||||
target_object,
|
||||
|
@ -134,8 +161,8 @@ impl<'gc> LoadManager<'gc> {
|
|||
player: Weak<Mutex<Player>>,
|
||||
target_node: XMLNode<'gc>,
|
||||
active_clip: DisplayObject<'gc>,
|
||||
fetch: OwnedFuture<Vec<u8>, Error>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
fetch: OwnedFuture<Vec<u8>, LoaderError>,
|
||||
) -> OwnedFuture<(), LoaderError> {
|
||||
let loader = Loader::XML {
|
||||
self_handle: None,
|
||||
active_clip,
|
||||
|
@ -248,11 +275,11 @@ impl<'gc> Loader<'gc> {
|
|||
pub fn movie_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
fetch: OwnedFuture<Vec<u8>, Error>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
fetch: OwnedFuture<Vec<u8>, LoaderError>,
|
||||
) -> OwnedFuture<(), LoaderError> {
|
||||
let handle = match self {
|
||||
Loader::Movie { self_handle, .. } => self_handle.expect("Loader not self-introduced"),
|
||||
_ => return Box::pin(async { Err("Non-movie loader spawned as movie loader".into()) }),
|
||||
_ => return Box::pin(async { Err(LoaderError::NotMovieLoader) }),
|
||||
};
|
||||
|
||||
let player = player
|
||||
|
@ -261,14 +288,14 @@ impl<'gc> Loader<'gc> {
|
|||
|
||||
Box::pin(async move {
|
||||
player.lock().expect("Could not lock player!!").update(
|
||||
|avm, uc| -> Result<(), Error> {
|
||||
|avm, uc| -> Result<(), LoaderError> {
|
||||
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
||||
Some(Loader::Movie {
|
||||
target_clip,
|
||||
target_broadcaster,
|
||||
..
|
||||
}) => (*target_clip, *target_broadcaster),
|
||||
None => return Err("Load cancelled".into()),
|
||||
None => return Err(LoaderError::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -287,14 +314,20 @@ impl<'gc> Loader<'gc> {
|
|||
"broadcastMessage",
|
||||
&["onLoadStart".into(), Value::Object(broadcaster)],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
let data = (fetch.await).and_then(|data| Ok((data.len(), SwfMovie::from_data(&data)?)));
|
||||
let data = (fetch.await).and_then(|data| {
|
||||
Ok((
|
||||
data.len(),
|
||||
SwfMovie::from_data(&data).map_err(|e| LoaderError::InvalidSwf(e))?,
|
||||
))
|
||||
});
|
||||
if let Ok((length, movie)) = data {
|
||||
let movie = Arc::new(movie);
|
||||
|
||||
|
@ -308,7 +341,7 @@ impl<'gc> Loader<'gc> {
|
|||
target_broadcaster,
|
||||
..
|
||||
}) => (*target_clip, *target_broadcaster),
|
||||
None => return Err("Load cancelled".into()),
|
||||
None => return Err(LoaderError::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -326,7 +359,8 @@ impl<'gc> Loader<'gc> {
|
|||
length.into(),
|
||||
],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
}
|
||||
|
||||
let mut mc = clip
|
||||
|
@ -359,7 +393,8 @@ impl<'gc> Loader<'gc> {
|
|||
"broadcastMessage",
|
||||
&["onLoadComplete".into(), Value::Object(broadcaster)],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
}
|
||||
|
||||
if let Some(Loader::Movie { load_complete, .. }) =
|
||||
|
@ -377,14 +412,14 @@ impl<'gc> Loader<'gc> {
|
|||
//This also can get errors from decoding an invalid SWF file,
|
||||
//too. We should distinguish those to player code.
|
||||
player.lock().expect("Could not lock player!!").update(
|
||||
|avm, uc| -> Result<(), Error> {
|
||||
|avm, uc| -> Result<(), LoaderError> {
|
||||
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
||||
Some(Loader::Movie {
|
||||
target_clip,
|
||||
target_broadcaster,
|
||||
..
|
||||
}) => (*target_clip, *target_broadcaster),
|
||||
None => return Err("Load cancelled".into()),
|
||||
None => return Err(LoaderError::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -401,7 +436,8 @@ impl<'gc> Loader<'gc> {
|
|||
"LoadNeverCompleted".into(),
|
||||
],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
}
|
||||
|
||||
if let Some(Loader::Movie { load_complete, .. }) =
|
||||
|
@ -420,11 +456,11 @@ impl<'gc> Loader<'gc> {
|
|||
pub fn form_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
fetch: OwnedFuture<Vec<u8>, Error>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
fetch: OwnedFuture<Vec<u8>, LoaderError>,
|
||||
) -> OwnedFuture<(), LoaderError> {
|
||||
let handle = match self {
|
||||
Loader::Form { self_handle, .. } => self_handle.expect("Loader not self-introduced"),
|
||||
_ => return Box::pin(async { Err("Non-form loader spawned as form loader".into()) }),
|
||||
_ => return Box::pin(async { Err(LoaderError::NotFormLoader) }),
|
||||
};
|
||||
|
||||
let player = player
|
||||
|
@ -438,12 +474,13 @@ impl<'gc> Loader<'gc> {
|
|||
let loader = uc.load_manager.get_loader(handle);
|
||||
let that = match loader {
|
||||
Some(Loader::Form { target_object, .. }) => *target_object,
|
||||
None => return Err("Load cancelled".into()),
|
||||
_ => return Err("Non-movie loader spawned as movie loader".into()),
|
||||
None => return Err(LoaderError::Cancelled),
|
||||
_ => return Err(LoaderError::NotMovieLoader),
|
||||
};
|
||||
|
||||
for (k, v) in form_urlencoded::parse(&data) {
|
||||
that.set(&k, v.into_owned().into(), avm, uc)?;
|
||||
that.set(&k, v.into_owned().into(), avm, uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -497,11 +534,11 @@ impl<'gc> Loader<'gc> {
|
|||
pub fn xml_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
fetch: OwnedFuture<Vec<u8>, Error>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
fetch: OwnedFuture<Vec<u8>, LoaderError>,
|
||||
) -> OwnedFuture<(), LoaderError> {
|
||||
let handle = match self {
|
||||
Loader::XML { self_handle, .. } => self_handle.expect("Loader not self-introduced"),
|
||||
_ => return Box::pin(async { Err("Non-XML loader spawned as XML loader".into()) }),
|
||||
_ => return Box::pin(async { Err(LoaderError::NotXmlLoader) }),
|
||||
};
|
||||
|
||||
let player = player
|
||||
|
@ -511,17 +548,17 @@ impl<'gc> Loader<'gc> {
|
|||
Box::pin(async move {
|
||||
let data = fetch.await;
|
||||
if let Ok(data) = data {
|
||||
let xmlstring = String::from_utf8(data)?;
|
||||
let xmlstring = String::from_utf8(data).map_err(LoaderError::InvalidXmlEncoding)?;
|
||||
|
||||
player.lock().expect("Could not lock player!!").update(
|
||||
|avm, uc| -> Result<(), Error> {
|
||||
|avm, uc| -> Result<(), LoaderError> {
|
||||
let (mut node, active_clip) = match uc.load_manager.get_loader(handle) {
|
||||
Some(Loader::XML {
|
||||
target_node,
|
||||
active_clip,
|
||||
..
|
||||
}) => (*target_node, *active_clip),
|
||||
None => return Err("Load cancelled".into()),
|
||||
None => return Err(LoaderError::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -535,7 +572,8 @@ impl<'gc> Loader<'gc> {
|
|||
"onHTTPStatus",
|
||||
&[200.into()],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
|
||||
avm.insert_stack_frame_for_method(
|
||||
active_clip,
|
||||
|
@ -545,21 +583,22 @@ impl<'gc> Loader<'gc> {
|
|||
"onData",
|
||||
&[xmlstring.into()],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
} else {
|
||||
player.lock().expect("Could not lock player!!").update(
|
||||
|avm, uc| -> Result<(), Error> {
|
||||
|avm, uc| -> Result<(), LoaderError> {
|
||||
let (mut node, active_clip) = match uc.load_manager.get_loader(handle) {
|
||||
Some(Loader::XML {
|
||||
target_node,
|
||||
active_clip,
|
||||
..
|
||||
}) => (*target_node, *active_clip),
|
||||
None => return Err("Load cancelled".into()),
|
||||
None => return Err(LoaderError::Cancelled),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -573,7 +612,8 @@ impl<'gc> Loader<'gc> {
|
|||
"onHTTPStatus",
|
||||
&[404.into()],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
|
||||
avm.insert_stack_frame_for_method(
|
||||
active_clip,
|
||||
|
@ -583,7 +623,8 @@ impl<'gc> Loader<'gc> {
|
|||
"onData",
|
||||
&[],
|
||||
);
|
||||
avm.run_stack_till_empty(uc)?;
|
||||
avm.run_stack_till_empty(uc)
|
||||
.map_err(|e| LoaderError::Avm1Error(e))?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
use crate::custom_event::RuffleEvent;
|
||||
use crate::task::Task;
|
||||
use generational_arena::{Arena, Index};
|
||||
use ruffle_core::backend::navigator::{Error, OwnedFuture};
|
||||
use ruffle_core::backend::navigator::OwnedFuture;
|
||||
use ruffle_core::loader::LoaderError;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::sync::{Arc, Mutex, Weak};
|
||||
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
|
||||
|
@ -125,7 +126,7 @@ pub struct GlutinAsyncExecutor {
|
|||
task_queue: Arena<Task>,
|
||||
|
||||
/// Source of tasks sent to us by the `NavigatorBackend`.
|
||||
channel: Receiver<OwnedFuture<(), Error>>,
|
||||
channel: Receiver<OwnedFuture<(), LoaderError>>,
|
||||
|
||||
/// Weak reference to ourselves.
|
||||
self_ref: Weak<Mutex<Self>>,
|
||||
|
@ -144,7 +145,7 @@ impl GlutinAsyncExecutor {
|
|||
/// to spawn new tasks.
|
||||
pub fn new(
|
||||
event_loop: EventLoopProxy<RuffleEvent>,
|
||||
) -> (Arc<Mutex<Self>>, Sender<OwnedFuture<(), Error>>) {
|
||||
) -> (Arc<Mutex<Self>>, Sender<OwnedFuture<(), LoaderError>>) {
|
||||
let (send, recv) = channel();
|
||||
let new_self = Arc::new(Mutex::new(Self {
|
||||
task_queue: Arena::new(),
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
use crate::custom_event::RuffleEvent;
|
||||
use ruffle_core::backend::navigator::{
|
||||
Error, NavigationMethod, NavigatorBackend, OwnedFuture, RequestOptions,
|
||||
NavigationMethod, NavigatorBackend, OwnedFuture, RequestOptions,
|
||||
};
|
||||
use ruffle_core::loader::LoaderError;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -16,7 +17,7 @@ use winit::event_loop::EventLoopProxy;
|
|||
/// out to a web browser.
|
||||
pub struct ExternalNavigatorBackend {
|
||||
/// Sink for tasks sent to us through `spawn_future`.
|
||||
channel: Sender<OwnedFuture<(), Error>>,
|
||||
channel: Sender<OwnedFuture<(), LoaderError>>,
|
||||
|
||||
/// Event sink to trigger a new task poll.
|
||||
event_loop: EventLoopProxy<RuffleEvent>,
|
||||
|
@ -31,7 +32,7 @@ pub struct ExternalNavigatorBackend {
|
|||
impl ExternalNavigatorBackend {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(
|
||||
channel: Sender<OwnedFuture<(), Error>>,
|
||||
channel: Sender<OwnedFuture<(), LoaderError>>,
|
||||
event_loop: EventLoopProxy<RuffleEvent>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -45,7 +46,7 @@ impl ExternalNavigatorBackend {
|
|||
/// Construct a navigator backend with fetch and async capability.
|
||||
pub fn with_base_path<P: AsRef<Path>>(
|
||||
path: P,
|
||||
channel: Sender<OwnedFuture<(), Error>>,
|
||||
channel: Sender<OwnedFuture<(), LoaderError>>,
|
||||
event_loop: EventLoopProxy<RuffleEvent>,
|
||||
) -> Self {
|
||||
let mut relative_base_path = PathBuf::new();
|
||||
|
@ -110,16 +111,16 @@ impl NavigatorBackend for ExternalNavigatorBackend {
|
|||
Instant::now().duration_since(self.start_time)
|
||||
}
|
||||
|
||||
fn fetch(&self, url: &str, _options: RequestOptions) -> OwnedFuture<Vec<u8>, Error> {
|
||||
fn fetch(&self, url: &str, _options: RequestOptions) -> OwnedFuture<Vec<u8>, LoaderError> {
|
||||
// Load from local filesystem.
|
||||
// TODO: Support network loads, honor sandbox type (local-with-filesystem, local-with-network, remote, ...)
|
||||
let mut path = self.relative_base_path.clone();
|
||||
path.push(url);
|
||||
|
||||
Box::pin(async move { fs::read(path).map_err(|e| e.into()) })
|
||||
Box::pin(async move { fs::read(path).map_err(LoaderError::NetworkError) })
|
||||
}
|
||||
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), Error>) {
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), LoaderError>) {
|
||||
self.channel.send(future).expect("working channel send");
|
||||
|
||||
if self.event_loop.send_event(RuffleEvent::TaskPoll).is_err() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! Task state information
|
||||
|
||||
use ruffle_core::backend::navigator::{Error, OwnedFuture};
|
||||
use ruffle_core::backend::navigator::OwnedFuture;
|
||||
use ruffle_core::loader::LoaderError;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// Indicates the state of a given task.
|
||||
|
@ -22,12 +23,12 @@ pub struct Task {
|
|||
state: TaskState,
|
||||
|
||||
/// The future to poll in order to progress the task.
|
||||
future: OwnedFuture<(), Error>,
|
||||
future: OwnedFuture<(), LoaderError>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
/// Box an owned future into a task structure.
|
||||
pub fn from_future(future: OwnedFuture<(), Error>) -> Self {
|
||||
pub fn from_future(future: OwnedFuture<(), LoaderError>) -> Self {
|
||||
Self {
|
||||
state: TaskState::Ready,
|
||||
future,
|
||||
|
@ -54,7 +55,7 @@ impl Task {
|
|||
///
|
||||
/// This wrapper function ensures that futures cannot be polled after they
|
||||
/// have completed. Future polls will return `Ok(())`.
|
||||
pub fn poll(&mut self, context: &mut Context) -> Poll<Result<(), Error>> {
|
||||
pub fn poll(&mut self, context: &mut Context) -> Poll<Result<(), LoaderError>> {
|
||||
if self.is_completed() {
|
||||
return Poll::Ready(Ok(()));
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
use js_sys::{Array, ArrayBuffer, Uint8Array};
|
||||
use ruffle_core::backend::navigator::{
|
||||
Error, NavigationMethod, NavigatorBackend, OwnedFuture, RequestOptions,
|
||||
NavigationMethod, NavigatorBackend, OwnedFuture, RequestOptions,
|
||||
};
|
||||
use ruffle_core::loader::LoaderError;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen::JsCast;
|
||||
|
@ -92,7 +93,7 @@ impl NavigatorBackend for WebNavigatorBackend {
|
|||
Duration::from_millis(dt as u64)
|
||||
}
|
||||
|
||||
fn fetch(&self, url: &str, options: RequestOptions) -> OwnedFuture<Vec<u8>, Error> {
|
||||
fn fetch(&self, url: &str, options: RequestOptions) -> OwnedFuture<Vec<u8>, LoaderError> {
|
||||
let url = url.to_string();
|
||||
Box::pin(async move {
|
||||
let mut init = RequestInit::new();
|
||||
|
@ -130,7 +131,10 @@ impl NavigatorBackend for WebNavigatorBackend {
|
|||
let window = web_sys::window().unwrap();
|
||||
let fetchval = JsFuture::from(window.fetch_with_request(&request)).await;
|
||||
if fetchval.is_err() {
|
||||
return Err("Could not fetch, got JS Error".into());
|
||||
return Err(LoaderError::NetworkError(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"Could not fetch, got JS Error",
|
||||
)));
|
||||
}
|
||||
|
||||
let resp: Response = fetchval.unwrap().dyn_into().unwrap();
|
||||
|
@ -147,7 +151,7 @@ impl NavigatorBackend for WebNavigatorBackend {
|
|||
})
|
||||
}
|
||||
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), Error>) {
|
||||
fn spawn_future(&mut self, future: OwnedFuture<(), LoaderError>) {
|
||||
spawn_local(async move {
|
||||
if let Err(e) = future.await {
|
||||
log::error!("Asynchronous error occured: {}", e);
|
||||
|
|
Loading…
Reference in New Issue