From bfb86e0a57fbb75b3fcb1bf362b99e0b130f66de Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Fri, 17 Jan 2014 15:09:50 +0100 Subject: [PATCH] use arrays for listeners (avoid allocating iterators) --- vtm/src/org/oscim/map/Layers.java | 23 +++----- vtm/src/org/oscim/map/Map.java | 90 +++++++++++++++++-------------- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/vtm/src/org/oscim/map/Layers.java b/vtm/src/org/oscim/map/Layers.java index 5722eb5f..18db4742 100644 --- a/vtm/src/org/oscim/map/Layers.java +++ b/vtm/src/org/oscim/map/Layers.java @@ -58,8 +58,8 @@ public final class Layers extends AbstractList { if (layer instanceof UpdateListener) mMap.bind((UpdateListener) layer); - //if (layer instanceof InputListener) - // mMap.bind((InputListener) layer); + if (layer instanceof InputListener) + mMap.bind((InputListener) layer); mLayerList.add(index, layer); mDirtyLayers = true; @@ -73,8 +73,8 @@ public final class Layers extends AbstractList { if (remove instanceof UpdateListener) mMap.unbind((UpdateListener) remove); - //if (remove instanceof InputListener) - // mMap.unbind((InputListener) remove); + if (remove instanceof InputListener) + mMap.unbind((InputListener) remove); return remove; } @@ -90,8 +90,8 @@ public final class Layers extends AbstractList { // unbind replaced layer if (remove instanceof UpdateListener) mMap.unbind((UpdateListener) remove); - //if (remove instanceof InputListener) - // mMap.unbind((InputListener) remove); + if (remove instanceof InputListener) + mMap.unbind((InputListener) remove); return remove; } @@ -114,8 +114,6 @@ public final class Layers extends AbstractList { for (Layer o : mLayers) o.onDetach(); - - // TODO need to clear lists here? } boolean handleGesture(Gesture g, MotionEvent e) { @@ -130,15 +128,6 @@ public final class Layers extends AbstractList { return false; } - void handleMotionEvent(MotionEvent e) { - if (mDirtyLayers) - updateLayers(); - - for (Layer o : mLayers) - if (o instanceof InputListener) - ((InputListener) o).onMotionEvent(e); - } - private synchronized void updateLayers() { mLayers = new Layer[mLayerList.size()]; int numRenderLayers = 0; diff --git a/vtm/src/org/oscim/map/Map.java b/vtm/src/org/oscim/map/Map.java index e5896548..a50f8850 100644 --- a/vtm/src/org/oscim/map/Map.java +++ b/vtm/src/org/oscim/map/Map.java @@ -74,11 +74,13 @@ public abstract class Map { private VectorTileLayer mBaseLayer; - private Set mInputListeners = new LinkedHashSet(); - private Set mUpdateListeners = new LinkedHashSet(); + private Set mInputListenerSet = new LinkedHashSet(); + private InputListener[] mInputListeners; + + private Set mUpdateListenerSet = new LinkedHashSet(); + private UpdateListener[] mUpdateListeners; public Map() { - mViewport = new Viewport(this); mAnimator = new MapAnimator(this, mViewport); @@ -88,8 +90,6 @@ public abstract class Map { mEventLayer = new MapEventLayer(this); mLayers.add(0, mEventLayer); - - //mGestureDetector = new GestureDetector(this, mLayers); } public MapEventLayer getEventLayer() { @@ -200,22 +200,6 @@ public abstract class Map { mClearMap = true; } - /** - * This function is run on main-loop before rendering a frame. - * Caution: Do not call directly! - */ - protected void updateLayers() { - boolean changed = false; - - // get the current MapPosition - changed |= mViewport.getMapPosition(mMapPosition); - - for (UpdateListener l : mUpdateListeners) - l.onMapUpdate(mMapPosition, changed, mClearMap); - - mClearMap = false; - } - /** * Set {@link MapPosition} of {@link Viewport} and trigger a redraw. */ @@ -262,37 +246,65 @@ public abstract class Map { return mAnimator; } - /** - * Register InputListener - */ - public void bind(InputListener listener) { - mInputListeners.add(listener); - } - - /** - * Unregister InputListener - */ - public void unbind(InputListener listener) { - mInputListeners.remove(listener); - } - /** * Register UpdateListener */ public void bind(UpdateListener l) { - mUpdateListeners.add(l); + if (mUpdateListenerSet.add(l)) + mUpdateListeners = null; } /** * Unregister UpdateListener */ public void unbind(UpdateListener l) { - mUpdateListeners.remove(l); + if (mUpdateListenerSet.remove(l)) + mUpdateListeners = null; + } + + /** + * This function is run on main-loop before rendering a frame. + * Caution: Do not call directly! + */ + protected void updateLayers() { + boolean changed = false; + + // get the current MapPosition + changed |= mViewport.getMapPosition(mMapPosition); + + if (mUpdateListeners == null) { + mUpdateListeners = new UpdateListener[mUpdateListenerSet.size()]; + mUpdateListenerSet.toArray(mUpdateListeners); + } + + for (UpdateListener l : mUpdateListeners) + l.onMapUpdate(mMapPosition, changed, mClearMap); + + mClearMap = false; + } + + /** + * Register InputListener + */ + public void bind(InputListener listener) { + if (mInputListenerSet.add(listener)) + mInputListeners = null; + } + + /** + * Unregister InputListener + */ + public void unbind(InputListener listener) { + if (mInputListenerSet.remove(listener)) + mInputListeners = null; } - // TODO make protected public void handleMotionEvent(MotionEvent e) { - mLayers.handleMotionEvent(e); + + if (mInputListeners == null) { + mInputListeners = new InputListener[mInputListenerSet.size()]; + mInputListenerSet.toArray(mInputListeners); + } for (InputListener l : mInputListeners) l.onMotionEvent(e);