aboutsummaryrefslogtreecommitdiffstats
path: root/components/net_traits/image_cache_thread.rs
diff options
context:
space:
mode:
authorrohan.prinja <rohan.prinja@samsung.com>2015-11-14 05:07:55 +0900
committerRohan Prinja <rohan.prinja@gmail.com>2016-01-10 17:58:13 +0900
commit1f02c4ebbb7d5ea49051f4391f1418f20c15d7a9 (patch)
tree7d61e58e746ddca93074ca6bca6849360a098b8c /components/net_traits/image_cache_thread.rs
parentf00532bab0382d1c24e6086314f26497fb6ffe0f (diff)
downloadservo-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.rs129
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();
+ }
+}
+