some event mechanism

This commit is contained in:
Hannes Janetzek 2013-09-13 14:41:14 +02:00
parent 5389f59df0
commit 4e01de31f7
21 changed files with 405 additions and 144 deletions

View File

@ -219,7 +219,7 @@ public class MapView extends RelativeLayout {
mPausing = false;
}
AndroidMotionEvent mMotionEvent = new AndroidMotionEvent();
AndroidMotionEvent mMotionEvent = new AndroidMotionEvent(this);
@Override
public boolean onTouchEvent(android.view.MotionEvent motionEvent) {
@ -228,8 +228,9 @@ public class MapView extends RelativeLayout {
return false;
mMotionEvent.wrap(motionEvent);
mMap.handleMotionEvent(mMotionEvent);
return mMap.getLayers().handleMotionEvent(mMotionEvent);
return true;
}
// synchronized ???

View File

@ -13,10 +13,19 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.input;
import org.oscim.backend.input.MotionEvent;
import org.oscim.event.MotionEvent;
public class AndroidMotionEvent extends MotionEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public AndroidMotionEvent(Object source) {
super(source);
}
android.view.MotionEvent mEvent;
public void wrap(android.view.MotionEvent e){

View File

@ -19,6 +19,8 @@ import java.net.URL;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.event.MapEvent;
import org.oscim.event.UpdateEvent;
import org.oscim.gdx.client.GwtBitmap;
import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
@ -48,33 +50,66 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
mFade = mTileSource.getFadeSteps();
}
// @Override
// public void onUpdate(MapPosition pos, boolean changed, boolean clear) {
// super.onUpdate(pos, changed, clear);
//
// if (mFade == null) {
// mRenderLayer.setBitmapAlpha(1);
// return;
// }
//
// float alpha = 0;
// for (FadeStep f : mFade) {
// if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
// continue;
//
// if (f.alphaStart == f.alphaEnd) {
// alpha = f.alphaStart;
// break;
// }
// double range = f.scaleEnd / f.scaleStart;
// float a = (float)((range - (pos.scale / f.scaleStart)) / range);
// a = FastMath.clamp(a, 0, 1);
// // interpolate alpha between start and end
// alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
// break;
// }
//
// mRenderLayer.setBitmapAlpha(alpha);
// }
@Override
public void onUpdate(MapPosition pos, boolean changed, boolean clear) {
super.onUpdate(pos, changed, clear);
public void handleEvent(MapEvent event) {
super.handleEvent(event);
if (mFade == null) {
mRenderLayer.setBitmapAlpha(1);
return;
}
if (event instanceof UpdateEvent) {
float alpha = 0;
for (FadeStep f : mFade) {
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
continue;
if (mFade == null) {
mRenderLayer.setBitmapAlpha(1);
return;
}
MapPosition pos = mMap.getMapPosition();
if (f.alphaStart == f.alphaEnd) {
alpha = f.alphaStart;
float alpha = 0;
for (FadeStep f : mFade) {
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
continue;
if (f.alphaStart == f.alphaEnd) {
alpha = f.alphaStart;
break;
}
double range = f.scaleEnd / f.scaleStart;
float a = (float) ((range - (pos.scale / f.scaleStart)) / range);
a = FastMath.clamp(a, 0, 1);
// interpolate alpha between start and end
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
break;
}
double range = f.scaleEnd / f.scaleStart;
float a = (float)((range - (pos.scale / f.scaleStart)) / range);
a = FastMath.clamp(a, 0, 1);
// interpolate alpha between start and end
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
break;
}
mRenderLayer.setBitmapAlpha(alpha);
mRenderLayer.setBitmapAlpha(alpha);
}
}
@Override

View File

@ -1,12 +1,17 @@
package org.oscim.gdx;
import org.oscim.backend.input.MotionEvent;
import org.oscim.event.MotionEvent;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
public class GdxMotionEvent extends MotionEvent implements InputProcessor{
private static final long serialVersionUID = 1L;
public GdxMotionEvent(Object source) {
super(source);
}
@Override
public int getAction() {
return 0;

View File

@ -0,0 +1,7 @@
package org.oscim.event;
public interface EventDispatcher {
public void addListener(String type, EventListener listener);
public void removeListener(String type, EventListener listener);
}

View File

@ -0,0 +1,5 @@
package org.oscim.event;
public interface EventListener {
public void handleEvent(MapEvent event);
}

View File

@ -12,8 +12,14 @@
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.backend.input;
package org.oscim.event;
public class KeyEvent {
public class KeyEvent extends MapEvent{
private static final long serialVersionUID = 1L;
public KeyEvent(Object source) {
super(source);
}
}

View File

@ -0,0 +1,13 @@
package org.oscim.event;
import java.util.EventObject;
public class MapEvent extends EventObject {
private static final long serialVersionUID = 1L;
public MapEvent(Object source) {
super(source);
}
}

View File

@ -12,9 +12,18 @@
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.backend.input;
package org.oscim.event;
public abstract class MotionEvent {
public abstract class MotionEvent extends MapEvent {
private static final long serialVersionUID = 1L;
public static final String TYPE = "MotionEvent";
public MotionEvent(Object source) {
super(source);
}
public static final int ACTION_DOWN = 0;
public static final int ACTION_UP = 1;

View File

@ -0,0 +1,16 @@
package org.oscim.event;
public class UpdateEvent extends MapEvent {
private static final long serialVersionUID = 1L;
public static final String TYPE = "UpdateEvent";
public UpdateEvent(Object source) {
super(source);
}
public boolean positionChanged;
public boolean clearMap;
}

View File

@ -44,14 +44,14 @@ public class CustomRenderLayer extends Layer {
private int someConccurentVariable;
@Override
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
synchronized (mRenderer) {
// chang
someConccurentVariable++;
}
}
// @Override
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
//
// synchronized (mRenderer) {
// // chang
// someConccurentVariable++;
// }
//
// }
}

View File

@ -15,8 +15,8 @@
*/
package org.oscim.layers;
import org.oscim.backend.input.KeyEvent;
import org.oscim.backend.input.MotionEvent;
import org.oscim.event.KeyEvent;
import org.oscim.event.MotionEvent;
import org.oscim.map.Map;
public abstract class InputLayer extends Layer {

View File

@ -14,11 +14,12 @@
*/
package org.oscim.layers;
import org.oscim.core.MapPosition;
import org.oscim.map.Map;
import org.oscim.renderer.LayerRenderer;
public abstract class Layer {
public abstract class Layer {
public Layer(Map map) {
mMap = map;
}
@ -32,33 +33,34 @@ public abstract class Layer {
return mRenderer;
}
/**
*/
public void setEnabled(boolean enabled) {
mEnabled = enabled;
}
/**
*/
public boolean isEnabled() {
return mEnabled;
}
/**
* Called before each frame render request (on main thread).
*
* @param mapPosition
* current MapPosition
* @param changed
* true when MapPosition has changed since last call
* @param clear
* Clear all resources that depend on previous map state. Most
* importantly all resources from previous GL context (hold by
* RenderLayer)
*/
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
// /**
// * Called before each frame render request (on main thread).
// *
// * @param mapPosition
// * current MapPosition
// * @param changed
// * true when MapPosition has changed since last call
// * @param clear
// * Clear all resources that depend on previous map state. Most
// * importantly all resources from previous GL context (hold by
// * RenderLayer)
// */
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
//
// }
}
// @Override
// public void handleEvent(MapEvent e){
//
// }
/**
* Override to perform clean up of resources before shutdown. By default

View File

@ -15,8 +15,10 @@
package org.oscim.layers;
import org.oscim.backend.Log;
import org.oscim.backend.input.MotionEvent;
import org.oscim.core.Tile;
import org.oscim.event.EventListener;
import org.oscim.event.MapEvent;
import org.oscim.event.MotionEvent;
import org.oscim.map.Map;
import org.oscim.map.Viewport;
@ -30,7 +32,7 @@ import org.oscim.map.Viewport;
* http://en.wikipedia.org/wiki/Viterbi_algorithm
*/
public class MapEventLayer extends InputLayer {
public class MapEventLayer extends Layer implements EventListener {
private static final boolean debug = false;
private static final String TAG = MapEventLayer.class.getName();
@ -65,10 +67,21 @@ public class MapEventLayer extends InputLayer {
public MapEventLayer(Map map) {
super(map);
map.addListener(MotionEvent.TYPE, this);
mMapPosition = map.getViewport();
mTracker = new VelocityTracker();
}
@Override
public void onDetach() {
mMap.removeListener(MotionEvent.TYPE, this);
}
@Override
public void handleEvent(MapEvent event){
if (event instanceof MotionEvent)
onTouchEvent((MotionEvent)event);
}
//private long mPrevTime;
private boolean mEnableRotation = true;
@ -96,7 +109,7 @@ public class MapEventLayer extends InputLayer {
mEnableZoom = enable;
}
@Override
//@Override
public boolean onTouchEvent(MotionEvent e) {
//mPrevTime = e.getTime();
@ -441,5 +454,4 @@ public class MapEventLayer extends InputLayer {
// return sum;
//}
}
}

View File

@ -17,9 +17,9 @@ package org.oscim.layers.marker;
import java.util.List;
import org.oscim.backend.input.MotionEvent;
import org.oscim.core.BoundingBox;
import org.oscim.core.Point;
import org.oscim.event.MotionEvent;
import org.oscim.map.Map;
import org.oscim.map.Viewport;

View File

@ -16,14 +16,16 @@ package org.oscim.layers.tile;
import java.util.ArrayList;
import org.oscim.core.MapPosition;
import org.oscim.event.EventListener;
import org.oscim.event.MapEvent;
import org.oscim.event.UpdateEvent;
import org.oscim.layers.Layer;
import org.oscim.map.Map;
import org.oscim.tiling.TileLoader;
import org.oscim.tiling.TileManager;
import org.oscim.tiling.TileRenderer;
public abstract class TileLayer<T extends TileLoader> extends Layer {
public abstract class TileLayer<T extends TileLoader> extends Layer implements EventListener {
//private final static String TAG = TileLayer.class.getName();
private final static int MAX_ZOOMLEVEL = 17;
private final static int MIN_ZOOMLEVEL = 2;
@ -59,6 +61,8 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
// RenderLayer is working in GL Thread and actually
// drawing loaded tiles to screen.
mRenderer = mRenderLayer = new TileRenderer(mTileManager);
map.addListener(UpdateEvent.TYPE, this);
}
abstract protected T createLoader(TileManager tm);
@ -67,22 +71,44 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
return (TileRenderer) mRenderer;
}
// @Override
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
//
// if (clear || mInitial) {
// mRenderLayer.clearTiles();
// mTileManager.init(mInitial);
// mInitial = false;
// changed = true;
// }
//
// if (changed && mTileManager.update(mapPosition))
// notifyLoaders();
// }
@Override
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
public void handleEvent(MapEvent event) {
if (event instanceof UpdateEvent) {
if (clear || mInitial) {
mRenderLayer.clearTiles();
mTileManager.init(mInitial);
mInitial = false;
changed = true;
UpdateEvent e = (UpdateEvent) event;
boolean changed = e.positionChanged;
if (e.clearMap || mInitial) {
mRenderLayer.clearTiles();
mTileManager.init(mInitial);
mInitial = false;
changed = true;
}
if (changed && mTileManager.update(mMap.getMapPosition()))
notifyLoaders();
}
if (changed && mTileManager.update(mapPosition))
notifyLoaders();
}
@Override
public void onDetach() {
mMap.removeListener(UpdateEvent.TYPE, this);
for (T loader : mTileLoader) {
loader.pause();
loader.interrupt();

View File

@ -24,6 +24,8 @@ import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.event.MapEvent;
import org.oscim.event.UpdateEvent;
import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
import org.oscim.map.Map;
@ -35,7 +37,7 @@ import org.oscim.tiling.TileManager;
import org.oscim.utils.FastMath;
public class BitmapTileLayer extends TileLayer<TileLoader> {
public class BitmapTileLayer extends TileLayer<TileLoader> {
private static final int TIMEOUT_CONNECT = 5000;
private static final int TIMEOUT_READ = 10000;
protected static final String TAG = BitmapTileLayer.class.getName();
@ -50,33 +52,67 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
}
// @Override
// public void onUpdate(MapPosition pos, boolean changed, boolean clear) {
// super.onUpdate(pos, changed, clear);
//
// if (mFade == null) {
// mRenderLayer.setBitmapAlpha(1);
// return;
// }
//
// float alpha = 0;
// for (FadeStep f : mFade) {
// if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
// continue;
//
// if (f.alphaStart == f.alphaEnd) {
// alpha = f.alphaStart;
// break;
// }
// double range = f.scaleEnd / f.scaleStart;
// float a = (float)((range - (pos.scale / f.scaleStart)) / range);
// a = FastMath.clamp(a, 0, 1);
// // interpolate alpha between start and end
// alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
// break;
// }
//
// mRenderLayer.setBitmapAlpha(alpha);
// }
@Override
public void onUpdate(MapPosition pos, boolean changed, boolean clear) {
super.onUpdate(pos, changed, clear);
public void handleEvent(MapEvent event) {
super.handleEvent(event);
if (mFade == null) {
mRenderLayer.setBitmapAlpha(1);
return;
}
if (event instanceof UpdateEvent){
float alpha = 0;
for (FadeStep f : mFade) {
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
continue;
if (mFade == null) {
mRenderLayer.setBitmapAlpha(1);
return;
}
MapPosition pos = mMap.getMapPosition();
if (f.alphaStart == f.alphaEnd) {
alpha = f.alphaStart;
float alpha = 0;
for (FadeStep f : mFade) {
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
continue;
if (f.alphaStart == f.alphaEnd) {
alpha = f.alphaStart;
break;
}
double range = f.scaleEnd / f.scaleStart;
float a = (float)((range - (pos.scale / f.scaleStart)) / range);
a = FastMath.clamp(a, 0, 1);
// interpolate alpha between start and end
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
break;
}
double range = f.scaleEnd / f.scaleStart;
float a = (float)((range - (pos.scale / f.scaleStart)) / range);
a = FastMath.clamp(a, 0, 1);
// interpolate alpha between start and end
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
break;
}
mRenderLayer.setBitmapAlpha(alpha);
mRenderLayer.setBitmapAlpha(alpha);
}
}
@Override

View File

@ -14,8 +14,8 @@
*/
package org.oscim.layers.tile.vector;
import org.oscim.backend.input.MotionEvent;
import org.oscim.core.MapPosition;
import org.oscim.event.MotionEvent;
import org.oscim.layers.InputLayer;
import org.oscim.map.Map;
import org.oscim.renderer.ExtrusionRenderer;

View File

@ -14,54 +14,90 @@
*/
package org.oscim.layers.tile.vector.labeling;
import org.oscim.backend.input.MotionEvent;
import org.oscim.core.MapPosition;
import org.oscim.layers.InputLayer;
import org.oscim.backend.Log;
import org.oscim.event.EventListener;
import org.oscim.event.MapEvent;
import org.oscim.event.MotionEvent;
import org.oscim.event.UpdateEvent;
import org.oscim.layers.Layer;
import org.oscim.map.Map;
import org.oscim.tiling.TileRenderer;
import org.oscim.backend.Log;
public class LabelLayer extends InputLayer {
public class LabelLayer extends Layer implements EventListener {
private final static String TAG = LabelLayer.class.getName();
final TextRenderer mTextRenderer;
private final TextRenderer mTextRenderer;
private int multi;
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
super(map);
map.addListener(UpdateEvent.TYPE, this);
map.addListener(MotionEvent.TYPE, this);
//mTextLayer = new org.oscim.renderer.layers.TextRenderLayer(map, tileRenderLayer);
mTextRenderer = new TextRenderer(map, tileRenderLayer);
mRenderer = mTextRenderer;
}
@Override
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
if (clear)
mTextRenderer.clearLabels();
}
private int multi;
@Override
public boolean onTouchEvent(MotionEvent e) {
int action = e.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_POINTER_DOWN) {
multi++;
mTextRenderer.hold(true);
} else if (action == MotionEvent.ACTION_POINTER_UP) {
multi--;
if (multi == 0)
mTextRenderer.hold(false);
} else if (action == MotionEvent.ACTION_CANCEL) {
multi = 0;
Log.d(TAG, "cancel " + multi);
mTextRenderer.hold(false);
}
return false;
}
@Override
public void onDetach() {
mMap.removeListener(UpdateEvent.TYPE, this);
mMap.removeListener(MotionEvent.TYPE, this);
// TODO stop and clear labeling thread
super.onDetach();
}
@Override
public void handleEvent(MapEvent event) {
if (event instanceof UpdateEvent) {
UpdateEvent e = (UpdateEvent) event;
if (e.clearMap)
mTextRenderer.clearLabels();
} else if (event instanceof MotionEvent) {
MotionEvent e = (MotionEvent) event;
int action = e.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_POINTER_DOWN) {
multi++;
mTextRenderer.hold(true);
} else if (action == MotionEvent.ACTION_POINTER_UP) {
multi--;
if (multi == 0)
mTextRenderer.hold(false);
} else if (action == MotionEvent.ACTION_CANCEL) {
multi = 0;
Log.d(TAG, "cancel " + multi);
mTextRenderer.hold(false);
}
}
}
// @Override
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
// if (clear)
// mTextRenderer.clearLabels();
// }
// @Override
// public boolean onTouchEvent(MotionEvent e) {
// int action = e.getAction() & MotionEvent.ACTION_MASK;
// if (action == MotionEvent.ACTION_POINTER_DOWN) {
// multi++;
// mTextRenderer.hold(true);
// } else if (action == MotionEvent.ACTION_POINTER_UP) {
// multi--;
// if (multi == 0)
// mTextRenderer.hold(false);
// } else if (action == MotionEvent.ACTION_CANCEL) {
// multi = 0;
// Log.d(TAG, "cancel " + multi);
// mTextRenderer.hold(false);
// }
//
// return false;
// }
}

View File

@ -20,9 +20,9 @@ import java.util.AbstractList;
import java.util.concurrent.CopyOnWriteArrayList;
import org.oscim.backend.Log;
import org.oscim.backend.input.KeyEvent;
import org.oscim.backend.input.MotionEvent;
import org.oscim.core.MapPosition;
import org.oscim.event.KeyEvent;
import org.oscim.event.MotionEvent;
import org.oscim.layers.InputLayer;
import org.oscim.layers.Layer;
import org.oscim.renderer.LayerRenderer;
@ -74,14 +74,14 @@ public class Layers extends AbstractList<Layer> {
return mLayerRenderer;
}
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
if (mDirtyLayers)
updateLayers();
for (Layer l : mLayers)
l.onUpdate(mapPosition, changed, clear);
}
//
// public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
// if (mDirtyLayers)
// updateLayers();
//
// for (Layer l : mLayers)
// l.onUpdate(mapPosition, changed, clear);
// }
public void destroy() {
if (mDirtyLayers)

View File

@ -14,10 +14,16 @@
*/
package org.oscim.map;
import java.util.ArrayList;
import org.oscim.backend.Log;
import org.oscim.core.BoundingBox;
import org.oscim.core.GeoPoint;
import org.oscim.core.MapPosition;
import org.oscim.event.EventDispatcher;
import org.oscim.event.EventListener;
import org.oscim.event.MotionEvent;
import org.oscim.event.UpdateEvent;
import org.oscim.layers.MapEventLayer;
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.layers.tile.vector.VectorTileLayer;
@ -29,7 +35,7 @@ import org.oscim.theme.ThemeLoader;
import org.oscim.tiling.source.TileSource;
import org.oscim.utils.async.AsyncExecutor;
public abstract class Map {
public abstract class Map implements EventDispatcher {
private static final String TAG = Map.class.getName();
@ -172,7 +178,15 @@ public abstract class Map {
// get the current MapPosition
changed |= mViewport.getMapPosition(mMapPosition);
mLayers.onUpdate(mMapPosition, changed, mClearMap);
//mLayers.onUpdate(mMapPosition, changed, mClearMap);
UpdateEvent e = new UpdateEvent(this);
e.clearMap = mClearMap;
e.positionChanged = changed;
for (EventListener l : mUpdateListeners)
l.handleEvent(e);
mClearMap = false;
}
@ -223,4 +237,33 @@ public abstract class Map {
public MapAnimator getAnimator() {
return mAnimator;
}
ArrayList<EventListener> mUpdateListeners = new ArrayList<EventListener>();
ArrayList<EventListener> mMotionListeners = new ArrayList<EventListener>();
@Override
public void addListener(String type, EventListener listener) {
if (type == UpdateEvent.TYPE)
mUpdateListeners.add(listener);
else if (type == MotionEvent.TYPE)
mMotionListeners.add(listener);
}
@Override
public void removeListener(String type, EventListener listener) {
if (type == UpdateEvent.TYPE)
mUpdateListeners.remove(listener);
else if (type == MotionEvent.TYPE)
mMotionListeners.remove(listener);
}
public MapPosition getMapPosition() {
return mMapPosition;
}
public void handleMotionEvent(MotionEvent e) {
for (EventListener l : mMotionListeners)
l.handleEvent(e);
}
}