Eliminate allocs - Move and Zoom Job Pools (#1892)

Create object pools for the Zoom, move, and animation jobs.  Their constructors remain public, to make this easier to roll back from if needed.
This commit is contained in:
Tony Patino 2016-06-30 15:33:02 -07:00
parent 5a18d0ef22
commit 38fbefe66b
7 changed files with 187 additions and 11 deletions

View file

@ -9,7 +9,6 @@ import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
@ -664,7 +663,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
*/
public void zoomAndCenter(float scaleX, float scaleY, float xValue, float yValue, AxisDependency axis) {
Runnable job = new ZoomJob(mViewPortHandler, scaleX, scaleY, xValue, yValue, getTransformer(axis), axis, this);
Runnable job = ZoomJob.getInstance(mViewPortHandler, scaleX, scaleY, xValue, yValue, getTransformer(axis), axis, this);
addViewportJob(job);
}
@ -686,7 +685,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
PointD origin = getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), axis);
Runnable job = new AnimatedZoomJob(mViewPortHandler, this, getTransformer(axis), getAxis(axis), mXAxis
Runnable job = AnimatedZoomJob.getInstance(mViewPortHandler, this, getTransformer(axis), getAxis(axis), mXAxis
.mAxisRange, scaleX, scaleY, mViewPortHandler.getScaleX(), mViewPortHandler.getScaleY(),
xValue, yValue, (float) origin.x, (float) origin.y, duration);
addViewportJob(job);
@ -800,6 +799,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
mViewPortHandler.setMinMaxScaleY(minScale, maxScale);
}
/**
* Moves the left side of the current viewport to the specified x-position.
* This also refreshes the chart by calling invalidate().
@ -808,7 +808,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
*/
public void moveViewToX(float xValue) {
Runnable job = new MoveViewJob(mViewPortHandler, xValue, 0f,
Runnable job = MoveViewJob.getInstance(mViewPortHandler, xValue, 0f,
getTransformer(AxisDependency.LEFT), this);
addViewportJob(job);
@ -827,7 +827,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
float yInView = getDeltaY(axis) / mViewPortHandler.getScaleY();
Runnable job = new MoveViewJob(mViewPortHandler, xValue, yValue + yInView / 2f,
Runnable job = MoveViewJob.getInstance(mViewPortHandler, xValue, yValue + yInView / 2f,
getTransformer(axis), this);
addViewportJob(job);
@ -852,7 +852,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
float yInView = getDeltaY(axis) / mViewPortHandler.getScaleY();
Runnable job = new AnimatedMoveViewJob(mViewPortHandler, xValue, yValue + yInView / 2f,
Runnable job = AnimatedMoveViewJob.getInstance(mViewPortHandler, xValue, yValue + yInView / 2f,
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);
addViewportJob(job);
@ -874,7 +874,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
float valsInView = getDeltaY(axis) / mViewPortHandler.getScaleY();
Runnable job = new MoveViewJob(mViewPortHandler, 0f, yValue + valsInView / 2f,
Runnable job = MoveViewJob.getInstance(mViewPortHandler, 0f, yValue + valsInView / 2f,
getTransformer(axis), this);
addViewportJob(job);
@ -894,7 +894,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
float yInView = getDeltaY(axis) / mViewPortHandler.getScaleY();
float xInView = getXAxis().mAxisRange / mViewPortHandler.getScaleX();
Runnable job = new MoveViewJob(mViewPortHandler,
Runnable job = MoveViewJob.getInstance(mViewPortHandler,
xValue - xInView / 2f, yValue + yInView / 2f,
getTransformer(axis), this);
@ -920,7 +920,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
float yInView = getDeltaY(axis) / mViewPortHandler.getScaleY();
float xInView = getXAxis().mAxisRange / mViewPortHandler.getScaleX();
Runnable job = new AnimatedMoveViewJob(mViewPortHandler,
Runnable job = AnimatedMoveViewJob.getInstance(mViewPortHandler,
xValue - xInView / 2f, yValue + yInView / 2f,
getTransformer(axis), this, (float) bounds.x, (float) bounds.y, duration);

View file

@ -5,14 +5,42 @@ import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.view.View;
import com.github.mikephil.charting.utils.ObjectPool;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
/**
* Created by Philipp Jahoda on 19/02/16.
*/
@SuppressLint("NewApi")
public class AnimatedMoveViewJob extends AnimatedViewPortJob {
private static ObjectPool<AnimatedMoveViewJob> pool;
static {
pool = ObjectPool.create(4, new AnimatedMoveViewJob(null,0,0,null,null,0,0,0));
pool.setReplenishPercentage(0.5f);
}
public static AnimatedMoveViewJob getInstance(ViewPortHandler viewPortHandler, float xValue, float yValue, Transformer trans, View v, float xOrigin, float yOrigin, long duration){
AnimatedMoveViewJob result = pool.get();
result.mViewPortHandler = viewPortHandler;
result.xValue = xValue;
result.yValue = yValue;
result.mTrans = trans;
result.view = v;
result.xOrigin = xOrigin;
result.yOrigin = yOrigin;
result.resetAnimator();
result.animator.setDuration(duration);
return result;
}
public static void recycleInstance(AnimatedMoveViewJob instance){
pool.recycle(instance);
}
public AnimatedMoveViewJob(ViewPortHandler viewPortHandler, float xValue, float yValue, Transformer trans, View v, float xOrigin, float yOrigin, long duration) {
super(viewPortHandler, xValue, yValue, trans, v, xOrigin, yOrigin, duration);
}
@ -26,4 +54,13 @@ public class AnimatedMoveViewJob extends AnimatedViewPortJob {
mTrans.pointValuesToPixel(pts);
mViewPortHandler.centerViewPort(pts, view);
}
public void recycleSelf(){
recycleInstance(this);
}
@Override
protected ObjectPool.Poolable instantiate() {
return new AnimatedMoveViewJob(null,0,0,null,null,0,0,0);
}
}

View file

@ -1,5 +1,6 @@
package com.github.mikephil.charting.jobs;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
@ -12,7 +13,7 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
* Created by Philipp Jahoda on 19/02/16.
*/
@SuppressLint("NewApi")
public abstract class AnimatedViewPortJob extends ViewPortJob implements ValueAnimator.AnimatorUpdateListener {
public abstract class AnimatedViewPortJob extends ViewPortJob implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
protected ObjectAnimator animator;
@ -28,6 +29,7 @@ public abstract class AnimatedViewPortJob extends ViewPortJob implements ValueAn
animator = ObjectAnimator.ofFloat(this, "phase", 0f, 1f);
animator.setDuration(duration);
animator.addUpdateListener(this);
animator.addListener(this);
}
@SuppressLint("NewApi")
@ -51,4 +53,47 @@ public abstract class AnimatedViewPortJob extends ViewPortJob implements ValueAn
public float getYOrigin() {
return yOrigin;
}
public abstract void recycleSelf();
protected void resetAnimator(){
animator.removeAllListeners();
animator.removeAllUpdateListeners();
animator.reverse();
animator.addUpdateListener(this);
animator.addListener(this);
}
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
try{
recycleSelf();
}catch (IllegalArgumentException e){
// don't worry about it.
}
}
@Override
public void onAnimationCancel(Animator animation) {
try{
recycleSelf();
}catch (IllegalArgumentException e){
// don't worry about it.
}
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
}
}

View file

@ -8,6 +8,7 @@ import android.view.View;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.utils.ObjectPool;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
@ -17,6 +18,26 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
@SuppressLint("NewApi")
public class AnimatedZoomJob extends AnimatedViewPortJob implements Animator.AnimatorListener {
private static ObjectPool<AnimatedZoomJob> pool;
static {
pool = ObjectPool.create(8, new AnimatedZoomJob(null,null,null,null,0,0,0,0,0,0,0,0,0,0));
}
public static AnimatedZoomJob getInstance(ViewPortHandler viewPortHandler, View v, Transformer trans, YAxis axis, float xAxisRange, float scaleX, float scaleY, float xOrigin, float yOrigin, float zoomCenterX, float zoomCenterY, float zoomOriginX, float zoomOriginY, long duration) {
AnimatedZoomJob result = pool.get();
result.mViewPortHandler = viewPortHandler;
result.xValue = scaleX;
result.yValue = scaleY;
result.mTrans = trans;
result.view = v;
result.xOrigin = xOrigin;
result.yOrigin = yOrigin;
result.resetAnimator();
result.animator.setDuration(duration);
return result;
}
protected float zoomOriginX;
protected float zoomOriginY;
@ -79,8 +100,18 @@ public class AnimatedZoomJob extends AnimatedViewPortJob implements Animator.Ani
}
@Override
public void recycleSelf() {
}
@Override
public void onAnimationStart(Animator animation) {
}
@Override
protected ObjectPool.Poolable instantiate() {
return new AnimatedZoomJob(null,null,null,null,0,0,0,0,0,0,0,0,0,0);
}
}

View file

@ -3,6 +3,7 @@ package com.github.mikephil.charting.jobs;
import android.view.View;
import com.github.mikephil.charting.utils.ObjectPool;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
@ -11,6 +12,27 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
*/
public class MoveViewJob extends ViewPortJob {
private static ObjectPool<MoveViewJob> pool;
static {
pool = ObjectPool.create(2, new MoveViewJob(null,0,0,null,null));
pool.setReplenishPercentage(0.5f);
}
public static MoveViewJob getInstance(ViewPortHandler viewPortHandler, float xValue, float yValue, Transformer trans, View v){
MoveViewJob result = pool.get();
result.mViewPortHandler = viewPortHandler;
result.xValue = xValue;
result.yValue = yValue;
result.mTrans = trans;
result.view = v;
return result;
}
public static void recycleInstance(MoveViewJob instance){
pool.recycle(instance);
}
public MoveViewJob(ViewPortHandler viewPortHandler, float xValue, float yValue, Transformer trans, View v) {
super(viewPortHandler, xValue, yValue, trans, v);
}
@ -23,5 +45,12 @@ public class MoveViewJob extends ViewPortJob {
mTrans.pointValuesToPixel(pts);
mViewPortHandler.centerViewPort(pts, view);
this.recycleInstance(this);
}
@Override
protected ObjectPool.Poolable instantiate() {
return new MoveViewJob(mViewPortHandler, xValue, yValue, mTrans, view);
}
}

View file

@ -3,6 +3,7 @@ package com.github.mikephil.charting.jobs;
import android.view.View;
import com.github.mikephil.charting.utils.ObjectPool;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
@ -15,7 +16,7 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
*
* @author Philipp Jahoda
*/
public abstract class ViewPortJob implements Runnable {
public abstract class ViewPortJob extends ObjectPool.Poolable implements Runnable {
protected float[] pts = new float[2];
@ -33,6 +34,7 @@ public abstract class ViewPortJob implements Runnable {
this.yValue = yValue;
this.mTrans = trans;
this.view = v;
}
public float getXValue() {

View file

@ -6,6 +6,7 @@ import android.view.View;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.utils.ObjectPool;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
@ -14,6 +15,30 @@ import com.github.mikephil.charting.utils.ViewPortHandler;
*/
public class ZoomJob extends ViewPortJob {
private static ObjectPool<ZoomJob> pool;
static {
pool = ObjectPool.create(1, new ZoomJob(null,0,0,0,0,null,null,null));
pool.setReplenishPercentage(0.5f);
}
public static ZoomJob getInstance(ViewPortHandler viewPortHandler, float scaleX, float scaleY, float xValue, float yValue, Transformer trans, YAxis.AxisDependency axis, View v) {
ZoomJob result = pool.get();
result.xValue = xValue;
result.yValue = yValue;
result.scaleX = scaleX;
result.scaleY = scaleY;
result.mViewPortHandler = viewPortHandler;
result.mTrans = trans;
result.axisDependency = axis;
result.view = v;
return result;
}
public static void recycleInstance(ZoomJob instance){
pool.recycle(instance);
}
protected float scaleX;
protected float scaleY;
@ -48,5 +73,12 @@ public class ZoomJob extends ViewPortJob {
((BarLineChartBase) view).calculateOffsets();
view.postInvalidate();
recycleInstance(this);
}
@Override
protected ObjectPool.Poolable instantiate() {
return new ZoomJob(null,0,0,0,0,null,null,null);
}
}