refactor TextRenderer, sync MapTile in Label-Thread
This commit is contained in:
parent
ec8821e557
commit
e76b0a3740
@ -28,7 +28,7 @@ public class LabelLayer extends Layer implements Map.InputListener, Map.UpdateLi
|
|||||||
static final Logger log = LoggerFactory.getLogger(LabelLayer.class);
|
static final Logger log = LoggerFactory.getLogger(LabelLayer.class);
|
||||||
private final TextRenderer mTextRenderer;
|
private final TextRenderer mTextRenderer;
|
||||||
|
|
||||||
private int multi;
|
//private int multi;
|
||||||
|
|
||||||
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
|
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
|
||||||
super(map);
|
super(map);
|
||||||
@ -49,19 +49,19 @@ public class LabelLayer extends Layer implements Map.InputListener, Map.UpdateLi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMotionEvent(MotionEvent e) {
|
public void onMotionEvent(MotionEvent e) {
|
||||||
int action = e.getAction() & MotionEvent.ACTION_MASK;
|
// int action = e.getAction() & MotionEvent.ACTION_MASK;
|
||||||
if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
// if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||||
multi++;
|
// multi++;
|
||||||
mTextRenderer.hold(true);
|
// mTextRenderer.hold(true);
|
||||||
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
// } else if (action == MotionEvent.ACTION_POINTER_UP) {
|
||||||
multi--;
|
// multi--;
|
||||||
if (multi == 0)
|
// if (multi == 0)
|
||||||
mTextRenderer.hold(false);
|
// mTextRenderer.hold(false);
|
||||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
// } else if (action == MotionEvent.ACTION_CANCEL) {
|
||||||
multi = 0;
|
// multi = 0;
|
||||||
log.debug("cancel " + multi);
|
// log.debug("cancel " + multi);
|
||||||
mTextRenderer.hold(false);
|
// mTextRenderer.hold(false);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import org.oscim.tiling.TileRenderer;
|
|||||||
import org.oscim.tiling.TileSet;
|
import org.oscim.tiling.TileSet;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.OBB2D;
|
import org.oscim.utils.OBB2D;
|
||||||
|
import org.oscim.utils.async.ContinuousTask;
|
||||||
import org.oscim.utils.pool.Pool;
|
import org.oscim.utils.pool.Pool;
|
||||||
|
|
||||||
class TextRenderer extends ElementRenderer {
|
class TextRenderer extends ElementRenderer {
|
||||||
@ -143,6 +144,8 @@ class TextRenderer extends ElementRenderer {
|
|||||||
|
|
||||||
//mActiveTiles = new HashMap<MapTile, LabelTile>();
|
//mActiveTiles = new HashMap<MapTile, LabelTile>();
|
||||||
mRelabelCnt = 0;
|
mRelabelCnt = 0;
|
||||||
|
|
||||||
|
mLabelTask = new LabelTask(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove Label l from mLabels and return l.next
|
// remove Label l from mLabels and return l.next
|
||||||
@ -274,6 +277,108 @@ class TextRenderer extends ElementRenderer {
|
|||||||
return dx;
|
return dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Label updateWayLabels(MapTile t, Label l, float dx, float dy, double scale,
|
||||||
|
ElementLayers dbg) {
|
||||||
|
|
||||||
|
for (TextItem ti = t.labels; ti != null; ti = ti.next) {
|
||||||
|
if (ti.text.caption)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// acquire a TextItem to add to TextLayer
|
||||||
|
if (l == null)
|
||||||
|
l = getLabel();
|
||||||
|
|
||||||
|
// check if path at current scale is long enough for text
|
||||||
|
if (dbg == null && ti.width > ti.length * scale)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
l.clone(ti);
|
||||||
|
l.move(ti, dx, dy, (float) scale);
|
||||||
|
|
||||||
|
// set line endpoints relative to view to be able to
|
||||||
|
// check intersections with label from other tiles
|
||||||
|
float w = (ti.x2 - ti.x1) / 2f;
|
||||||
|
float h = (ti.y2 - ti.y1) / 2f;
|
||||||
|
l.bbox = null;
|
||||||
|
l.x1 = l.x - w;
|
||||||
|
l.y1 = l.y - h;
|
||||||
|
l.x2 = l.x + w;
|
||||||
|
l.y2 = l.y + h;
|
||||||
|
|
||||||
|
if (!wayIsVisible(l))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
byte overlaps = -1;
|
||||||
|
|
||||||
|
if (l.bbox == null)
|
||||||
|
l.bbox = new OBB2D(l.x, l.y, l.x1, l.y1,
|
||||||
|
l.width + MIN_WAY_DIST,
|
||||||
|
l.text.fontHeight + MIN_WAY_DIST);
|
||||||
|
else
|
||||||
|
l.bbox.set(l.x, l.y, l.x1, l.y1,
|
||||||
|
l.width + MIN_WAY_DIST,
|
||||||
|
l.text.fontHeight + MIN_WAY_DIST);
|
||||||
|
|
||||||
|
if (dbg == null || ti.width < ti.length * scale)
|
||||||
|
overlaps = checkOverlap(l);
|
||||||
|
|
||||||
|
if (dbg != null)
|
||||||
|
Debug.addDebugBox(dbg, l, ti, overlaps, false, (float) scale);
|
||||||
|
|
||||||
|
if (overlaps == 0) {
|
||||||
|
addLabel(l);
|
||||||
|
l.item = TextItem.copy(ti);
|
||||||
|
l.tile = t;
|
||||||
|
l.active = mRelabelCnt;
|
||||||
|
l = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Label updateNodeLabels(MapTile t, Label l, float dx, float dy, double scale, float cos,
|
||||||
|
float sin) {
|
||||||
|
O: for (TextItem ti = t.labels; ti != null; ti = ti.next) {
|
||||||
|
if (!ti.text.caption)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// acquire a TextItem to add to TextLayer
|
||||||
|
if (l == null)
|
||||||
|
l = getLabel();
|
||||||
|
|
||||||
|
l.clone(ti);
|
||||||
|
l.move(ti, dx, dy, (float) scale);
|
||||||
|
if (!nodeIsVisible(l))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (l.bbox == null)
|
||||||
|
l.bbox = new OBB2D();
|
||||||
|
|
||||||
|
l.bbox.setNormalized(l.x, l.y, cos, -sin,
|
||||||
|
l.width + MIN_CAPTION_DIST,
|
||||||
|
l.text.fontHeight + MIN_CAPTION_DIST,
|
||||||
|
l.text.dy);
|
||||||
|
|
||||||
|
for (Label lp = mLabels; lp != null;) {
|
||||||
|
if (l.bbox.overlaps(lp.bbox)) {
|
||||||
|
if (l.text.priority < lp.text.priority) {
|
||||||
|
lp = removeLabel(lp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
continue O;
|
||||||
|
}
|
||||||
|
lp = (Label) lp.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
addLabel(l);
|
||||||
|
l.item = TextItem.copy(ti);
|
||||||
|
l.tile = t;
|
||||||
|
l.active = mRelabelCnt;
|
||||||
|
l = null;
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
boolean updateLabels() {
|
boolean updateLabels() {
|
||||||
// nextLayer is not loaded yet
|
// nextLayer is not loaded yet
|
||||||
if (mNextLayer.ready)
|
if (mNextLayer.ready)
|
||||||
@ -400,118 +505,30 @@ class TextRenderer extends ElementRenderer {
|
|||||||
/* add way labels */
|
/* add way labels */
|
||||||
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
if (!t.state(MapTile.STATE_READY))
|
synchronized (t) {
|
||||||
continue;
|
if (!t.state(MapTile.STATE_READY))
|
||||||
|
|
||||||
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
|
||||||
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
|
||||||
dx = flipLongitude(dx, maxx);
|
|
||||||
|
|
||||||
for (TextItem ti = t.labels; ti != null; ti = ti.next) {
|
|
||||||
|
|
||||||
if (ti.text.caption)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// acquire a TextItem to add to TextLayer
|
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||||
if (l == null)
|
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
||||||
l = getLabel();
|
dx = flipLongitude(dx, maxx);
|
||||||
|
|
||||||
// check if path at current scale is long enough for text
|
l = updateWayLabels(t, l, dx, dy, scale, dbg);
|
||||||
if (dbg == null && ti.width > ti.length * scale)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
l.clone(ti);
|
|
||||||
l.move(ti, dx, dy, (float) scale);
|
|
||||||
|
|
||||||
// set line endpoints relative to view to be able to
|
|
||||||
// check intersections with label from other tiles
|
|
||||||
float w = (ti.x2 - ti.x1) / 2f;
|
|
||||||
float h = (ti.y2 - ti.y1) / 2f;
|
|
||||||
l.bbox = null;
|
|
||||||
l.x1 = l.x - w;
|
|
||||||
l.y1 = l.y - h;
|
|
||||||
l.x2 = l.x + w;
|
|
||||||
l.y2 = l.y + h;
|
|
||||||
|
|
||||||
if (!wayIsVisible(l))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
byte overlaps = -1;
|
|
||||||
|
|
||||||
if (l.bbox == null)
|
|
||||||
l.bbox = new OBB2D(l.x, l.y, l.x1, l.y1,
|
|
||||||
l.width + MIN_WAY_DIST,
|
|
||||||
l.text.fontHeight + MIN_WAY_DIST);
|
|
||||||
else
|
|
||||||
l.bbox.set(l.x, l.y, l.x1, l.y1,
|
|
||||||
l.width + MIN_WAY_DIST,
|
|
||||||
l.text.fontHeight + MIN_WAY_DIST);
|
|
||||||
|
|
||||||
if (dbg == null || ti.width < ti.length * scale)
|
|
||||||
overlaps = checkOverlap(l);
|
|
||||||
|
|
||||||
if (dbg != null)
|
|
||||||
Debug.addDebugBox(dbg, l, ti, overlaps, false, (float) scale);
|
|
||||||
|
|
||||||
if (overlaps == 0) {
|
|
||||||
addLabel(l);
|
|
||||||
l.item = TextItem.copy(ti);
|
|
||||||
l.tile = t;
|
|
||||||
l.active = mRelabelCnt;
|
|
||||||
l = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add caption */
|
/* add caption */
|
||||||
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
if (!t.state(MapTile.STATE_READY))
|
synchronized (t) {
|
||||||
continue;
|
if (!t.state(MapTile.STATE_READY))
|
||||||
|
|
||||||
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
|
||||||
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
|
||||||
dx = flipLongitude(dx, maxx);
|
|
||||||
|
|
||||||
O: for (TextItem ti = t.labels; ti != null; ti = ti.next) {
|
|
||||||
if (!ti.text.caption)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// acquire a TextItem to add to TextLayer
|
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||||
if (l == null)
|
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
||||||
l = getLabel();
|
dx = flipLongitude(dx, maxx);
|
||||||
|
|
||||||
l.clone(ti);
|
l = updateNodeLabels(t, l, dx, dy, scale, cos, sin);
|
||||||
l.move(ti, dx, dy, (float) scale);
|
|
||||||
if (!nodeIsVisible(l))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//l.setAxisAlignedBBox();
|
|
||||||
|
|
||||||
if (l.bbox == null)
|
|
||||||
l.bbox = new OBB2D();
|
|
||||||
|
|
||||||
l.bbox.setNormalized(l.x, l.y, cos, -sin,
|
|
||||||
l.width + MIN_CAPTION_DIST,
|
|
||||||
l.text.fontHeight + MIN_CAPTION_DIST,
|
|
||||||
l.text.dy);
|
|
||||||
|
|
||||||
for (Label lp = mLabels; lp != null;) {
|
|
||||||
if (l.bbox.overlaps(lp.bbox)) {
|
|
||||||
if (l.text.priority < lp.text.priority) {
|
|
||||||
lp = removeLabel(lp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
continue O;
|
|
||||||
}
|
|
||||||
lp = (Label) lp.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
addLabel(l);
|
|
||||||
l.item = TextItem.copy(ti);
|
|
||||||
l.tile = t;
|
|
||||||
l.active = mRelabelCnt;
|
|
||||||
l = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,25 +558,27 @@ class TextRenderer extends ElementRenderer {
|
|||||||
|
|
||||||
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
if (!t.state(MapTile.STATE_READY))
|
synchronized (t) {
|
||||||
continue;
|
if (!t.state(MapTile.STATE_READY))
|
||||||
|
|
||||||
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
|
||||||
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
|
||||||
dx = flipLongitude(dx, maxx);
|
|
||||||
|
|
||||||
for (SymbolItem ti = t.symbols; ti != null; ti = ti.next) {
|
|
||||||
if (ti.texRegion == null)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SymbolItem s = SymbolItem.pool.get();
|
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||||
|
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
||||||
|
dx = flipLongitude(dx, maxx);
|
||||||
|
|
||||||
s.texRegion = ti.texRegion;
|
for (SymbolItem ti = t.symbols; ti != null; ti = ti.next) {
|
||||||
s.x = (float) ((dx + ti.x) * scale);
|
if (ti.texRegion == null)
|
||||||
s.y = (float) ((dy + ti.y) * scale);
|
continue;
|
||||||
s.billboard = true;
|
|
||||||
|
|
||||||
sl.addSymbol(s);
|
SymbolItem s = SymbolItem.pool.get();
|
||||||
|
|
||||||
|
s.texRegion = ti.texRegion;
|
||||||
|
s.x = (float) ((dx + ti.x) * scale);
|
||||||
|
s.y = (float) ((dy + ti.y) * scale);
|
||||||
|
s.billboard = true;
|
||||||
|
|
||||||
|
sl.addSymbol(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,11 +607,6 @@ class TextRenderer extends ElementRenderer {
|
|||||||
public synchronized void update(MapPosition pos, boolean changed,
|
public synchronized void update(MapPosition pos, boolean changed,
|
||||||
Matrices matrices) {
|
Matrices matrices) {
|
||||||
|
|
||||||
//if (System.currentTimeMillis() - lastDraw > 1000){
|
|
||||||
// updateLabels();
|
|
||||||
// lastDraw = System.currentTimeMillis();
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
if (mNextLayer.ready) {
|
if (mNextLayer.ready) {
|
||||||
// exchange current with next layers
|
// exchange current with next layers
|
||||||
TextureLayers tmp = mCurLayer;
|
TextureLayers tmp = mCurLayer;
|
||||||
@ -615,127 +629,68 @@ class TextRenderer extends ElementRenderer {
|
|||||||
compile();
|
compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRequestClear)
|
mLabelTask.submit((mLastRun + MAX_RELABEL_DELAY) - System.currentTimeMillis());
|
||||||
cleanup();
|
|
||||||
|
|
||||||
//if (!mHolding)
|
|
||||||
postLabelTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* private */LabelTask mLabelTask;
|
|
||||||
/* private */long mLastRun;
|
|
||||||
/* private */boolean mRequestRun;
|
|
||||||
/* private */boolean mRequestClear;
|
|
||||||
/* private */boolean mRelabel;
|
|
||||||
|
|
||||||
class LabelTask implements Runnable {
|
|
||||||
private boolean isCancelled;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
boolean labelsChanged = false;
|
|
||||||
if (isCancelled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
//log.debug("relabel after " + (now - mLastRun));
|
|
||||||
mLastRun = now;
|
|
||||||
|
|
||||||
labelsChanged = updateLabels();
|
|
||||||
|
|
||||||
if (!isCancelled && labelsChanged)
|
|
||||||
mMap.render();
|
|
||||||
|
|
||||||
mLabelTask = null;
|
|
||||||
mRequestRun = false;
|
|
||||||
isCancelled = false;
|
|
||||||
|
|
||||||
if (mRelabel) {
|
|
||||||
mRelabel = false;
|
|
||||||
postLabelTask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancel() {
|
|
||||||
isCancelled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* private */void cleanup() {
|
|
||||||
mLabels = (Label) mPool.releaseAll(mLabels);
|
|
||||||
mTileSet.releaseTiles();
|
|
||||||
mLabelTask = null;
|
|
||||||
mRequestClear = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Runnable mLabelUpdate = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mLabelTask == null) {
|
|
||||||
mLabelTask = new LabelTask();
|
|
||||||
mMap.addTask(mLabelTask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* private */void postLabelTask() {
|
|
||||||
synchronized (mLabelUpdate) {
|
|
||||||
if (mRequestRun) {
|
|
||||||
mRelabel = true;
|
|
||||||
} else {
|
|
||||||
mRequestRun = true;
|
|
||||||
long delay = (mLastRun + MAX_RELABEL_DELAY) - System.currentTimeMillis();
|
|
||||||
//log.debug("relabel in: " + delay);
|
|
||||||
mMap.postDelayed(mLabelUpdate, Math.max(delay, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void render(MapPosition pos, Matrices m) {
|
public synchronized void render(MapPosition pos, Matrices m) {
|
||||||
|
|
||||||
layers.vbo.bind();
|
|
||||||
GLState.test(false, false);
|
GLState.test(false, false);
|
||||||
|
|
||||||
float scale = (float) (mMapPosition.scale / pos.scale);
|
float scale = (float) (mMapPosition.scale / pos.scale);
|
||||||
|
|
||||||
setMatrix(pos, m, true);
|
setMatrix(pos, m, true);
|
||||||
|
|
||||||
if (layers.baseLayers != null) {
|
synchronized (layers) {
|
||||||
for (RenderElement l = layers.baseLayers; l != null;) {
|
layers.vbo.bind();
|
||||||
if (l.type == RenderElement.POLYGON) {
|
if (layers.baseLayers != null) {
|
||||||
l = PolygonLayer.Renderer.draw(pos, l, m, true, 1, false);
|
for (RenderElement l = layers.baseLayers; l != null;) {
|
||||||
} else {
|
if (l.type == RenderElement.POLYGON) {
|
||||||
float div = scale * (float) (pos.scale / (1 << pos.zoomLevel));
|
l = PolygonLayer.Renderer.draw(pos, l, m, true, 1, false);
|
||||||
l = LineLayer.Renderer.draw(layers, l, pos, m, div, 0);
|
} else {
|
||||||
|
float div = scale * (float) (pos.scale / (1 << pos.zoomLevel));
|
||||||
|
l = LineLayer.Renderer.draw(layers, l, pos, m, div, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setMatrix(pos, m, false);
|
||||||
|
|
||||||
|
for (RenderElement l = layers.textureLayers; l != null;)
|
||||||
|
l = TextureLayer.Renderer.draw(l, scale, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
setMatrix(pos, m, false);
|
|
||||||
|
|
||||||
for (RenderElement l = layers.textureLayers; l != null;)
|
|
||||||
l = TextureLayer.Renderer.draw(l, scale, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//private boolean mHolding;
|
final class LabelTask extends ContinuousTask {
|
||||||
|
|
||||||
/**
|
public LabelTask(Map map) {
|
||||||
* @param enable layer updates
|
super(map, 10);
|
||||||
*/
|
}
|
||||||
public synchronized void hold(boolean enable) {
|
|
||||||
// mHolding = enable;
|
@Override
|
||||||
// if (!enable)
|
public void doWork() {
|
||||||
// runLabelTask();
|
|
||||||
|
if (updateLabels())
|
||||||
|
mMap.render();
|
||||||
|
|
||||||
|
mLastRun = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() {
|
||||||
|
clearLabelsInternal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void clearLabels() {
|
private final LabelTask mLabelTask;
|
||||||
if (mRequestRun) {
|
|
||||||
mRequestClear = true;
|
/* private */long mLastRun;
|
||||||
//mRelabel = true;
|
|
||||||
} else {
|
/* private */void clearLabelsInternal() {
|
||||||
cleanup();
|
mLabels = (Label) mPool.releaseAll(mLabels);
|
||||||
//postLabelTask();
|
mTileSet.releaseTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearLabels() {
|
||||||
|
mLabelTask.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
91
vtm/src/org/oscim/utils/async/ContinuousTask.java
Normal file
91
vtm/src/org/oscim/utils/async/ContinuousTask.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package org.oscim.utils.async;
|
||||||
|
|
||||||
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
|
public abstract class ContinuousTask implements Runnable {
|
||||||
|
private final Map mMap;
|
||||||
|
|
||||||
|
protected boolean mRunning;
|
||||||
|
protected boolean mWait;
|
||||||
|
protected boolean mCancel;
|
||||||
|
protected boolean mDelayed;
|
||||||
|
|
||||||
|
protected long mMinDelay;
|
||||||
|
|
||||||
|
public ContinuousTask(Map map, long minDelay) {
|
||||||
|
mMap = map;
|
||||||
|
mMinDelay = minDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
//System.out.println("run " + mRunning + " "
|
||||||
|
// + mCancel + " " + mDelayed + " " + mWait);
|
||||||
|
|
||||||
|
if (mCancel) {
|
||||||
|
mCancel = false;
|
||||||
|
mRunning = false;
|
||||||
|
mDelayed = false;
|
||||||
|
mWait = false;
|
||||||
|
cleanup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mDelayed) {
|
||||||
|
// entered on main-loop
|
||||||
|
mDelayed = false;
|
||||||
|
mWait = false;
|
||||||
|
// unset running temporarily
|
||||||
|
mRunning = false;
|
||||||
|
submit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doWork();
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
mRunning = false;
|
||||||
|
|
||||||
|
if (mCancel)
|
||||||
|
cleanup();
|
||||||
|
else if (mWait)
|
||||||
|
submit(mMinDelay);
|
||||||
|
|
||||||
|
mCancel = false;
|
||||||
|
mWait = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void doWork();
|
||||||
|
|
||||||
|
public abstract void cleanup();
|
||||||
|
|
||||||
|
public synchronized void submit(long delay) {
|
||||||
|
//System.out.println("submit " + mRunning + " " + mCancel + " " + delay);
|
||||||
|
|
||||||
|
if (mRunning) {
|
||||||
|
mWait = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mRunning = true;
|
||||||
|
if (delay <= 0) {
|
||||||
|
mMap.addTask(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDelayed = true;
|
||||||
|
mMap.postDelayed(this, delay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void cancel() {
|
||||||
|
if (mRunning) {
|
||||||
|
mCancel = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user