Optimize view update Add semaphore to TimeRecordList Add waiting timer to model updatetags/Release_1
@@ -18,6 +18,7 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
public static final float defaultBrakeProb = 0.3f; | |||
public static final float defaultMaxVelocity = 5.0f; | |||
public static final int defaultDelay = 0; | |||
public static final int defaultHistoryLength = 50; | |||
protected Track track; | |||
protected TimeRecordView trackView; | |||
protected Worker worker; | |||
@@ -28,9 +29,11 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.activity_main); | |||
this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, | |||
defaultMaxVelocity, defaultDelay); | |||
defaultMaxVelocity, defaultDelay, defaultHistoryLength); | |||
this.track.addObserver(this); | |||
this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | |||
this.trackView = new TimeRecordView(this, track, defaultHistoryLength); | |||
viewStack.addView(this.trackView); | |||
SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar); | |||
trackLengthSeekBar.setOnSeekBarChangeListener(this); | |||
@@ -73,18 +76,22 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView); | |||
final TextView delayedAvgView = (TextView) findViewById(R.id.delayedAvgTextView); | |||
final TextView stepsView = (TextView) findViewById(R.id.stepsTextView); | |||
final TimeRecordView view = this.trackView; | |||
runOnUiThread(new Runnable() { | |||
@Override | |||
public void run() { | |||
TimeRecordView newTrView = new TimeRecordView(mainActivity, trackRef); | |||
if (viewStackRef.getChildCount() > 0) | |||
viewStackRef.removeViewAt(0); | |||
viewStackRef.addView(newTrView); | |||
//TimeRecordView newTrView = new TimeRecordView(mainActivity, trackRef); | |||
trackView.invalidate(); | |||
//if (viewStackRef.getChildCount() > 0) | |||
// viewStackRef.removeViewAt(0); | |||
//viewStackRef.addView(newTrView); | |||
lastAvgView.setText(String.valueOf(round(trackRef.getLastAvg(), 2))); | |||
overallAvgView.setText(String.valueOf(round(trackRef.getOverallAvg(), 2))); | |||
stepsView.setText(String.valueOf(trackRef.getVtrList().size())); | |||
stepsView.setText(String.valueOf(trackRef.getSteps())); | |||
delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2))); | |||
} | |||
}); | |||
} | |||
@@ -172,7 +179,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||
int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress(); | |||
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay); | |||
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay, defaultHistoryLength); | |||
this.trackView.setTrack(this.track); | |||
this.track.addObserver(this); | |||
if (this.worker != null) { // There was a simulation running already | |||
this.stopWorker(); | |||
@@ -14,11 +14,13 @@ public class TimeRecordView extends View { | |||
protected Track track; | |||
protected int pixelPerVehicle; | |||
protected float tooShortPerTrackLength; | |||
protected int historyLength; | |||
public TimeRecordView(Context context, Track track) { | |||
public TimeRecordView(Context context, Track track, int historyLength) { | |||
super(context); | |||
this.track = track; | |||
this.paint = new Paint(); | |||
this.historyLength = historyLength; | |||
paint.setColor(Color.BLACK); | |||
paint.setStyle(Paint.Style.FILL_AND_STROKE); | |||
this.setBackgroundColor(Color.BLACK); | |||
@@ -26,6 +28,10 @@ public class TimeRecordView extends View { | |||
this.tooShortPerTrackLength = (this.getWidth() - this.pixelPerVehicle*this.track.getTrackLength())/this.track.getTrackLength(); | |||
} | |||
public void setTrack(Track track) { | |||
this.track = track; | |||
} | |||
protected int getColor(float curVelocity, float maxVelocity) { | |||
float perc = curVelocity / maxVelocity; | |||
perc = 1 - perc; | |||
@@ -60,18 +66,25 @@ public class TimeRecordView extends View { | |||
protected void onDraw(Canvas canvas) { | |||
int y = 0; | |||
List<List<VehicleTimeRecord>> stepList = this.track.getVtrList(); | |||
for (int curStepIdx = stepList.size()-1; curStepIdx >= stepList.size()-1-50 && curStepIdx >= 0; curStepIdx--) { | |||
for (int curStepIdx = this.historyLength-1; | |||
curStepIdx >= 0 && stepList.size() >= curStepIdx; | |||
curStepIdx--) { | |||
try { | |||
try { | |||
track.getListSemaphore().acquire(); | |||
} catch (InterruptedException ex) { return; } | |||
List<VehicleTimeRecord> step = stepList.get(curStepIdx); | |||
int i = 0; | |||
for (VehicleTimeRecord r : step) { | |||
int left = (int) (this.pixelPerVehicle * r.getPosition()); | |||
int compensate = Math.round(r.getPosition()*this.tooShortPerTrackLength); | |||
this.paint.setColor(getColor(r.getVelocity(), r.getMaxVelocity())); | |||
canvas.drawRect(left+compensate, y, left + this.pixelPerVehicle - 1+compensate, | |||
canvas.drawRect(left+compensate, y, | |||
left + this.pixelPerVehicle - 1+compensate, | |||
y + 10, this.paint); | |||
i++; | |||
} | |||
track.getListSemaphore().release(); | |||
y += 10; | |||
} catch (ConcurrentModificationException ex) { | |||
System.out.println("Concurrent Exception occured, skipping record"); | |||
@@ -4,6 +4,8 @@ import java.util.ArrayList; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import java.util.Observable; | |||
import java.util.concurrent.Semaphore; | |||
import java.util.concurrent.locks.LockSupport; | |||
public class Track extends Observable { | |||
protected List<Vehicle> vehicles; | |||
@@ -18,6 +20,8 @@ public class Track extends Observable { | |||
protected int waitTime; | |||
protected float maxVelocity; | |||
protected float brakeProb; | |||
protected long steps; | |||
protected Semaphore listSemaphore; | |||
public List<List<VehicleTimeRecord>> getVtrList() { return vtrList; } | |||
public float getOverallAvg() { | |||
@@ -33,8 +37,10 @@ public class Track extends Observable { | |||
public float getTrackLength() { | |||
return trackLength; | |||
} | |||
public long getSteps() { return steps; } | |||
public Semaphore getListSemaphore() { return listSemaphore; } | |||
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime) { | |||
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime, int historyLength) { | |||
this.trackLength = trackLength; | |||
this.brakeProb = brakeProb; | |||
this.maxVelocity = maxVelocity; | |||
@@ -45,8 +51,10 @@ public class Track extends Observable { | |||
this.overallAvg = 0; | |||
this.delayedAvg = 0; | |||
this.lastAvg = 0; | |||
this.historyLength = 25; | |||
this.historyLength = historyLength; | |||
this.waitTime = waitTime; | |||
this.steps = 0; | |||
this.listSemaphore = new Semaphore(1); | |||
} | |||
@@ -90,17 +98,28 @@ public class Track extends Observable { | |||
} | |||
v.updateVelocity(distanceForerunner); | |||
} | |||
try { | |||
this.listSemaphore.acquire(); | |||
} catch (InterruptedException ex) {return;} | |||
List <VehicleTimeRecord> records = new ArrayList<>(vehicles.size()); | |||
this.vtrList.add(records); | |||
if (this.vtrList.size() > this.historyLength) { | |||
this.vtrList.remove(0); | |||
} | |||
for(Vehicle v: vehicles){ | |||
v.timeElapse(); | |||
VehicleTimeRecord vtr = new VehicleTimeRecord(v.id, v.position, v.curVelocity, v.maxVelocity); | |||
records.add(vtr); | |||
} | |||
steps++; | |||
this.listSemaphore.release(); | |||
update_avg(); | |||
this.setChanged(); | |||
this.notifyObservers(); | |||
this.clearChanged(); | |||
LockSupport.parkNanos(1); | |||
try { | |||
Thread.sleep(waitTime); | |||
} catch (InterruptedException ex) { } | |||
@@ -116,12 +135,12 @@ public class Track extends Observable { | |||
protected void update_avg(){ | |||
lastAvg = avg_step(vtrList.size()-1); | |||
if (this.vtrList.size() > 10) { | |||
if (this.steps > 10) { | |||
sumDelAvgMemory += lastAvg; | |||
delayedAvg = sumDelAvgMemory / (vtrList.size() - 10); | |||
delayedAvg = sumDelAvgMemory / (this.steps - 10); | |||
} | |||
sumAvgMemory += lastAvg; | |||
overallAvg = sumAvgMemory / vtrList.size(); | |||
overallAvg = sumAvgMemory / this.steps; | |||
} | |||
@@ -46,7 +46,6 @@ public class Vehicle { | |||
curVelocity = curVelocity + 1; | |||
} | |||
if (r < brakeProb && curVelocity > 0) { | |||
System.out.println("vehicle: "+brakeProb); | |||
curVelocity = curVelocity - 1; | |||
} | |||
if (curVelocity > distanceForerunner) { | |||