@@ -1,9 +1,6 @@
-use crate::{ImageData, ImageId, SharedUrl};
+use crate::{AppContext, ImageData, ImageId, SharedUrl, Task};
use collections::HashMap;
-use futures::{
- future::{BoxFuture, Shared},
- AsyncReadExt, FutureExt, TryFutureExt,
-};
+use futures::{future::Shared, AsyncReadExt, FutureExt, TryFutureExt};
use image::ImageError;
use parking_lot::Mutex;
use std::sync::Arc;
@@ -44,10 +41,10 @@ impl From<ImageError> for Error {
pub(crate) struct ImageCache {
client: Arc<dyn HttpClient>,
- images: Arc<Mutex<HashMap<SharedUrl, FetchImageFuture>>>,
+ images: Arc<Mutex<HashMap<SharedUrl, FetchImageTask>>>,
}
-type FetchImageFuture = Shared<BoxFuture<'static, Result<Arc<ImageData>, Error>>>;
+type FetchImageTask = Shared<Task<Result<Arc<ImageData>, Error>>>;
impl ImageCache {
pub fn new(client: Arc<dyn HttpClient>) -> Self {
@@ -57,10 +54,7 @@ impl ImageCache {
}
}
- pub fn get(
- &self,
- uri: impl Into<SharedUrl>,
- ) -> Shared<BoxFuture<'static, Result<Arc<ImageData>, Error>>> {
+ pub fn get(&self, uri: impl Into<SharedUrl>, cx: &AppContext) -> FetchImageTask {
let uri = uri.into();
let mut images = self.images.lock();
@@ -68,36 +62,39 @@ impl ImageCache {
Some(future) => future.clone(),
None => {
let client = self.client.clone();
- let future = {
- let uri = uri.clone();
- async move {
- let mut response = client.get(uri.as_ref(), ().into(), true).await?;
- let mut body = Vec::new();
- response.body_mut().read_to_end(&mut body).await?;
+ let future = cx
+ .background_executor()
+ .spawn(
+ {
+ let uri = uri.clone();
+ async move {
+ let mut response =
+ client.get(uri.as_ref(), ().into(), true).await?;
+ let mut body = Vec::new();
+ response.body_mut().read_to_end(&mut body).await?;
- if !response.status().is_success() {
- return Err(Error::BadStatus {
- status: response.status(),
- body: String::from_utf8_lossy(&body).into_owned(),
- });
- }
-
- let format = image::guess_format(&body)?;
- let image =
- image::load_from_memory_with_format(&body, format)?.into_bgra8();
- Ok(Arc::new(ImageData::new(image)))
- }
- }
- .map_err({
- let uri = uri.clone();
+ if !response.status().is_success() {
+ return Err(Error::BadStatus {
+ status: response.status(),
+ body: String::from_utf8_lossy(&body).into_owned(),
+ });
+ }
- move |error| {
- log::log!(log::Level::Error, "{:?} {:?}", &uri, &error);
- error
- }
- })
- .boxed()
- .shared();
+ let format = image::guess_format(&body)?;
+ let image = image::load_from_memory_with_format(&body, format)?
+ .into_bgra8();
+ Ok(Arc::new(ImageData::new(image)))
+ }
+ }
+ .map_err({
+ let uri = uri.clone();
+ move |error| {
+ log::log!(log::Level::Error, "{:?} {:?}", &uri, &error);
+ error
+ }
+ }),
+ )
+ .shared();
images.insert(uri, future.clone());
future