Procházet zdrojové kódy

Add ability to switch tile source during execution

Johannes Hofmann před 8 roky
rodič
revize
350e8db588
9 změnil soubory, kde provedl 122 přidání a 75 odebrání
  1. 5
    5
      src/config.rs
  2. 0
    1
      src/coord.rs
  3. 46
    9
      src/main.rs
  4. 3
    6
      src/map_view_gl.rs
  5. 9
    0
      src/tile.rs
  6. 12
    7
      src/tile_cache.rs
  7. 7
    5
      src/tile_cache_gl.rs
  8. 26
    24
      src/tile_loader.rs
  9. 14
    18
      src/tile_source.rs

+ 5
- 5
src/config.rs Zobrazit soubor

33
         toml::from_str(&content).ok()
33
         toml::from_str(&content).ok()
34
     }
34
     }
35
 
35
 
36
-    pub fn tile_sources(&self) -> BTreeMap<String, TileSource> {
37
-        let mut map = BTreeMap::new();
36
+    pub fn tile_sources(&self) -> Vec<(String, TileSource)> {
37
+        let mut vec = Vec::with_capacity(self.sources.len());
38
 
38
 
39
         for (id, (name, source)) in self.sources.iter().enumerate() {
39
         for (id, (name, source)) in self.sources.iter().enumerate() {
40
             let mut path = PathBuf::from(&self.tile_cache_dir);
40
             let mut path = PathBuf::from(&self.tile_cache_dir);
41
             //TODO escape name (no slashes or dots)
41
             //TODO escape name (no slashes or dots)
42
             path.push(name);
42
             path.push(name);
43
 
43
 
44
-            map.insert(
44
+            vec.push((
45
                 name.clone(),
45
                 name.clone(),
46
                 TileSource::new(
46
                 TileSource::new(
47
                     id as u32,
47
                     id as u32,
49
                     path,
49
                     path,
50
                     source.max_zoom,
50
                     source.max_zoom,
51
                 ),
51
                 ),
52
-            );
52
+            ));
53
         }
53
         }
54
 
54
 
55
-        return map;
55
+        vec
56
     }
56
     }
57
 }
57
 }

+ 0
- 1
src/coord.rs Zobrazit soubor

1
 use std::f64::consts::PI;
1
 use std::f64::consts::PI;
2
-use tile::Tile;
3
 
2
 
4
 /// A position in map coordinates.
3
 /// A position in map coordinates.
5
 /// Valid values for x and y lie in the interval [0.0, 1.0].
4
 /// Valid values for x and y lie in the interval [0.0, 1.0].

+ 46
- 9
src/main.rs Zobrazit soubor

55
     mouse_pressed: bool,
55
     mouse_pressed: bool,
56
 }
56
 }
57
 
57
 
58
-fn handle_event(event: Event, map: &mut MapViewGl, input_state: &mut InputState) -> Action {
58
+fn handle_event(event: Event, map: &mut MapViewGl, input_state: &mut InputState, sources: &mut TileSources) -> Action {
59
     match event {
59
     match event {
60
         Event::Closed => Action::Close,
60
         Event::Closed => Action::Close,
61
         Event::Awakened => Action::Redraw,
61
         Event::Awakened => Action::Redraw,
119
                 VirtualKeyCode::Escape => {
119
                 VirtualKeyCode::Escape => {
120
                     Action::Close
120
                     Action::Close
121
                 },
121
                 },
122
+                VirtualKeyCode::PageUp => {
123
+                    sources.switch_to_prev();
124
+                    Action::Redraw
125
+                },
126
+                VirtualKeyCode::PageDown => {
127
+                    sources.switch_to_next();
128
+                    Action::Redraw
129
+                },
122
                 VirtualKeyCode::Left => {
130
                 VirtualKeyCode::Left => {
123
                     map.move_pixel(-50.0, 0.0);
131
                     map.move_pixel(-50.0, 0.0);
124
                     Action::Redraw
132
                     Action::Redraw
159
 
167
 
160
 fn main() {
168
 fn main() {
161
     let config = config::Config::from_toml("deltamap.toml").unwrap();
169
     let config = config::Config::from_toml("deltamap.toml").unwrap();
170
+    let mut sources = TileSources::new(config.tile_sources()).unwrap();
162
 
171
 
163
     let mut window = glutin::WindowBuilder::new().build().unwrap();
172
     let mut window = glutin::WindowBuilder::new().build().unwrap();
164
     window.set_title("DeltaMap");
173
     window.set_title("DeltaMap");
168
     let proxy = window.create_window_proxy();
177
     let proxy = window.create_window_proxy();
169
 
178
 
170
     let cx = context::Context::from_window(&window);
179
     let cx = context::Context::from_window(&window);
171
-    let mut sources = config.tile_sources();
172
     let mut map = map_view_gl::MapViewGl::new(
180
     let mut map = map_view_gl::MapViewGl::new(
173
         &cx,
181
         &cx,
174
-        sources.into_iter().next().unwrap().1,
175
         window.get_inner_size_pixels().unwrap(),
182
         window.get_inner_size_pixels().unwrap(),
176
         move || { proxy.wakeup_event_loop(); },
183
         move || { proxy.wakeup_event_loop(); },
177
     );
184
     );
190
 
197
 
191
         let mut redraw = false;
198
         let mut redraw = false;
192
 
199
 
193
-        match handle_event(event, &mut map, &mut input_state) {
200
+        match handle_event(event, &mut map, &mut input_state, &mut sources) {
194
             Action::Close => break 'outer,
201
             Action::Close => break 'outer,
195
             Action::Redraw => {
202
             Action::Redraw => {
196
                 redraw = true;
203
                 redraw = true;
199
         }
206
         }
200
 
207
 
201
         for event in window.poll_events() {
208
         for event in window.poll_events() {
202
-            match handle_event(event, &mut map, &mut input_state) {
209
+            match handle_event(event, &mut map, &mut input_state, &mut sources) {
203
                 Action::Close => break 'outer,
210
                 Action::Close => break 'outer,
204
                 Action::Redraw => {
211
                 Action::Redraw => {
205
                     redraw = true;
212
                     redraw = true;
213
             if diff + draw_dur * 2 < milli16 {
220
             if diff + draw_dur * 2 < milli16 {
214
                 if let Some(dur) = milli16.checked_sub(draw_dur * 2) {
221
                 if let Some(dur) = milli16.checked_sub(draw_dur * 2) {
215
                     std::thread::sleep(dur);
222
                     std::thread::sleep(dur);
216
-                    println!("SLEEP {}", dur.as_secs() as f64 + dur.subsec_nanos() as f64 * 1e-9);
223
+                    println!("SLEEP {}", dur.as_secs() as f64 + f64::from(dur.subsec_nanos()) * 1e-9);
217
 
224
 
218
                     for event in window.poll_events() {
225
                     for event in window.poll_events() {
219
-                        match handle_event(event, &mut map, &mut input_state) {
226
+                        match handle_event(event, &mut map, &mut input_state, &mut sources) {
220
                             Action::Close => break 'outer,
227
                             Action::Close => break 'outer,
221
                             Action::Redraw => {
228
                             Action::Redraw => {
222
                                 redraw = true;
229
                                 redraw = true;
230
 
237
 
231
         if redraw {
238
         if redraw {
232
             let draw_start = Instant::now();
239
             let draw_start = Instant::now();
233
-            map.draw();
240
+            map.draw(sources.current());
234
             draw_dur = draw_start.elapsed();
241
             draw_dur = draw_start.elapsed();
235
 
242
 
236
             let _ = window.swap_buffers();
243
             let _ = window.swap_buffers();
238
             last_draw = Instant::now();
245
             last_draw = Instant::now();
239
 
246
 
240
             let diff = start_loop.elapsed();
247
             let diff = start_loop.elapsed();
241
-            println!("EVENT LOOP SECS {}", diff.as_secs() as f64 + diff.subsec_nanos() as f64 * 1e-9);
248
+            println!("EVENT LOOP SECS {}", diff.as_secs() as f64 + f64::from(diff.subsec_nanos()) * 1e-9);
249
+        }
250
+    }
251
+}
252
+
253
+struct TileSources {
254
+    current_index: usize,
255
+    sources: Vec<(String, TileSource)>,
256
+}
257
+
258
+impl TileSources {
259
+    pub fn new(sources: Vec<(String, TileSource)>) -> Option<TileSources> {
260
+        if sources.is_empty() {
261
+            None
262
+        } else {
263
+            Some(TileSources {
264
+                current_index: 0,
265
+                sources: sources,
266
+            })
242
         }
267
         }
243
     }
268
     }
269
+
270
+    pub fn current(&self) -> &TileSource {
271
+        &self.sources[self.current_index].1
272
+    }
273
+
274
+    pub fn switch_to_next(&mut self) {
275
+        self.current_index = (self.current_index + 1) % self.sources.len();
276
+    }
277
+
278
+    pub fn switch_to_prev(&mut self) {
279
+        self.current_index = (self.current_index + self.sources.len().saturating_sub(1)) % self.sources.len();
280
+    }
244
 }
281
 }

+ 3
- 6
src/map_view_gl.rs Zobrazit soubor

19
     buf: Buffer<'a>,
19
     buf: Buffer<'a>,
20
     viewport_size: (u32, u32),
20
     viewport_size: (u32, u32),
21
     map_view: MapView,
21
     map_view: MapView,
22
-    tile_source: TileSource,
23
     tile_cache: TileCache,
22
     tile_cache: TileCache,
24
     tile_cache_gl: TileCacheGl<'a>,
23
     tile_cache_gl: TileCacheGl<'a>,
25
 }
24
 }
26
 
25
 
27
 impl<'a> MapViewGl<'a> {
26
 impl<'a> MapViewGl<'a> {
28
-    pub fn new<F>(cx: &Context, tile_source: TileSource, initial_size: (u32, u32), update_func: F) -> MapViewGl
27
+    pub fn new<F>(cx: &Context, initial_size: (u32, u32), update_func: F) -> MapViewGl
29
         where F: Fn() + Sync + Send + 'static,
28
         where F: Fn() + Sync + Send + 'static,
30
     {
29
     {
31
         println!("version: {}", cx.gl_version());
30
         println!("version: {}", cx.gl_version());
74
                 buf: buf,
73
                 buf: buf,
75
                 viewport_size: initial_size,
74
                 viewport_size: initial_size,
76
                 map_view: map_view,
75
                 map_view: map_view,
77
-                //TODO load templates from config
78
-                tile_source: tile_source,
79
                 tile_cache: TileCache::new(move |_tile| update_func()),
76
                 tile_cache: TileCache::new(move |_tile| update_func()),
80
                 tile_cache_gl: TileCacheGl::new(tex, 256),
77
                 tile_cache_gl: TileCacheGl::new(tex, 256),
81
             }
78
             }
94
         }
91
         }
95
     }
92
     }
96
 
93
 
97
-    pub fn draw(&mut self) {
94
+    pub fn draw(&mut self, source: &TileSource) {
98
         {
95
         {
99
             let visible_tiles = self.map_view.visible_tiles(true);
96
             let visible_tiles = self.map_view.visible_tiles(true);
100
             let textured_visible_tiles = self.tile_cache_gl.textured_visible_tiles(
97
             let textured_visible_tiles = self.tile_cache_gl.textured_visible_tiles(
101
                 &visible_tiles,
98
                 &visible_tiles,
102
-                &self.tile_source,
99
+                source,
103
                 &mut self.tile_cache,
100
                 &mut self.tile_cache,
104
             );
101
             );
105
 
102
 

+ 9
- 0
src/tile.rs Zobrazit soubor

7
     pub coord: TileCoord,
7
     pub coord: TileCoord,
8
     pub source_id: TileSourceId,
8
     pub source_id: TileSourceId,
9
 }
9
 }
10
+
11
+impl Tile {
12
+    pub fn new(coord: TileCoord, source_id: TileSourceId) -> Tile {
13
+        Tile {
14
+            coord: coord,
15
+            source_id: source_id,
16
+        }
17
+    }
18
+}

+ 12
- 7
src/tile_cache.rs Zobrazit soubor

1
 use image;
1
 use image;
2
 use linked_hash_map::{Entry, LinkedHashMap};
2
 use linked_hash_map::{Entry, LinkedHashMap};
3
 use coord::TileCoord;
3
 use coord::TileCoord;
4
+use tile::Tile;
4
 use tile_loader::TileLoader;
5
 use tile_loader::TileLoader;
5
 use tile_source::TileSource;
6
 use tile_source::TileSource;
6
 
7
 
7
 
8
 
8
 pub struct TileCache {
9
 pub struct TileCache {
9
     loader: TileLoader,
10
     loader: TileLoader,
10
-    map: LinkedHashMap<TileCoord, image::DynamicImage>,
11
+    map: LinkedHashMap<Tile, image::DynamicImage>,
11
     max_tiles: usize,
12
     max_tiles: usize,
12
 }
13
 }
13
 
14
 
14
 impl TileCache {
15
 impl TileCache {
15
     pub fn new<F>(new_tile_func: F) -> Self
16
     pub fn new<F>(new_tile_func: F) -> Self
16
-        where F: Fn(TileCoord) + Sync + Send + 'static,
17
+        where F: Fn(Tile) + Sync + Send + 'static,
17
     {
18
     {
18
         TileCache {
19
         TileCache {
19
             loader: TileLoader::new(move |tile| {
20
             loader: TileLoader::new(move |tile| {
26
 
27
 
27
     pub fn get_sync(
28
     pub fn get_sync(
28
         &mut self,
29
         &mut self,
29
-        tile: TileCoord,
30
+        tile_coord: TileCoord,
30
         source: &TileSource,
31
         source: &TileSource,
31
         write_to_file: bool,
32
         write_to_file: bool,
32
         ) -> Option<&image::DynamicImage>
33
         ) -> Option<&image::DynamicImage>
33
     {
34
     {
35
+        let tile = Tile::new(tile_coord, source.id());
36
+
34
         //TODO Return the value from get_refresh with borrowck agreeing that this is OK.
37
         //TODO Return the value from get_refresh with borrowck agreeing that this is OK.
35
         self.map.get_refresh(&tile);
38
         self.map.get_refresh(&tile);
36
 
39
 
44
                 Some(entry.into_mut())
47
                 Some(entry.into_mut())
45
             },
48
             },
46
             Entry::Vacant(entry) => {
49
             Entry::Vacant(entry) => {
47
-                self.loader.get_sync(tile, source, write_to_file).map(|img| entry.insert(img) as &_)
50
+                self.loader.get_sync(tile_coord, source, write_to_file).map(|img| entry.insert(img) as &_)
48
             },
51
             },
49
         }
52
         }
50
     }
53
     }
51
 
54
 
52
     pub fn get_async(
55
     pub fn get_async(
53
         &mut self,
56
         &mut self,
54
-        tile: TileCoord,
57
+        tile_coord: TileCoord,
55
         source: &TileSource,
58
         source: &TileSource,
56
         write_to_file: bool,
59
         write_to_file: bool,
57
         ) -> Option<&image::DynamicImage>
60
         ) -> Option<&image::DynamicImage>
66
             println!("CACHE SIZE: {} tiles", self.map.len());
69
             println!("CACHE SIZE: {} tiles", self.map.len());
67
         }
70
         }
68
 
71
 
72
+        let tile = Tile::new(tile_coord, source.id());
73
+
69
         //TODO Return the value from get_refresh with borrowck agreeing that this is OK.
74
         //TODO Return the value from get_refresh with borrowck agreeing that this is OK.
70
         self.map.get_refresh(&tile);
75
         self.map.get_refresh(&tile);
71
 
76
 
72
         match self.map.entry(tile) {
77
         match self.map.entry(tile) {
73
             Entry::Occupied(entry) => Some(entry.into_mut()),
78
             Entry::Occupied(entry) => Some(entry.into_mut()),
74
             Entry::Vacant(_) => {
79
             Entry::Vacant(_) => {
75
-                self.loader.async_request(tile, source, write_to_file);
80
+                self.loader.async_request(tile_coord, source, write_to_file);
76
                 None
81
                 None
77
             }
82
             }
78
         }
83
         }
79
     }
84
     }
80
 
85
 
81
     // Return a tile from the cache but do not use TileLoader.
86
     // Return a tile from the cache but do not use TileLoader.
82
-    pub fn lookup(&mut self, tile: TileCoord, source: &TileSource) -> Option<&image::DynamicImage> {
87
+    pub fn lookup(&mut self, tile: Tile) -> Option<&image::DynamicImage> {
83
         //TODO Return the value from get_refresh with borrowck agreeing that this is OK.
88
         //TODO Return the value from get_refresh with borrowck agreeing that this is OK.
84
         self.map.get_refresh(&tile);
89
         self.map.get_refresh(&tile);
85
 
90
 

+ 7
- 5
src/tile_cache_gl.rs Zobrazit soubor

4
 use std::collections::HashMap;
4
 use std::collections::HashMap;
5
 use std::collections::hash_map::Entry;
5
 use std::collections::hash_map::Entry;
6
 use texture::Texture;
6
 use texture::Texture;
7
+use tile::Tile;
7
 use tile_cache::TileCache;
8
 use tile_cache::TileCache;
8
 use tile_source::TileSource;
9
 use tile_source::TileSource;
9
 
10
 
37
 pub struct TileCacheGl<'a> {
38
 pub struct TileCacheGl<'a> {
38
     texture: Texture<'a>,
39
     texture: Texture<'a>,
39
     tile_size: u32,
40
     tile_size: u32,
40
-    slots_lru: LinkedHashMap<CacheSlot, Option<TileCoord>>, // LRU cache of slots
41
-    tile_to_slot: HashMap<TileCoord, CacheSlot>,
41
+    slots_lru: LinkedHashMap<CacheSlot, Option<Tile>>, // LRU cache of slots
42
+    tile_to_slot: HashMap<Tile, CacheSlot>,
42
 }
43
 }
43
 
44
 
44
 impl<'a> TileCacheGl<'a> {
45
 impl<'a> TileCacheGl<'a> {
69
         CacheSlot { x: 0, y: 0 }
70
         CacheSlot { x: 0, y: 0 }
70
     }
71
     }
71
 
72
 
72
-    pub fn store(&mut self, tile: TileCoord, source: &TileSource, cache: &mut TileCache, load: bool) -> Option<CacheSlot> {
73
+    pub fn store(&mut self, tile_coord: TileCoord, source: &TileSource, cache: &mut TileCache, load: bool) -> Option<CacheSlot> {
73
         let mut remove_tile = None;
74
         let mut remove_tile = None;
75
+        let tile = Tile::new(tile_coord, source.id());
74
 
76
 
75
         let slot = match self.tile_to_slot.entry(tile) {
77
         let slot = match self.tile_to_slot.entry(tile) {
76
             Entry::Vacant(entry) => {
78
             Entry::Vacant(entry) => {
77
                 let img_option = if load {
79
                 let img_option = if load {
78
-                    cache.get_async(tile, source, true)
80
+                    cache.get_async(tile_coord, source, true)
79
                 } else {
81
                 } else {
80
-                    cache.lookup(tile, source)
82
+                    cache.lookup(tile)
81
                 };
83
                 };
82
 
84
 
83
                 if let Some(img) = img_option {
85
                 if let Some(img) = img_option {

+ 26
- 24
src/tile_loader.rs Zobrazit soubor

8
 use std::path::{Path, PathBuf};
8
 use std::path::{Path, PathBuf};
9
 use std::sync::mpsc;
9
 use std::sync::mpsc;
10
 use std::thread;
10
 use std::thread;
11
-use tile_source::{TileSource, TileSourceId};
11
+use tile::Tile;
12
+use tile_source::TileSource;
12
 
13
 
13
 
14
 
14
 //TODO remember failed loading attempts
15
 //TODO remember failed loading attempts
17
 pub struct TileLoader {
18
 pub struct TileLoader {
18
     client: Option<Client>,
19
     client: Option<Client>,
19
     join_handle: thread::JoinHandle<()>,
20
     join_handle: thread::JoinHandle<()>,
20
-    request_tx: mpsc::Sender<(TileCoord, TileSourceId, String, PathBuf, bool)>,
21
-    result_rx: mpsc::Receiver<(TileCoord, TileSourceId, Option<DynamicImage>)>,
22
-    pending: HashSet<(TileCoord, TileSourceId)>,
21
+    request_tx: mpsc::Sender<(Tile, String, PathBuf, bool)>,
22
+    result_rx: mpsc::Receiver<(Tile, Option<DynamicImage>)>,
23
+    pending: HashSet<Tile>,
23
 }
24
 }
24
 
25
 
25
 impl TileLoader {
26
 impl TileLoader {
26
     pub fn new<F>(notice_func: F) -> Self
27
     pub fn new<F>(notice_func: F) -> Self
27
-        where F: Fn(TileCoord) + Sync + Send + 'static,
28
+        where F: Fn(Tile) + Sync + Send + 'static,
28
     {
29
     {
29
         let (request_tx, request_rx) = mpsc::channel();
30
         let (request_tx, request_rx) = mpsc::channel();
30
         let (result_tx, result_rx) = mpsc::channel();
31
         let (result_tx, result_rx) = mpsc::channel();
39
     }
40
     }
40
 
41
 
41
     fn work<F>(
42
     fn work<F>(
42
-        request_rx: mpsc::Receiver<(TileCoord, TileSourceId, String, PathBuf, bool)>,
43
-        result_tx: mpsc::Sender<(TileCoord, TileSourceId, Option<DynamicImage>)>,
43
+        request_rx: mpsc::Receiver<(Tile, String, PathBuf, bool)>,
44
+        result_tx: mpsc::Sender<(Tile, Option<DynamicImage>)>,
44
         notice_func: F,
45
         notice_func: F,
45
     )
46
     )
46
-        where F: Fn(TileCoord) + Sync + Send + 'static,
47
+        where F: Fn(Tile) + Sync + Send + 'static,
47
     {
48
     {
48
         let mut client_opt = None;
49
         let mut client_opt = None;
49
-        while let Ok((tile, source_id, url, path, write_to_file)) = request_rx.recv() {
50
+        while let Ok((tile, url, path, write_to_file)) = request_rx.recv() {
50
             println!("work {:?}", tile);
51
             println!("work {:?}", tile);
51
             match image::open(&path) {
52
             match image::open(&path) {
52
                 Ok(img) => {
53
                 Ok(img) => {
53
-                    result_tx.send((tile, source_id, Some(img))).unwrap();
54
+                    result_tx.send((tile, Some(img))).unwrap();
54
                     notice_func(tile);
55
                     notice_func(tile);
55
                     continue;
56
                     continue;
56
                 },
57
                 },
66
                             let mut buf: Vec<u8> = vec![];
67
                             let mut buf: Vec<u8> = vec![];
67
                             response.copy_to(&mut buf).unwrap();
68
                             response.copy_to(&mut buf).unwrap();
68
                             if let Ok(img) = image::load_from_memory(&buf) {
69
                             if let Ok(img) = image::load_from_memory(&buf) {
69
-                                result_tx.send((tile, source_id, Some(img))).unwrap();
70
+                                result_tx.send((tile, Some(img))).unwrap();
70
                                 notice_func(tile);
71
                                 notice_func(tile);
71
 
72
 
72
                                 if write_to_file {
73
                                 if write_to_file {
80
                     }
81
                     }
81
                 },
82
                 },
82
             }
83
             }
83
-            result_tx.send((tile, source_id, None)).unwrap();
84
+            result_tx.send((tile, None)).unwrap();
84
         }
85
         }
85
     }
86
     }
86
 
87
 
87
-    pub fn async_request(&mut self, tile: TileCoord, source: &TileSource, write_to_file: bool) {
88
-        if tile.zoom > source.max_tile_zoom() {
88
+    pub fn async_request(&mut self, tile_coord: TileCoord, source: &TileSource, write_to_file: bool) {
89
+        if tile_coord.zoom > source.max_tile_zoom() {
89
             return;
90
             return;
90
         }
91
         }
91
 
92
 
92
-        if !self.pending.contains(&(tile, source.id())) {
93
-            self.pending.insert((tile, source.id()));
93
+        let tile = Tile::new(tile_coord, source.id());
94
+
95
+        if !self.pending.contains(&tile) {
96
+            self.pending.insert(tile);
94
             self.request_tx.send((
97
             self.request_tx.send((
95
                 tile,
98
                 tile,
96
-                source.id(),
97
-                source.remote_tile_url(tile),
98
-                source.local_tile_path(tile),
99
+                source.remote_tile_url(tile_coord),
100
+                source.local_tile_path(tile_coord),
99
                 write_to_file
101
                 write_to_file
100
             )).unwrap();
102
             )).unwrap();
101
         }
103
         }
102
     }
104
     }
103
 
105
 
104
-    pub fn async_result(&mut self) -> Option<(TileCoord, DynamicImage)> {
106
+    pub fn async_result(&mut self) -> Option<(Tile, DynamicImage)> {
105
         match self.result_rx.try_recv() {
107
         match self.result_rx.try_recv() {
106
             Err(_) => None,
108
             Err(_) => None,
107
-            Ok((tile, source_id, None)) => {
108
-                self.pending.remove(&(tile, source_id));
109
+            Ok((tile, None)) => {
110
+                self.pending.remove(&tile);
109
                 None
111
                 None
110
             },
112
             },
111
-            Ok((tile, source_id, Some(img))) => {
112
-                self.pending.remove(&(tile, source_id));
113
+            Ok((tile, Some(img))) => {
114
+                self.pending.remove(&tile);
113
                 Some((tile, img))
115
                 Some((tile, img))
114
             },
116
             },
115
         }
117
         }

+ 14
- 18
src/tile_source.rs Zobrazit soubor

1
 use coord::TileCoord;
1
 use coord::TileCoord;
2
-use std::path::{Path, PathBuf};
2
+use std::path::PathBuf;
3
 
3
 
4
 
4
 
5
 #[derive(Clone, Debug)]
5
 #[derive(Clone, Debug)]
36
         }
36
         }
37
     }
37
     }
38
 
38
 
39
-    pub fn local_tile_path(&self, tile: TileCoord) -> PathBuf {
39
+    pub fn local_tile_path(&self, tile_coord: TileCoord) -> PathBuf {
40
         let mut path = PathBuf::from(&self.directory);
40
         let mut path = PathBuf::from(&self.directory);
41
-        path.push(tile.zoom.to_string());
42
-        path.push(tile.x.to_string());
43
-        path.push(tile.y.to_string() + ".png");
41
+        path.push(tile_coord.zoom.to_string());
42
+        path.push(tile_coord.x.to_string());
43
+        path.push(tile_coord.y.to_string() + ".png");
44
 
44
 
45
         path
45
         path
46
     }
46
     }
47
 
47
 
48
-    pub fn remote_tile_url(&self, tile: TileCoord) -> String {
49
-        Self::fill_template(&self.url_template, tile)
48
+    pub fn remote_tile_url(&self, tile_coord: TileCoord) -> String {
49
+        Self::fill_template(&self.url_template, tile_coord)
50
     }
50
     }
51
 
51
 
52
     pub fn max_tile_zoom(&self) -> u32 {
52
     pub fn max_tile_zoom(&self) -> u32 {
53
         self.max_zoom
53
         self.max_zoom
54
     }
54
     }
55
 
55
 
56
-    fn fill_template(template: &str, tile: TileCoord) -> String {
57
-        let x_str = tile.x.to_string();
58
-        let y_str = tile.y.to_string();
59
-        let z_str = tile.zoom.to_string();
60
-
61
-        //let len = (template.len() + x_str.len() + y_str.len() + z_str.len()).saturating_sub(9);
56
+    fn fill_template(template: &str, tile_coord: TileCoord) -> String {
57
+        let x_str = tile_coord.x.to_string();
58
+        let y_str = tile_coord.y.to_string();
59
+        let z_str = tile_coord.zoom.to_string();
62
 
60
 
63
         //TODO use the regex crate for templates or some other more elegant method
61
         //TODO use the regex crate for templates or some other more elegant method
64
-        let string = template.replacen("{x}", &x_str, 1);
65
-        let string = string.replacen("{y}", &y_str, 1);
66
-        let string = string.replacen("{z}", &z_str, 1);
67
-
68
-        return string;
62
+        template.replacen("{x}", &x_str, 1)
63
+                .replacen("{y}", &y_str, 1)
64
+                .replacen("{z}", &z_str, 1)
69
     }
65
     }
70
 }
66
 }