diff --git a/src/components/net/image_cache_task.rs b/src/components/net/image_cache_task.rs index bdf7e1d9404..3e06de423c6 100644 --- a/src/components/net/image_cache_task.rs +++ b/src/components/net/image_cache_task.rs @@ -48,22 +48,13 @@ pub enum Msg { Exit(Chan<()>), } +#[deriving(Clone)] pub enum ImageResponseMsg { ImageReady(Arc<~Image>), ImageNotReady, ImageFailed } -impl ImageResponseMsg { - fn clone(&self) -> ImageResponseMsg { - match *self { - ImageReady(ref img) => ImageReady(img.clone()), - ImageNotReady => ImageNotReady, - ImageFailed => ImageFailed, - } - } -} - impl Eq for ImageResponseMsg { fn eq(&self, other: &ImageResponseMsg) -> bool { // FIXME: Bad copies @@ -243,11 +234,11 @@ impl ImageCache { } } - fn set_state(&self, url: Url, state: ImageState) { + fn set_state(&mut self, url: Url, state: ImageState) { self.state_map.insert(url, state); } - fn prefetch(&self, url: Url) { + fn prefetch(&mut self, url: Url) { match self.get_state(url.clone()) { Init => { let to_cache = self.chan.clone(); @@ -278,7 +269,7 @@ impl ImageCache { } } - fn store_prefetched_image_data(&self, url: Url, data: Result, ()>) { + fn store_prefetched_image_data(&mut self, url: Url, data: Result, ()>) { match self.get_state(url.clone()) { Prefetching(next_step) => { match data { @@ -307,7 +298,7 @@ impl ImageCache { } } - fn decode(&self, url: Url) { + fn decode(&mut self, url: Url) { match self.get_state(url.clone()) { Init => fail!(~"decoding image before prefetch"), @@ -350,7 +341,7 @@ impl ImageCache { } } - fn store_image(&self, url: Url, image: Option>) { + fn store_image(&mut self, url: Url, image: Option>) { match self.get_state(url.clone()) { Decoding => { @@ -377,7 +368,7 @@ impl ImageCache { } - fn purge_waiters(&self, url: Url, f: &fn() -> ImageResponseMsg) { + fn purge_waiters(&mut self, url: Url, f: &fn() -> ImageResponseMsg) { match self.wait_map.pop(&url) { Some(waiters) => { for response in waiters.iter() { @@ -399,7 +390,7 @@ impl ImageCache { } } - fn wait_for_image(&self, url: Url, response: Chan) { + fn wait_for_image(&mut self, url: Url, response: Chan) { match self.get_state(url.clone()) { Init => fail!(~"request for image before prefetch"), diff --git a/src/components/net/local_image_cache.rs b/src/components/net/local_image_cache.rs index 12521263a30..f1889ff306b 100644 --- a/src/components/net/local_image_cache.rs +++ b/src/components/net/local_image_cache.rs @@ -34,9 +34,10 @@ pub struct LocalImageCache { priv image_cache_task: ImageCacheTask, priv round_number: uint, priv on_image_available: Option<~ImageResponder:Send>, - priv state_map: UrlMap<@mut ImageState> + priv state_map: UrlMap } +#[deriving(Clone)] struct ImageState { prefetched: bool, decoded: bool, @@ -52,51 +53,62 @@ impl LocalImageCache { self.on_image_available = Some(on_image_available); } - pub fn prefetch(&self, url: &Url) { - let state = self.get_state(url); - if !state.prefetched { - self.image_cache_task.send(Prefetch((*url).clone())); + pub fn prefetch(&mut self, url: &Url) { + { + let state = self.get_state(url); + if state.prefetched { + return + } + state.prefetched = true; } + + self.image_cache_task.send(Prefetch((*url).clone())); } - pub fn decode(&self, url: &Url) { - let state = self.get_state(url); - if !state.decoded { - self.image_cache_task.send(Decode((*url).clone())); + pub fn decode(&mut self, url: &Url) { + { + let state = self.get_state(url); + if state.decoded { + return + } state.decoded = true; } + + self.image_cache_task.send(Decode((*url).clone())); } // FIXME: Should return a Future - pub fn get_image(&self, url: &Url) -> Port { - let state = self.get_state(url); + pub fn get_image(&mut self, url: &Url) -> Port { + { + let state = self.get_state(url); - // Save the previous round number for comparison - let last_round = state.last_request_round; - // Set the current round number for this image - state.last_request_round = self.round_number; + // Save the previous round number for comparison + let last_round = state.last_request_round; + // Set the current round number for this image + state.last_request_round = self.round_number; - match state.last_response { - ImageReady(ref image) => { - let (port, chan) = comm::stream(); - chan.send(ImageReady(image.clone())); - return port; - } - ImageNotReady => { - if last_round == self.round_number { + match state.last_response { + ImageReady(ref image) => { let (port, chan) = comm::stream(); - chan.send(ImageNotReady); + chan.send(ImageReady(image.clone())); + return port; + } + ImageNotReady => { + if last_round == self.round_number { + let (port, chan) = comm::stream(); + chan.send(ImageNotReady); + return port; + } else { + // We haven't requested the image from the + // remote cache this round + } + } + ImageFailed => { + let (port, chan) = comm::stream(); + chan.send(ImageFailed); return port; - } else { - // We haven't requested the image from the - // remote cache this round } - } - ImageFailed => { - let (port, chan) = comm::stream(); - chan.send(ImageFailed); - return port; } } @@ -130,24 +142,24 @@ impl LocalImageCache { ImageNotReady => ImageNotReady, ImageFailed => ImageFailed }; - state.last_response = response_copy; + self.get_state(url).last_response = response_copy; let (port, chan) = comm::stream(); chan.send(response); return port; } - fn get_state(&self, url: &Url) -> @mut ImageState { - let state = do self.state_map.find_or_insert_with(url.clone()) |_| { - let new_state = @mut ImageState { + fn get_state<'a>(&'a mut self, url: &Url) -> &'a mut ImageState { + let state = self.state_map.find_or_insert_with(url.clone(), |_| { + let new_state = ImageState { prefetched: false, decoded: false, last_request_round: 0, last_response: ImageNotReady }; new_state - }; - *state // Unborrowing the state + }); + state } } diff --git a/src/components/util/url.rs b/src/components/util/url.rs index 29385decd58..bf796c02c19 100644 --- a/src/components/util/url.rs +++ b/src/components/util/url.rs @@ -147,8 +147,9 @@ mod make_url_tests { } -pub type UrlMap = @mut HashMap; +pub type UrlMap = HashMap; pub fn url_map() -> UrlMap { - @mut HashMap::new() + HashMap::new() } +