e849da79893f757713e48f658333f01caa2dc719
[fw/altos] / altosuilib / AltosUIMapCache.java
1 /*
2  * Copyright © 2010 Anthony Towns <aj@erisian.com.au>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package org.altusmetrum.altosuilib_2;
19
20 import javax.swing.*;
21 import javax.imageio.ImageIO;
22 import java.awt.image.*;
23 import java.awt.*;
24 import java.io.*;
25 import java.net.*;
26
27 public class AltosUIMapCache {
28         static final int        success = 0;
29         static final int        loading = 1;
30         static final int        failed = 2;
31         static final int        bad_request = 3;
32         static final int        forbidden = 4;
33
34         static private Object fetch_lock = new Object();
35
36         static final int                min_cache_size = 9;
37         static final int                max_cache_size = 24;
38
39         static int                      cache_size = min_cache_size;
40
41         static AltosUIMapImage[]        images = new AltosUIMapImage[cache_size];
42
43         static Object cache_lock = new Object();
44
45         public  static void set_cache_size(int new_size) {
46                 if (new_size < min_cache_size)
47                         new_size = min_cache_size;
48                 if (new_size > max_cache_size)
49                         new_size = max_cache_size;
50                 if (new_size == cache_size)
51                         return;
52
53                 synchronized(cache_lock) {
54                         AltosUIMapImage[]       new_images = new AltosUIMapImage[new_size];
55
56                         for (int i = 0; i < cache_size; i++) {
57                                 if (i < new_size)
58                                         new_images[i] = images[i];
59                                 else if (images[i] != null)
60                                         images[i].flush();
61                         }
62                         images = new_images;
63                         cache_size = new_size;
64                 }
65         }
66
67         static long                     used;
68
69         public static Image get(AltosUIMapTile tile, AltosUIMapStore store, int width, int height) {
70                 int             oldest = -1;
71                 long            age = used;
72
73                 synchronized(cache_lock) {
74                         AltosUIMapImage image = null;
75                         for (int i = 0; i < cache_size; i++) {
76                                 image = images[i];
77
78                                 if (image == null) {
79                                         oldest = i;
80                                         break;
81                                 }
82                                 if (store.equals(image.store)) {
83                                         image.used = used++;
84                                         return image.image;
85                                 }
86                                 if (image.used < age) {
87                                         oldest = i;
88                                         age = image.used;
89                                 }
90                         }
91
92                         try {
93                                 image = new AltosUIMapImage(tile, store);
94                                 image.used = used++;
95                                 if (images[oldest] != null)
96                                         images[oldest].flush();
97
98                                 images[oldest] = image;
99
100                                 if (image.image == null)
101                                         tile.set_status(loading);
102                                 else
103                                         tile.set_status(success);
104
105                                 return image.image;
106                         } catch (IOException e) {
107                                 tile.set_status(failed);
108                                 return null;
109                         }
110                 }
111         }
112 }