package de.hems.trafficsim; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.TextView; import java.util.Observable; import java.util.Observer; public class MainActivity extends AppCompatActivity implements Observer, SeekBar.OnSeekBarChangeListener { public static final int defaultNoOfVehicles = 25; public static final int defaultTrackLength = 100; 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; protected LinearLayout viewStack; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, 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); trackLengthSeekBar.setProgress(defaultTrackLength); ((TextView)(findViewById(R.id.trackLengthTextView))).setText(String.valueOf(defaultTrackLength)); SeekBar maxVelocitySeekBar = (SeekBar) findViewById(R.id.maxVelocitySeekBar); maxVelocitySeekBar.setOnSeekBarChangeListener(this); maxVelocitySeekBar.setProgress((int)defaultMaxVelocity); ((TextView)(findViewById(R.id.maxVeloTextView))).setText(String.valueOf((int)defaultMaxVelocity)); SeekBar noOfVehiclesSeekBar = (SeekBar) findViewById(R.id.noOfVehiclesSeekBar); noOfVehiclesSeekBar.setOnSeekBarChangeListener(this); noOfVehiclesSeekBar.setProgress(defaultNoOfVehicles); ((TextView)(findViewById(R.id.noOfVehiclesTextView))).setText(String.valueOf(defaultNoOfVehicles)); SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); brakeProbabilitySeekBar.setOnSeekBarChangeListener(this); brakeProbabilitySeekBar.setProgress((int)(defaultBrakeProb*20)); ((TextView)(findViewById(R.id.brakeProbTextView))).setText(String.valueOf(defaultBrakeProb)); SeekBar delaySeekBar = (SeekBar)(findViewById(R.id.simDelaySeekBar)); delaySeekBar.setOnSeekBarChangeListener(this); delaySeekBar.setProgress(defaultDelay); this.update(this.track, null); } public static float round(float number, int digits) { float div = (float) Math.pow(10.0f, digits); return Math.round(number*div)/div; } @Override public void update(Observable observable, Object o) { final Track trackRef = this.track; final LinearLayout viewStackRef = this.viewStack; final MainActivity mainActivity = this; final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); 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); 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.getSteps())); delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2))); } }); } public void onStepButtonClick(View view) { this.track.timeElapse(); } public void onPlayButtonClick(View view) { Button playButton = (Button) findViewById(R.id.playButton); playButton.setEnabled(false); Button stepButton = (Button) findViewById(R.id.stepButton); stepButton.setEnabled(false); Button stopButton = (Button) findViewById(R.id.stopButton); stopButton.setEnabled(true); Button clearButton = (Button) findViewById(R.id.clearButton); clearButton.setEnabled(false); this.worker = new Worker(track); this.worker.start(); } public void onStopButtonClick(View view) { Button playButton = (Button) findViewById(R.id.playButton); playButton.setEnabled(true); Button stepButton = (Button) findViewById(R.id.stepButton); stepButton.setEnabled(true); Button stopButton = (Button) findViewById(R.id.stopButton); stopButton.setEnabled(false); Button clearButton = (Button) findViewById(R.id.clearButton); clearButton.setEnabled(true); this.worker.setStop(true); try { this.worker.join(); } catch (InterruptedException ex) { } this.worker = null; } protected void stopWorker() { this.worker.setStop(true); try { this.worker.join(); } catch (InterruptedException ex) { } this.worker = null; } public void onClearButtonClick(View view) { this.track.deleteObserver(this); if (this.worker != null) { // There was a simulation running this.stopWorker(); } Button playButton = (Button) findViewById(R.id.playButton); playButton.setEnabled(true); Button stepButton = (Button) findViewById(R.id.stepButton); stepButton.setEnabled(true); Button stopButton = (Button) findViewById(R.id.stopButton); stopButton.setEnabled(false); this.updateTrack(); this.update(this.track, null); } protected void updateTrack() { int newTrackLength = ((SeekBar)(findViewById(R.id.trackLengthSeekBar))).getProgress(); SeekBar noOfVehiclesSeekBar = (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar)); int newNoOfVehicles = noOfVehiclesSeekBar.getProgress(); if (newTrackLength < newNoOfVehicles) { // Dont allow values greater than track length! newNoOfVehicles = (int) newTrackLength; noOfVehiclesSeekBar.setProgress(newNoOfVehicles); } TextView noOfVehiclesTextView = (TextView)(findViewById(R.id.noOfVehiclesTextView)); noOfVehiclesTextView.setText(String.valueOf(newNoOfVehicles)); TextView trackLengthTextView = (TextView)(findViewById(R.id.trackLengthTextView)); trackLengthTextView.setText(String.valueOf(newTrackLength)); float newMaxVelocity = ((SeekBar) findViewById(R.id.maxVelocitySeekBar)).getProgress(); SeekBar brakeProbabilitySeekBar = (SeekBar) findViewById(R.id.brakeProbabilitySeekBar); float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax(); int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress(); 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(); this.worker = new Worker(track); this.worker.start(); } } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (seekBar == (SeekBar)(findViewById(R.id.noOfVehiclesSeekBar))) { this.updateTrack(); } else if (seekBar == (SeekBar)(findViewById(R.id.brakeProbabilitySeekBar))) { float newBrakeProb = (float)seekBar.getProgress() / (float)seekBar.getMax(); this.track.setBrakeProb(newBrakeProb); TextView newBrakeProbTextView = (TextView)(findViewById(R.id.brakeProbTextView)); newBrakeProbTextView.setText(String.valueOf((newBrakeProb))); } else if (seekBar == (SeekBar)(findViewById(R.id.maxVelocitySeekBar))) { this.track.setMaxVelocity(seekBar.getProgress()); TextView tv = (TextView)(findViewById(R.id.maxVeloTextView)); tv.setText(String.valueOf(progress)); } else if (seekBar == (SeekBar)(findViewById(R.id.trackLengthSeekBar))) { this.updateTrack(); } else if (seekBar == (SeekBar)(findViewById(R.id.simDelaySeekBar))) { TextView tv = (TextView)(findViewById(R.id.simDelayTextView)); tv.setText(String.valueOf(seekBar.getProgress())); this.track.setWaitTime(seekBar.getProgress()); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }