diff options
author | rohan.prinja <rohan.prinja@samsung.com> | 2015-11-14 05:07:55 +0900 |
---|---|---|
committer | Rohan Prinja <rohan.prinja@gmail.com> | 2016-01-10 17:58:13 +0900 |
commit | 1f02c4ebbb7d5ea49051f4391f1418f20c15d7a9 (patch) | |
tree | 7d61e58e746ddca93074ca6bca6849360a098b8c /components/net_traits/image_cache_thread.rs | |
parent | f00532bab0382d1c24e6086314f26497fb6ffe0f (diff) | |
download | servo-1f02c4ebbb7d5ea49051f4391f1418f20c15d7a9.tar.gz servo-1f02c4ebbb7d5ea49051f4391f1418f20c15d7a9.zip |
task -> thread
Diffstat (limited to 'components/net_traits/image_cache_thread.rs')
-rw-r--r-- | components/net_traits/image_cache_thread.rs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/components/net_traits/image_cache_thread.rs b/components/net_traits/image_cache_thread.rs new file mode 100644 index 00000000000..85ef01be4f6 --- /dev/null +++ b/components/net_traits/image_cache_thread.rs @@ -0,0 +1,129 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use ipc_channel::ipc::{self, IpcSender}; +use msg::constellation_msg::Image; +use std::sync::Arc; +use url::Url; +use util::mem::HeapSizeOf; + +/// This is optionally passed to the image cache when requesting +/// and image, and returned to the specified event loop when the +/// image load completes. It is typically used to trigger a reflow +/// and/or repaint. +#[derive(Deserialize, Serialize)] +pub struct ImageResponder { + sender: IpcSender<ImageResponse>, +} + +impl ImageResponder { + pub fn new(sender: IpcSender<ImageResponse>) -> ImageResponder { + ImageResponder { + sender: sender, + } + } + + pub fn respond(&self, response: ImageResponse) { + self.sender.send(response).unwrap() + } +} + +/// The current state of an image in the cache. +#[derive(PartialEq, Copy, Clone, Deserialize, Serialize)] +pub enum ImageState { + Pending, + LoadError, + NotRequested, +} + +/// The returned image. +#[derive(Clone, Deserialize, Serialize, HeapSizeOf)] +pub enum ImageResponse { + /// The requested image was loaded. + Loaded(Arc<Image>), + /// The requested image failed to load, so a placeholder was loaded instead. + PlaceholderLoaded(Arc<Image>), + /// Neither the requested image nor the placeholder could be loaded. + None +} + +/// Channel for sending commands to the image cache. +#[derive(Clone, Deserialize, Serialize)] +pub struct ImageCacheChan(pub IpcSender<ImageCacheResult>); + +/// The result of an image cache command that is returned to the +/// caller. +#[derive(Deserialize, Serialize)] +pub struct ImageCacheResult { + pub responder: Option<ImageResponder>, + pub image_response: ImageResponse, +} + +/// Commands that the image cache understands. +#[derive(Deserialize, Serialize)] +pub enum ImageCacheCommand { + /// Request an image asynchronously from the cache. Supply a channel + /// to receive the result, and optionally an image responder + /// that is passed to the result channel. + RequestImage(Url, ImageCacheChan, Option<ImageResponder>), + + /// Synchronously check the state of an image in the cache. + /// TODO(gw): Profile this on some real world sites and see + /// if it's worth caching the results of this locally in each + /// layout / paint thread. + GetImageIfAvailable(Url, UsePlaceholder, IpcSender<Result<Arc<Image>, ImageState>>), + + /// Clients must wait for a response before shutting down the ResourceThread + Exit(IpcSender<()>), +} + +#[derive(Copy, Clone, PartialEq, Deserialize, Serialize)] +pub enum UsePlaceholder { + No, + Yes, +} + +/// The client side of the image cache thread. This can be safely cloned +/// and passed to different threads. +#[derive(Clone, Deserialize, Serialize)] +pub struct ImageCacheThread { + chan: IpcSender<ImageCacheCommand>, +} + +/// The public API for the image cache thread. +impl ImageCacheThread { + + /// Construct a new image cache + pub fn new(chan: IpcSender<ImageCacheCommand>) -> ImageCacheThread { + ImageCacheThread { + chan: chan, + } + } + + /// Asynchronously request and image. See ImageCacheCommand::RequestImage. + pub fn request_image(&self, + url: Url, + result_chan: ImageCacheChan, + responder: Option<ImageResponder>) { + let msg = ImageCacheCommand::RequestImage(url, result_chan, responder); + self.chan.send(msg).unwrap(); + } + + /// Get the current state of an image. See ImageCacheCommand::GetImageIfAvailable. + pub fn find_image(&self, url: Url, use_placeholder: UsePlaceholder) + -> Result<Arc<Image>, ImageState> { + let (sender, receiver) = ipc::channel().unwrap(); + let msg = ImageCacheCommand::GetImageIfAvailable(url, use_placeholder, sender); + self.chan.send(msg).unwrap(); + receiver.recv().unwrap() + } + + /// Shutdown the image cache thread. + pub fn exit(&self) { + let (response_chan, response_port) = ipc::channel().unwrap(); + self.chan.send(ImageCacheCommand::Exit(response_chan)).unwrap(); + response_port.recv().unwrap(); + } +} + |