altoslib: Fix map preloading callbacks, run in separate thread
authorKeith Packard <keithp@keithp.com>
Thu, 5 May 2016 09:25:52 +0000 (02:25 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 5 May 2016 09:25:52 +0000 (02:25 -0700)
The map storage and tile callbacks were muddled together. Create
clearly separate states for map data and have status updates be
delivered when registering for new status events so that registration
is sufficient to track the state without an explicit call to get the
current state.

Run the map tile creation in a separate thread so that even checking
status of files on disk runs out of the UI thread.

These fixes serve to make the pacifier update more smoothly, and also
not over/under count tile loading so that the loading actually
completes when all of the tiles are loaded.

Signed-off-by: Keith Packard <keithp@keithp.com>
altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOffline.java
altosdroid/src/org/altusmetrum/AltosDroid/PreloadMapActivity.java
altoslib/AltosMap.java
altoslib/AltosMapCache.java
altoslib/AltosMapInterface.java
altoslib/AltosMapLoader.java
altoslib/AltosMapStore.java
altoslib/AltosMapTile.java
altoslib/AltosMapTileListener.java
altosuilib/AltosUIMapNew.java
altosuilib/AltosUIMapPreloadNew.java

index bde80cfc99146b35c011b744282ffc35886bdd14..ab142b175c43f4ba4a4e6d2cb23d46778bac835c 100644 (file)
@@ -133,7 +133,7 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
                        if (canvas.quickReject(pt.x, pt.y, pt.x + px_size, pt.y + px_size, Canvas.EdgeType.AA))
                                return;
 
                        if (canvas.quickReject(pt.x, pt.y, pt.x + px_size, pt.y + px_size, Canvas.EdgeType.AA))
                                return;
 
-                       AltosImage              altos_image = cache.get(this, store, px_size, px_size);
+                       AltosImage              altos_image = this.get_image();
 
                        MapImage                map_image = (MapImage) altos_image;
 
 
                        MapImage                map_image = (MapImage) altos_image;
 
@@ -150,8 +150,8 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
                                if (t.has_location()) {
                                        String  message = null;
                                        switch (status) {
                                if (t.has_location()) {
                                        String  message = null;
                                        switch (status) {
-                                       case AltosMapTile.loading:
-                                               message = "Loading...";
+                                       case AltosMapTile.fetching:
+                                               message = "Fetching...";
                                                break;
                                        case AltosMapTile.bad_request:
                                                message = "Internal error";
                                                break;
                                        case AltosMapTile.bad_request:
                                                message = "Internal error";
@@ -181,14 +181,14 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
                        }
                }
 
                        }
                }
 
-               public MapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(listener, upper_left, center, zoom, maptype, px_size, 2);
+               public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
+                       super(cache, upper_left, center, zoom, maptype, px_size, 2);
                }
 
        }
 
                }
 
        }
 
-       public AltosMapTile new_tile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new MapTile(listener, upper_left, center, zoom, maptype, px_size);
+       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
+               return new MapTile(cache, upper_left, center, zoom, maptype, px_size);
        }
 
        public AltosMapPath new_path() {
        }
 
        public AltosMapPath new_path() {
index 87f03a92f30a84c3328d6e7762de56f19d2c93ae..13a44e1f6902f3def172a88c8b31adb776729860 100644 (file)
@@ -107,7 +107,6 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
        }
 
        AltosMap        map;
        }
 
        AltosMap        map;
-       AltosMapLoader  loader;
 
        class PreloadMapImage implements AltosImage {
                public void flush() {
 
        class PreloadMapImage implements AltosImage {
                public void flush() {
@@ -137,14 +136,14 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
                public void paint(AltosMapTransform t) {
                }
 
                public void paint(AltosMapTransform t) {
                }
 
-               public PreloadMapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(listener, upper_left, center, zoom, maptype, px_size, 2);
+               public PreloadMapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
+                       super(cache, upper_left, center, zoom, maptype, px_size, 2);
                }
 
        }
 
                }
 
        }
 
-       public AltosMapTile new_tile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new PreloadMapTile(listener, upper_left, center, zoom, maptype, px_size);
+       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
+               return new PreloadMapTile(cache, upper_left, center, zoom, maptype, px_size);
        }
 
        public int width() {
        }
 
        public int width() {
@@ -265,7 +264,7 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
 
                        AltosDebug.debug("PreloadMap load %f %f %d %d %f %d\n",
                                         lat, lon, min, max, r, t);
 
                        AltosDebug.debug("PreloadMap load %f %f %d %d %f %d\n",
                                         lat, lon, min, max, r, t);
-                       loader.load(lat, lon, min, max, r, t);
+                       new AltosMapLoader(map, this, lat, lon, min, max, r, t);
                } catch (ParseException e) {
                        AltosDebug.debug("PreloadMap load raised exception %s", e.toString());
                }
                } catch (ParseException e) {
                        AltosDebug.debug("PreloadMap load raised exception %s", e.toString());
                }
@@ -398,8 +397,6 @@ public class PreloadMapActivity extends Activity implements AltosLaunchSiteListe
 
                map = new AltosMap(this);
 
 
                map = new AltosMap(this);
 
-               loader = new AltosMapLoader(map, this);
-
                // Listen for GPS and Network position updates
                LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 
                // Listen for GPS and Network position updates
                LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 
index 26851e961453e985169e990939e5b92da4137646..1841277f8bd61889390f0d5802dff09a7584b603 100644 (file)
@@ -328,7 +328,8 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                                if (!tiles.containsKey(point)) {
                                        AltosLatLon     ul = transform.lat_lon(point);
                                        AltosLatLon     center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
                                if (!tiles.containsKey(point)) {
                                        AltosLatLon     ul = transform.lat_lon(point);
                                        AltosLatLon     center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
-                                       AltosMapTile tile = map_interface.new_tile(this, ul, center, zoom, maptype, px_size);
+                                       AltosMapTile tile = map_interface.new_tile(cache, ul, center, zoom, maptype, px_size);
+                                       tile.add_listener(this);
                                        tiles.put(point, tile);
                                }
                        }
                                        tiles.put(point, tile);
                                }
                        }
@@ -345,11 +346,6 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                centre(lat, lon);
                tiles.clear();
                make_tiles();
                centre(lat, lon);
                tiles.clear();
                make_tiles();
-               for (AltosMapTile tile : tiles.values()) {
-                       tile.add_store_listener(this);
-                       if (tile.store_status() != AltosMapTile.loading)
-                               listener.notify_tile(tile, tile.store_status());
-               }
                repaint();
        }
 
                repaint();
        }
 
index 17a36ff341b02adf50cd8876468e66245216771d..38e0f769871a186d4ae434ce4d24668ba32e2e4c 100644 (file)
@@ -23,25 +23,20 @@ import java.net.*;
 public class AltosMapCache implements AltosMapCacheListener {
 
        /* An entry in the MapCache */
 public class AltosMapCache implements AltosMapCacheListener {
 
        /* An entry in the MapCache */
-       class MapCacheElement implements AltosMapStoreListener {
+       class MapCacheElement implements AltosMapTileListener {
 
                AltosMapTile            tile;           /* Notify when image has been loaded */
                AltosImage              image;
 
                AltosMapTile            tile;           /* Notify when image has been loaded */
                AltosImage              image;
-               AltosMapStore           store;
                long                    used;
 
                class loader implements Runnable {
                        public void run() {
                long                    used;
 
                class loader implements Runnable {
                        public void run() {
-                               if (image != null)
-                                       tile.notify_image(image);
-                               try {
-                                       image = map_interface.load_image(store.file);
-                               } catch (Exception ex) {
+                               if (image == null) {
+                                       try {
+                                               image = map_interface.load_image(tile.store.file);
+                                       } catch (Exception ex) {
+                                       }
                                }
                                }
-                               if (image == null)
-                                       tile.set_status(AltosMapTile.failed);
-                               else
-                                       tile.set_status(AltosMapTile.success);
                                tile.notify_image(image);
                        }
                }
                                tile.notify_image(image);
                        }
                }
@@ -60,41 +55,21 @@ public class AltosMapCache implements AltosMapCacheListener {
                }
 
                public boolean has_map() {
                }
 
                public boolean has_map() {
-                       return store.status() == AltosMapTile.success;
+                       return tile.status == AltosMapTile.loaded;
                }
 
                }
 
-               public synchronized void notify_store(AltosMapStore store, int status) {
-                       switch (status) {
-                       case AltosMapTile.loading:
-                               break;
-                       case AltosMapTile.success:
+               public synchronized void notify_tile(AltosMapTile tile, int status) {
+                       if (status == AltosMapTile.fetched) {
+                               System.out.printf("tile fetched, loading image\n");
                                load();
                                load();
-                               break;
-                       default:
-                               tile.set_status(status);
-                               tile.notify_image(null);
                        }
                }
 
                        }
                }
 
-               public MapCacheElement(AltosMapTile tile, AltosMapStore store) throws IOException {
+               public MapCacheElement(AltosMapTile tile) {
                        this.tile = tile;
                        this.image = null;
                        this.tile = tile;
                        this.image = null;
-                       this.store = store;
                        this.used = 0;
                        this.used = 0;
-
-                       int status = store.status();
-                       switch (status) {
-                       case AltosMapTile.loading:
-                               store.add_listener(this);
-                               break;
-                       case AltosMapTile.success:
-                               load();
-                               break;
-                       default:
-                               tile.set_status(status);
-                               tile.notify_image(null);
-                               break;
-                       }
+                       tile.add_listener(this);
                }
        }
 
                }
        }
 
@@ -135,7 +110,7 @@ public class AltosMapCache implements AltosMapCacheListener {
                }
        }
 
                }
        }
 
-       public AltosImage get(AltosMapTile tile, AltosMapStore store, int width, int height) {
+       public AltosImage get(AltosMapTile tile) {
                int             oldest = -1;
                long            age = used;
 
                int             oldest = -1;
                long            age = used;
 
@@ -148,7 +123,7 @@ public class AltosMapCache implements AltosMapCacheListener {
                                        oldest = i;
                                        break;
                                }
                                        oldest = i;
                                        break;
                                }
-                               if (store.equals(element.store)) {
+                               if (tile.store.equals(element.tile.store)) {
                                        element.used = used++;
                                        return element.image;
                                }
                                        element.used = used++;
                                        return element.image;
                                }
@@ -158,24 +133,15 @@ public class AltosMapCache implements AltosMapCacheListener {
                                }
                        }
 
                                }
                        }
 
-                       try {
-                               element = new MapCacheElement(tile, store);
-                               element.used = used++;
-                               if (elements[oldest] != null)
-                                       elements[oldest].flush();
+                       element = new MapCacheElement(tile);
+                       element.used = used++;
+                       if (elements[oldest] != null)
+                               elements[oldest].flush();
 
 
-                               elements[oldest] = element;
-
-                               if (element.image == null)
-                                       tile.set_status(AltosMapTile.loading);
-                               else
-                                       tile.set_status(AltosMapTile.success);
-
-                               return element.image;
-                       } catch (IOException e) {
-                               tile.set_status(AltosMapTile.failed);
-                               return null;
-                       }
+                       elements[oldest] = element;
+                       System.out.printf("AltosMapCache.get image ? %s\n",
+                                         element.image == null ? "false" : "true");
+                       return element.image;
                }
        }
 
                }
        }
 
index 71936ad2784e7db074d3145ba66eadcc5d974fe1..756a78f20e88c437d9fef8c2bd9767c2b47d104e 100644 (file)
@@ -29,7 +29,7 @@ public interface AltosMapInterface {
 
        public abstract AltosMapMark new_mark(double lat, double lon, int state);
 
 
        public abstract AltosMapMark new_mark(double lat, double lon, int state);
 
-       public abstract AltosMapTile new_tile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size);
+       public abstract AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size);
 
        public abstract int width();
 
 
        public abstract int width();
 
index 15fd756ef5de6d6eea07ba959db483d405d3ec63..7112a1c4d22f06e8c7af078ff8b4ef2c93957fe7 100644 (file)
@@ -24,7 +24,7 @@ import java.lang.Math;
 import java.net.URL;
 import java.net.URLConnection;
 
 import java.net.URL;
 import java.net.URLConnection;
 
-public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListener {
+public class AltosMapLoader extends Thread implements AltosMapTileListener {
        AltosMapLoaderListener  listener;
 
        double  latitude, longitude;
        AltosMapLoaderListener  listener;
 
        double  latitude, longitude;
@@ -91,10 +91,8 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen
                                AltosPointInt   point = new AltosPointInt(x, y);
                                AltosLatLon     ul = transform.lat_lon(point);
                                AltosLatLon     center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
                                AltosPointInt   point = new AltosPointInt(x, y);
                                AltosLatLon     ul = transform.lat_lon(point);
                                AltosLatLon     center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
-                               AltosMapTile    tile = map.map_interface.new_tile(this, ul, center, zoom, maptype, AltosMap.px_size);
-                               tile.add_store_listener(this);
-                               if (tile.store_status() != AltosMapTile.loading)
-                                       notify_tile(tile, tile.store_status());
+                               AltosMapTile    tile = map.map_interface.new_tile(null, ul, center, zoom, maptype, AltosMap.px_size);
+                               tile.add_listener(this);
                        }
                }
        }
                        }
                }
        }
@@ -123,7 +121,7 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen
                do_load();
        }
 
                do_load();
        }
 
-       private void start_load() {
+       public void run() {
 
                cur_z = min_z;
                int ntype = 0;
 
                cur_z = min_z;
                int ntype = 0;
@@ -138,66 +136,64 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen
 
                cur_type = next_type(0);
 
 
                cur_type = next_type(0);
 
+               tiles_total = 0;
                for (int z = min_z; z <= max_z; z++)
                for (int z = min_z; z <= max_z; z++)
-                       tiles_total += tiles_per_layer(z);
+                       tiles_total += tiles_per_layer(z) * ntype;
 
                layers_total = (max_z - min_z + 1) * ntype;
                layers_loaded = 0;
                tiles_loaded_total = 0;
 
 
                layers_total = (max_z - min_z + 1) * ntype;
                layers_loaded = 0;
                tiles_loaded_total = 0;
 
-               listener.debug("total tiles %d\n", tiles_total);
+               listener.debug("total tiles %d layers %d\n", tiles_total, layers_total);
 
                listener.loader_start(tiles_total);
                do_load();
        }
 
 
                listener.loader_start(tiles_total);
                do_load();
        }
 
-       public void load(double latitude, double longitude, int min_z, int max_z, double radius, int all_types) {
-               listener.debug("lat %f lon %f min_z %d max_z %d radius %f all_types %d\n",
-                              latitude, longitude, min_z, max_z, radius, all_types);
-               this.latitude = latitude;
-               this.longitude = longitude;
-               this.min_z = min_z;
-               this.max_z = max_z;
-               this.radius = radius;
-               this.all_types = all_types;
-               start_load();
-       }
-
-       public synchronized void notify_store(AltosMapStore store, int status) {
+       public synchronized void notify_tile(AltosMapTile tile, int status) {
                boolean do_next = false;
                boolean do_next = false;
-               if (status == AltosMapTile.loading)
+               if (status == AltosMapTile.fetching)
                        return;
 
                        return;
 
+               tile.remove_listener(this);
+
                if (layers_loaded >= layers_total)
                        return;
 
                ++tiles_loaded_total;
                ++tiles_loaded_layer;
 
                if (layers_loaded >= layers_total)
                        return;
 
                ++tiles_loaded_total;
                ++tiles_loaded_layer;
 
+               listener.debug("AltosMapLoader.notify_tile status %d total %d of %d layer %d of %d\n",
+                              status, tiles_loaded_total, tiles_total, tiles_loaded_layer, tiles_this_layer);
+
                if (tiles_loaded_layer == tiles_this_layer) {
                        ++layers_loaded;
                        listener.debug("%d layers loaded\n", layers_loaded);
                if (tiles_loaded_layer == tiles_this_layer) {
                        ++layers_loaded;
                        listener.debug("%d layers loaded\n", layers_loaded);
-                       if (layers_loaded == layers_total) {
-                               listener.loader_done(tiles_total);
-                               return;
-                       } else {
-                               do_next = true;
-                       }
+                       do_next = true;
                }
                }
-               listener.loader_notify(tiles_loaded_total,
-                                      tiles_total, store.file.toString());
-               if (do_next)
-                       next_load();
-       }
 
 
-       public synchronized void notify_tile(AltosMapTile tile, int status) {
-               notify_store(tile.store, status);
+               if (tiles_loaded_total == tiles_total)
+                       listener.loader_done(tiles_total);
+               else {
+                       listener.loader_notify(tiles_loaded_total,
+                                              tiles_total, tile.store.file.toString());
+                       if (do_next)
+                               next_load();
+               }
        }
 
        }
 
-       public AltosMapCache cache() { return map.cache(); }
-
-       public AltosMapLoader(AltosMap map, AltosMapLoaderListener listener) {
+       public AltosMapLoader(AltosMap map, AltosMapLoaderListener listener,
+                             double latitude, double longitude, int min_z, int max_z, double radius, int all_types) {
+               listener.debug("lat %f lon %f min_z %d max_z %d radius %f all_types %d\n",
+                              latitude, longitude, min_z, max_z, radius, all_types);
                this.map = map;
                this.listener = listener;
                this.map = map;
                this.listener = listener;
+               this.latitude = latitude;
+               this.longitude = longitude;
+               this.min_z = min_z;
+               this.max_z = max_z;
+               this.radius = radius;
+               this.all_types = all_types;
+               start();
        }
 }
        }
 }
index eebef310688de8908476aeb020ba715b521141c9..aed365ca175e07ea81abe05b7535b707227887dd 100644 (file)
@@ -35,6 +35,7 @@ public class AltosMapStore {
        public synchronized void add_listener(AltosMapStoreListener listener) {
                if (!listeners.contains(listener))
                        listeners.add(listener);
        public synchronized void add_listener(AltosMapStoreListener listener) {
                if (!listeners.contains(listener))
                        listeners.add(listener);
+               listener.notify_store(this, status);
        }
 
        public synchronized void remove_listener(AltosMapStoreListener listener) {
        }
 
        public synchronized void remove_listener(AltosMapStoreListener listener) {
@@ -110,7 +111,7 @@ public class AltosMapStore {
                                file.delete();
                        return AltosMapTile.bad_request;
                }
                                file.delete();
                        return AltosMapTile.bad_request;
                }
-               return AltosMapTile.success;
+               return AltosMapTile.fetched;
        }
 
        static Object   fetch_lock = new Object();
        }
 
        static Object   fetch_lock = new Object();
@@ -118,42 +119,42 @@ public class AltosMapStore {
        static final long       forbidden_interval = 60l * 1000l * 1000l * 1000l;
        static final long       google_maps_ratelimit_ms = 1200;
 
        static final long       forbidden_interval = 60l * 1000l * 1000l * 1000l;
        static final long       google_maps_ratelimit_ms = 1200;
 
-       static Object   loader_lock = new Object();
+       static Object   fetcher_lock = new Object();
 
        static LinkedList<AltosMapStore> waiting = new LinkedList<AltosMapStore>();
        static LinkedList<AltosMapStore> running = new LinkedList<AltosMapStore>();
 
 
        static LinkedList<AltosMapStore> waiting = new LinkedList<AltosMapStore>();
        static LinkedList<AltosMapStore> running = new LinkedList<AltosMapStore>();
 
-       static final int concurrent_loaders = 128;
+       static final int concurrent_fetchers = 128;
 
 
-       static void start_loaders() {
-               while (!waiting.isEmpty() && running.size() < concurrent_loaders) {
+       static void start_fetchers() {
+               while (!waiting.isEmpty() && running.size() < concurrent_fetchers) {
                        AltosMapStore   s = waiting.remove();
                        running.add(s);
                        AltosMapStore   s = waiting.remove();
                        running.add(s);
-                       Thread lt = s.make_loader_thread();
+                       Thread lt = s.make_fetcher_thread();
                        lt.start();
                }
        }
 
                        lt.start();
                }
        }
 
-       void finish_loader() {
-               synchronized(loader_lock) {
+       void finish_fetcher() {
+               synchronized(fetcher_lock) {
                        running.remove(this);
                        running.remove(this);
-                       start_loaders();
+                       start_fetchers();
                }
        }
 
                }
        }
 
-       void add_loader() {
-               synchronized(loader_lock) {
+       void add_fetcher() {
+               synchronized(fetcher_lock) {
                        waiting.add(this);
                        waiting.add(this);
-                       start_loaders();
+                       start_fetchers();
                }
        }
 
                }
        }
 
-       class loader implements Runnable {
+       class fetcher implements Runnable {
 
                public void run() {
                        try {
                                if (file.exists()) {
 
                public void run() {
                        try {
                                if (file.exists()) {
-                                       notify_listeners(AltosMapTile.success);
+                                       notify_listeners(AltosMapTile.fetched);
                                        return;
                                }
 
                                        return;
                                }
 
@@ -170,7 +171,7 @@ public class AltosMapStore {
                                        synchronized (fetch_lock) {
                                                long startTime = System.nanoTime();
                                                new_status = fetch_url();
                                        synchronized (fetch_lock) {
                                                long startTime = System.nanoTime();
                                                new_status = fetch_url();
-                                               if (new_status == AltosMapTile.success) {
+                                               if (new_status == AltosMapTile.fetched) {
                                                        long duration_ms = (System.nanoTime() - startTime) / 1000000;
                                                        if (duration_ms < google_maps_ratelimit_ms) {
                                                                try {
                                                        long duration_ms = (System.nanoTime() - startTime) / 1000000;
                                                        if (duration_ms < google_maps_ratelimit_ms) {
                                                                try {
@@ -186,17 +187,17 @@ public class AltosMapStore {
                                }
                                notify_listeners(new_status);
                        } finally {
                                }
                                notify_listeners(new_status);
                        } finally {
-                               finish_loader();
+                               finish_fetcher();
                        }
                }
        }
 
                        }
                }
        }
 
-       private Thread make_loader_thread() {
-               return new Thread(new loader());
+       private Thread make_fetcher_thread() {
+               return new Thread(new fetcher());
        }
 
        }
 
-       private void load() {
-               add_loader();
+       private void fetch() {
+               add_fetcher();
        }
 
        private AltosMapStore (String url, File file) {
        }
 
        private AltosMapStore (String url, File file) {
@@ -204,10 +205,10 @@ public class AltosMapStore {
                this.file = file;
 
                if (file.exists())
                this.file = file;
 
                if (file.exists())
-                       status = AltosMapTile.success;
+                       status = AltosMapTile.fetched;
                else {
                else {
-                       status = AltosMapTile.loading;
-                       load();
+                       status = AltosMapTile.fetching;
+                       fetch();
                }
        }
 
                }
        }
 
index 076c5937fe1cb36bf5fa3e9c016d789eb78e8b01..fdc8ff65995ab0752843e88ad3f58b62afd52049 100644 (file)
@@ -20,22 +20,23 @@ package org.altusmetrum.altoslib_10;
 import java.io.*;
 import java.util.*;
 
 import java.io.*;
 import java.util.*;
 
-public abstract class AltosMapTile implements AltosFontListener {
-       AltosMapTileListener    listener;
+public abstract class AltosMapTile implements AltosFontListener, AltosMapStoreListener {
+       LinkedList<AltosMapTileListener>        listeners = new LinkedList<AltosMapTileListener>();
        public AltosLatLon      upper_left, center;
        public int              px_size;
        int             zoom;
        int             maptype;
        int             scale;
        public AltosLatLon      upper_left, center;
        public int              px_size;
        int             zoom;
        int             maptype;
        int             scale;
+       private AltosMapCache   cache;
        public AltosMapStore    store;
        public AltosMapStore    store;
-       public AltosMapCache    cache;
        public int      status;
 
        public int      status;
 
-       static public final int success = 0;
-       static public final int loading = 1;
-       static public final int failed = 2;
-       static public final int bad_request = 3;
-       static public final int forbidden = 4;
+       static public final int loaded = 0;     /* loaded from file */
+       static public final int fetched = 1;    /* downloaded to file */
+       static public final int fetching = 2;   /* downloading from net */
+       static public final int failed = 3;     /* loading from file failed */
+       static public final int bad_request = 4;/* downloading failed */
+       static public final int forbidden = 5;  /* downloading failed */
 
        private File map_file() {
                double lat = center.lat;
 
        private File map_file() {
                double lat = center.lat;
@@ -79,33 +80,46 @@ public abstract class AltosMapTile implements AltosFontListener {
        public void font_size_changed(int font_size) {
        }
 
        public void font_size_changed(int font_size) {
        }
 
-       public void set_status(int status) {
+       private synchronized void notify_listeners(int status) {
                this.status = status;
                this.status = status;
-               listener.notify_tile(this, status);
+               for (AltosMapTileListener listener : listeners)
+                       listener.notify_tile(this, status);
        }
 
        }
 
-       public void notify_image(AltosImage image) {
-               listener.notify_tile(this, status);
+       public void notify_store(AltosMapStore store, int status) {
+//             System.out.printf("AltosMapTile.notify_store %d\n", status);
+               notify_listeners(status);
        }
 
        }
 
-       public int store_status() {
-               return store.status();
+       public void notify_image(AltosImage image) {
+               if (image == null)
+                       status = failed;
+               else
+                       status = loaded;
+               notify_listeners(status);
        }
 
        }
 
-       public void add_store_listener(AltosMapStoreListener listener) {
-               store.add_listener(listener);
+       public abstract void paint(AltosMapTransform t);
+
+       public AltosImage get_image() {
+               if (cache == null)
+                       return null;
+               return cache.get(this);
        }
 
        }
 
-       public void remove_store_listener(AltosMapStoreListener listener) {
-               store.remove_listener(listener);
+       public synchronized void add_listener(AltosMapTileListener listener) {
+               if (!listeners.contains(listener))
+                       listeners.add(listener);
+               listener.notify_tile(this, status);
        }
 
        }
 
-       public abstract void paint(AltosMapTransform t);
+       public synchronized void remove_listener(AltosMapTileListener listener) {
+               listeners.remove(listener);
+       }
 
 
-       public AltosMapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
-               this.listener = listener;
+       public AltosMapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               this.cache = cache;
                this.upper_left = upper_left;
                this.upper_left = upper_left;
-               this.cache = listener.cache();
 
                while (center.lon < -180.0)
                        center.lon += 360.0;
 
                while (center.lon < -180.0)
                        center.lon += 360.0;
@@ -118,11 +132,11 @@ public abstract class AltosMapTile implements AltosFontListener {
                this.px_size = px_size;
                this.scale = scale;
 
                this.px_size = px_size;
                this.scale = scale;
 
-               status = AltosMapTile.loading;
                store = AltosMapStore.get(map_url(), map_file());
                store = AltosMapStore.get(map_url(), map_file());
+               store.add_listener(this);
        }
 
        }
 
-       public AltosMapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               this(listener, upper_left, center, zoom, maptype, px_size, 1);
+       public AltosMapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
+               this(cache, upper_left, center, zoom, maptype, px_size, 1);
        }
 }
        }
 }
index 6ab03638b0b27047fed51c363a75199b178e1511..6d78b205207a4cfaf62c2f10af81edb6b60fe542 100644 (file)
@@ -19,6 +19,4 @@ package org.altusmetrum.altoslib_10;
 
 public interface AltosMapTileListener {
        abstract public void notify_tile(AltosMapTile tile, int status);
 
 public interface AltosMapTileListener {
        abstract public void notify_tile(AltosMapTile tile, int status);
-
-       abstract public AltosMapCache cache();
 }
 }
index c867bf2e1ba2dcbe6aab3a72e94060f0cac57e6b..a90e8c91ae76f9c9387db39db1a47a2b646956c7 100644 (file)
@@ -241,8 +241,8 @@ public class AltosUIMapNew extends JComponent implements AltosFlightDisplay, Alt
        }
 
        class MapTile extends AltosMapTile {
        }
 
        class MapTile extends AltosMapTile {
-               public MapTile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-                       super(listener, upper_left, center, zoom, maptype, px_size);
+               public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
+                       super(cache, upper_left, center, zoom, maptype, px_size);
                }
 
                public void paint(AltosMapTransform t) {
                }
 
                public void paint(AltosMapTransform t) {
@@ -254,11 +254,9 @@ public class AltosUIMapNew extends JComponent implements AltosFlightDisplay, Alt
                        if (!g.hitClip(point.x, point.y, px_size, px_size))
                                return;
 
                        if (!g.hitClip(point.x, point.y, px_size, px_size))
                                return;
 
-                       AltosImage altos_image = cache.get(this, store, px_size, px_size);
-
+                       AltosImage      altos_image = get_image();
                        AltosUIImage    ui_image = (AltosUIImage) altos_image;
                        AltosUIImage    ui_image = (AltosUIImage) altos_image;
-
-                       Image image = null;
+                       Image           image = null;
 
                        if (ui_image != null)
                                image = ui_image.image;
 
                        if (ui_image != null)
                                image = ui_image.image;
@@ -272,8 +270,8 @@ public class AltosUIMapNew extends JComponent implements AltosFlightDisplay, Alt
                                if (t.has_location()) {
                                        String  message = null;
                                        switch (status) {
                                if (t.has_location()) {
                                        String  message = null;
                                        switch (status) {
-                                       case AltosMapTile.loading:
-                                               message = "Loading...";
+                                       case AltosMapTile.fetching:
+                                               message = "Fetching...";
                                                break;
                                        case AltosMapTile.bad_request:
                                                message = "Internal error";
                                                break;
                                        case AltosMapTile.bad_request:
                                                message = "Internal error";
@@ -334,8 +332,8 @@ public class AltosUIMapNew extends JComponent implements AltosFlightDisplay, Alt
                return new MapMark(lat, lon, state);
        }
 
                return new MapMark(lat, lon, state);
        }
 
-       public AltosMapTile new_tile(AltosMapTileListener listener, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
-               return new MapTile(listener, upper_left, center, zoom, maptype, px_size);
+       public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
+               return new MapTile(cache, upper_left, center, zoom, maptype, px_size);
        }
 
        public int width() {
        }
 
        public int width() {
index b5f4dbf8b64b737cd9e78ed1f3d75cab583fdf54..3269bbddbdeaaa35535483b90dd61978584b0049 100644 (file)
@@ -127,8 +127,6 @@ public class AltosUIMapPreloadNew extends AltosUIFrame implements ActionListener
 
        JProgressBar    pbar;
 
 
        JProgressBar    pbar;
 
-       AltosMapLoader  loader;
-
        JLabel          site_list_label;
        JComboBox<AltosLaunchSite>      site_list;
 
        JLabel          site_list_label;
        JComboBox<AltosLaunchSite>      site_list;
 
@@ -238,7 +236,10 @@ public class AltosUIMapPreloadNew extends AltosUIFrame implements ActionListener
                                                r = r * 1000;
                                        loading = true;
 
                                                r = r * 1000;
                                        loading = true;
 
-                                       loader.load(latitude, longitude, min_z, max_z, r, all_types());
+                                       new AltosMapLoader(map.map, this,
+                                                          latitude, longitude,
+                                                          min_z, max_z, r, all_types());
+
                                } catch (ParseException pe) {
                                        load_button.setSelected(false);
                                }
                                } catch (ParseException pe) {
                                        load_button.setSelected(false);
                                }
@@ -271,8 +272,6 @@ public class AltosUIMapPreloadNew extends AltosUIFrame implements ActionListener
 
                map = new AltosUIMapNew();
 
 
                map = new AltosUIMapNew();
 
-               loader = new AltosMapLoader(map.map, this);
-
                c.fill = GridBagConstraints.BOTH;
                c.anchor = GridBagConstraints.CENTER;
                c.insets = i;
                c.fill = GridBagConstraints.BOTH;
                c.anchor = GridBagConstraints.CENTER;
                c.insets = i;