JobQueue now belongs to TileManager instead of TileLayer

This commit is contained in:
Hannes Janetzek 2013-05-07 08:11:39 +02:00
parent 0174c0229d
commit 7220fee194
7 changed files with 52 additions and 61 deletions

View File

@ -28,8 +28,6 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
protected final TileManager mTileManager; protected final TileManager mTileManager;
protected final JobQueue mJobQueue;
protected final int mNumTileLoader = 4; protected final int mNumTileLoader = 4;
protected final ArrayList<T> mTileLoader; protected final ArrayList<T> mTileLoader;
@ -44,12 +42,10 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
// to load queue and managing in-memory tile cache. // to load queue and managing in-memory tile cache.
mTileManager = new TileManager(mapView, this, maxZoom); mTileManager = new TileManager(mapView, this, maxZoom);
mJobQueue = new JobQueue();
// Instantiate TileLoader threads // Instantiate TileLoader threads
mTileLoader = new ArrayList<T>(); mTileLoader = new ArrayList<T>();
for (int i = 0; i < mNumTileLoader; i++) { for (int i = 0; i < mNumTileLoader; i++) {
T tileGenerator = createLoader(mJobQueue, mTileManager); T tileGenerator = createLoader(mTileManager);
mTileLoader.add(tileGenerator); mTileLoader.add(tileGenerator);
tileGenerator.start(); tileGenerator.start();
} }
@ -59,7 +55,7 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
mLayer = new TileRenderLayer(mapView, mTileManager); mLayer = new TileRenderLayer(mapView, mTileManager);
} }
abstract protected T createLoader(JobQueue q, TileManager tm); abstract protected T createLoader(TileManager tm);
public TileRenderLayer getTileLayer() { public TileRenderLayer getTileLayer() {
return (TileRenderLayer) mLayer; return (TileRenderLayer) mLayer;
@ -83,10 +79,9 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
mTileManager.destroy(); mTileManager.destroy();
for (T tileWorker : mTileLoader) { for (T tileWorker : mTileLoader) {
tileWorker.pause(); tileWorker.pause();
tileWorker.interrupt(); tileWorker.interrupt();
//tileWorker.getMapDatabase().close();
tileWorker.cleanup(); tileWorker.cleanup();
try { try {
@ -103,20 +98,7 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
mClearMap = true; mClearMap = true;
} }
void notifyLoaders() {
/**
* add jobs and remember TileGenerators that stuff needs to be done
*
* @param jobs
* tile jobs
*/
public void setJobs(MapTile[] jobs) {
if (jobs == null) {
mJobQueue.clear();
return;
}
mJobQueue.setJobs(jobs);
for (int i = 0; i < mNumTileLoader; i++) { for (int i = 0; i < mNumTileLoader; i++) {
T m = mTileLoader.get(i); T m = mTileLoader.get(i);
synchronized (m) { synchronized (m) {

View File

@ -19,14 +19,11 @@ import org.oscim.utils.PausableThread;
public abstract class TileLoader extends PausableThread { public abstract class TileLoader extends PausableThread {
private static int id; private static int id;
private final String THREAD_NAME; private final String THREAD_NAME;
private final JobQueue mJobQueue;
private final TileManager mTileManager; private final TileManager mTileManager;
public TileLoader(JobQueue jobQueue, TileManager tileManager) { public TileLoader(TileManager tileManager) {
super(); super();
mJobQueue = jobQueue;
mTileManager = tileManager; mTileManager = tileManager;
THREAD_NAME = "TileLoader" + (id++); THREAD_NAME = "TileLoader" + (id++);
} }
@ -38,7 +35,7 @@ public abstract class TileLoader extends PausableThread {
@Override @Override
protected void doWork() { protected void doWork() {
MapTile tile = mJobQueue.poll(); MapTile tile = mTileManager.jobQueue.poll();
if (tile == null) if (tile == null)
return; return;
@ -69,6 +66,6 @@ public abstract class TileLoader extends PausableThread {
@Override @Override
protected boolean hasWork() { protected boolean hasWork() {
return !mJobQueue.isEmpty(); return !mTileManager.jobQueue.isEmpty();
} }
} }

View File

@ -86,6 +86,8 @@ public class TileManager {
private TileSet mCurrentTiles; private TileSet mCurrentTiles;
/* package */TileSet mNewTiles; /* package */TileSet mNewTiles;
final JobQueue jobQueue;
private final QuadTreeIndex<MapTile> mIndex = new QuadTreeIndex<MapTile>() { private final QuadTreeIndex<MapTile> mIndex = new QuadTreeIndex<MapTile>() {
@Override @Override
@ -111,7 +113,7 @@ public class TileManager {
} }
}; };
private final float[] mBoxCoords = new float[8]; private final float[] mMapPlane = new float[8];
private final TileLayer<?> mTileLayer; private final TileLayer<?> mTileLayer;
public TileManager(MapView mapView, TileLayer<?> tileLayer, int maxZoom) { public TileManager(MapView mapView, TileLayer<?> tileLayer, int maxZoom) {
@ -119,6 +121,8 @@ public class TileManager {
mTileLayer = tileLayer; mTileLayer = tileLayer;
mMaxZoom = maxZoom; mMaxZoom = maxZoom;
mMapViewPosition = mapView.getMapViewPosition(); mMapViewPosition = mapView.getMapViewPosition();
jobQueue = new JobQueue();
mJobs = new ArrayList<MapTile>(); mJobs = new ArrayList<MapTile>();
mTiles = new MapTile[CACHE_TILES_MAX]; mTiles = new MapTile[CACHE_TILES_MAX];
@ -126,7 +130,6 @@ public class TileManager {
mTilesForUpload = 0; mTilesForUpload = 0;
mUpdateSerial = 0; mUpdateSerial = 0;
mInitialized = false; mInitialized = false;
} }
@ -194,29 +197,33 @@ public class TileManager {
// start with old jobs while new jobs are calculated, which // start with old jobs while new jobs are calculated, which
// should increase the chance that they are free when new // should increase the chance that they are free when new
// jobs come in. // jobs come in.
mTileLayer.setJobs(null); jobQueue.clear();
// load some tiles more than currently visible (* 0.75) // load some tiles more than currently visible (* 0.75)
double scale = pos.scale * 0.9f; double scale = pos.scale * 0.9f;
int tileZoom = FastMath.clamp(pos.zoomLevel, MIN_ZOOMLEVEL, mMaxZoom); int tileZoom = FastMath.clamp(pos.zoomLevel, MIN_ZOOMLEVEL, mMaxZoom);
mMapViewPosition.getMapViewProjection(mBoxCoords); mMapViewPosition.getMapViewProjection(mMapPlane);
// scan visible tiles. callback function calls 'addTile' // scan visible tiles. callback function calls 'addTile'
// which updates mNewTiles // which updates mNewTiles
mNewTiles.cnt = 0; mNewTiles.cnt = 0;
mScanBox.scan(pos.x, pos.y, scale, tileZoom, mBoxCoords); mScanBox.scan(pos.x, pos.y, scale, tileZoom, mMapPlane);
MapTile[] newTiles = mNewTiles.tiles; MapTile[] newTiles = mNewTiles.tiles;
int newCnt = mNewTiles.cnt;
MapTile[] curTiles = mCurrentTiles.tiles; MapTile[] curTiles = mCurrentTiles.tiles;
int curCnt = mCurrentTiles.cnt;
boolean changed = (mNewTiles.cnt != mCurrentTiles.cnt); boolean changed = (newCnt != curCnt);
Arrays.sort(mNewTiles.tiles, 0, mNewTiles.cnt, TileSet.coordComparator); Arrays.sort(newTiles, 0, newCnt, TileSet.coordComparator);
if (!changed) { if (!changed) {
for (int i = 0, n = mNewTiles.cnt; i < n; i++) { // compare if any tile has changed
for (int i = 0; i < newCnt; i++) {
if (newTiles[i] != curTiles[i]) { if (newTiles[i] != curTiles[i]) {
changed = true; changed = true;
break; break;
@ -227,11 +234,11 @@ public class TileManager {
if (changed) { if (changed) {
synchronized (mTilelock) { synchronized (mTilelock) {
// lock new tiles // lock new tiles
for (int i = 0, n = mNewTiles.cnt; i < n; i++) for (int i = 0; i < newCnt; i++)
newTiles[i].lock(); newTiles[i].lock();
// unlock previous tiles // unlock previous tiles
for (int i = 0, n = mCurrentTiles.cnt; i < n; i++) { for (int i = 0; i < curCnt; i++) {
curTiles[i].unlock(); curTiles[i].unlock();
curTiles[i] = null; curTiles[i] = null;
} }
@ -257,7 +264,9 @@ public class TileManager {
updateTileDistances(jobs, jobs.length, pos); updateTileDistances(jobs, jobs.length, pos);
// sets tiles to state == LOADING // sets tiles to state == LOADING
mTileLayer.setJobs(jobs);
jobQueue.setJobs(jobs);
mTileLayer.notifyLoaders();
mJobs.clear(); mJobs.clear();
/* limit cache items */ /* limit cache items */
@ -269,6 +278,11 @@ public class TileManager {
limitCache(pos, remove); limitCache(pos, remove);
} }
/** only used in setmapDatabase -- deprecate?*/
public void clearJobs() {
jobQueue.clear();
}
/** /**
* Retrive a TileSet of current tiles. * Retrive a TileSet of current tiles.
* Tiles remain locked in cache until the set is unlocked by either passing * Tiles remain locked in cache until the set is unlocked by either passing
@ -409,12 +423,12 @@ public class TileManager {
mTilesCount--; mTilesCount--;
} }
private static void updateTileDistances(MapTile[] tiles, int size, MapPosition mapPosition) { private static void updateTileDistances(MapTile[] tiles, int size, MapPosition pos) {
// TODO there is probably a better quad-tree distance function // TODO there is probably a better quad-tree distance function
int zoom = 20; int zoom = 20;
long x = (long) (mapPosition.x * (1 << zoom)); long x = (long) (pos.x * (1 << zoom));
long y = (long) (mapPosition.y * (1 << zoom)); long y = (long) (pos.y * (1 << zoom));
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
@ -435,7 +449,7 @@ public class TileManager {
dy = t.tileY - my; dy = t.tileY - my;
} }
int dz = (mapPosition.zoomLevel - t.zoomLevel); int dz = (pos.zoomLevel - t.zoomLevel);
if (dz == 0) if (dz == 0)
dz = 1; dz = 1;
else if (dz < -1) else if (dz < -1)
@ -445,7 +459,7 @@ public class TileManager {
} }
} }
private void limitCache(MapPosition mapPosition, int remove) { private void limitCache(MapPosition pos, int remove) {
MapTile[] tiles = mTiles; MapTile[] tiles = mTiles;
int size = mTilesSize; int size = mTilesSize;
@ -472,7 +486,7 @@ public class TileManager {
} }
if (remove > 10 || newTileCnt > MAX_TILES_IN_QUEUE) { if (remove > 10 || newTileCnt > MAX_TILES_IN_QUEUE) {
updateTileDistances(tiles, size, mapPosition); updateTileDistances(tiles, size, pos);
TileDistanceSort.sort(tiles, 0, size); TileDistanceSort.sort(tiles, 0, size);

View File

@ -21,7 +21,6 @@ import java.net.URLConnection;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.layers.tile.JobQueue;
import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLayer; import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.TileLoader; import org.oscim.layers.tile.TileLoader;
@ -45,8 +44,8 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
} }
@Override @Override
protected TileLoader createLoader(JobQueue q, TileManager tm) { protected TileLoader createLoader(TileManager tm) {
return new TileLoader(q, tm) { return new TileLoader(tm) {
@Override @Override
protected boolean executeJob(MapTile tile) { protected boolean executeJob(MapTile tile) {

View File

@ -18,7 +18,6 @@ import org.oscim.core.GeometryBuffer;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.graphics.Color; import org.oscim.graphics.Color;
import org.oscim.graphics.Paint.Cap; import org.oscim.graphics.Paint.Cap;
import org.oscim.layers.tile.JobQueue;
import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLayer; import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.TileLoader; import org.oscim.layers.tile.TileLoader;
@ -39,13 +38,13 @@ public class TestTileLayer extends TileLayer<TestTileLoader> {
} }
@Override @Override
protected TestTileLoader createLoader(JobQueue q, TileManager tm) { protected TestTileLoader createLoader(TileManager tm) {
return new TestTileLoader(q, tm); return new TestTileLoader(tm);
} }
static class TestTileLoader extends TileLoader { static class TestTileLoader extends TileLoader {
public TestTileLoader(JobQueue jobQueue, TileManager tileManager) { public TestTileLoader(TileManager tileManager) {
super(jobQueue, tileManager); super(tileManager);
} }
GeometryBuffer mGeom = new GeometryBuffer(128, 16); GeometryBuffer mGeom = new GeometryBuffer(128, 16);

View File

@ -29,7 +29,6 @@ import org.oscim.database.MapDatabaseFactory;
import org.oscim.database.MapDatabases; import org.oscim.database.MapDatabases;
import org.oscim.database.MapInfo; import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.layers.tile.JobQueue;
import org.oscim.layers.tile.TileLayer; import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.TileManager; import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.GLRenderer; import org.oscim.renderer.GLRenderer;
@ -51,8 +50,8 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
} }
@Override @Override
protected MapTileLoader createLoader(JobQueue q, TileManager tm) { protected MapTileLoader createLoader(TileManager tm) {
return new MapTileLoader(q, tm); return new MapTileLoader(tm);
} }
private MapOptions mMapOptions; private MapOptions mMapOptions;
@ -74,7 +73,9 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
pauseLoaders(true); pauseLoaders(true);
mJobQueue.clear(); //mJobQueue.clear();
mTileManager.clearJobs();
mMapOptions = options; mMapOptions = options;
mMapDatabase = null; mMapDatabase = null;

View File

@ -26,7 +26,6 @@ import org.oscim.core.Tile;
import org.oscim.database.IMapDatabase; import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabase.QueryResult; import org.oscim.database.IMapDatabase.QueryResult;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.layers.tile.JobQueue;
import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader; import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager; import org.oscim.layers.tile.TileManager;
@ -119,8 +118,8 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDa
/** /**
*/ */
public MapTileLoader(JobQueue jobQueue, TileManager tileManager) { public MapTileLoader(TileManager tileManager) {
super(jobQueue, tileManager); super(tileManager);
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true); mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);