Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for timing steps and pipelines #613

Merged
merged 43 commits into from
Oct 31, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
3470404
Add support for timing steps and pipelines
SamCarlberg Jul 7, 2016
72a02ee
Suppress PMD warnings
SamCarlberg Jul 7, 2016
0a9302c
Add documentation to StepStarted and StepFinishedEvents
SamCarlberg Jul 7, 2016
bbf2379
Add analysis of step timings
SamCarlberg Jul 9, 2016
14911e5
Updated UI test
SamCarlberg Jul 9, 2016
0a53a78
Add benchmarking to analysis window
SamCarlberg Jul 9, 2016
b71d79a
Undo accidental formatting
SamCarlberg Jul 9, 2016
493560f
Fix and suppress issues from Codacy
SamCarlberg Jul 10, 2016
eed8a26
Add tests for Timer
SamCarlberg Jul 10, 2016
0d8a8a8
Improve UI and increase tolerance for timer tests
SamCarlberg Jul 11, 2016
849ad71
Increase timer test tolerance to 5ms (5%)
SamCarlberg Jul 11, 2016
b0dca11
Add tests for BenchmarkRunner
SamCarlberg Jul 11, 2016
ca33126
Change analysis averager to a moving average, improve naming and docu…
SamCarlberg Jul 12, 2016
7b8d888
Fix flickering, make Analysis immutable
SamCarlberg Jul 12, 2016
f84ae37
Reset timers after running a benchmark.
SamCarlberg Jul 12, 2016
16f3a38
Add tests for MovingAverage
SamCarlberg Jul 13, 2016
c79f8c3
Update TimerTest for reset()
SamCarlberg Jul 13, 2016
764cba8
Fix tests (oops)
SamCarlberg Jul 13, 2016
23260d2
Freeze sources while benchmarking
SamCarlberg Jul 13, 2016
9ab9953
Improve Timer API, documentation, and tests
SamCarlberg Jul 13, 2016
ba91b1c
Fix accidental formatting (again)
SamCarlberg Jul 13, 2016
39880c0
Merge branch 'master' into feat/timing
SamCarlberg Jul 15, 2016
a1ddd49
Remove redundant (ms)
SamCarlberg Jul 15, 2016
9ca431b
Fix PMD issues
SamCarlberg Jul 15, 2016
5d2dce9
Fix PMD in UI
SamCarlberg Jul 16, 2016
7265ddf
Appease Codacy
SamCarlberg Jul 18, 2016
2239269
Merge branch 'master' into feat/timing
SamCarlberg Jul 28, 2016
9be25db
Don't make analysis window block main window. Disable inputs and outp…
SamCarlberg Jul 28, 2016
b2db03d
Remove hacky data aggregation from Analysis class.
SamCarlberg Aug 4, 2016
785ff04
Replace custom FixedSizeQueue with guava's EvictingQueue
SamCarlberg Aug 4, 2016
8b7218d
Add option to export results to CSV.
SamCarlberg Aug 30, 2016
5e525ca
Merge branch master into feat/timing
SamCarlberg Aug 30, 2016
a513c84
Fix tests
SamCarlberg Aug 30, 2016
9dd68f4
Add tests for metrics
SamCarlberg Aug 31, 2016
b2f9d4e
Move CSV to it's own class
SamCarlberg Oct 4, 2016
a0aaaeb
Merge master
SamCarlberg Oct 4, 2016
6e06b3b
Fix some checkstyle stuff I missed
SamCarlberg Oct 4, 2016
7c3b79d
Rename Timer.stopped() to stop()
SamCarlberg Oct 6, 2016
3d9f2b6
Delete redudant Analysis class and improve variable names in Statistics
SamCarlberg Oct 11, 2016
b01b2b5
Improve Javadoc for statistics hotness function
SamCarlberg Oct 11, 2016
b61da85
Fix import order
SamCarlberg Oct 11, 2016
0c3b769
Merge remote-tracking branch 'refs/remotes/WPIRoboicsProjects/master'
SamCarlberg Oct 24, 2016
3d7481c
Move analysis window to fx:include
SamCarlberg Oct 24, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion core/src/main/java/edu/wpi/grip/core/PipelineRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import edu.wpi.grip.core.events.RunPipelineEvent;
import edu.wpi.grip.core.events.RunStartedEvent;
import edu.wpi.grip.core.events.RunStoppedEvent;
import edu.wpi.grip.core.events.StepFinishedEvent;
import edu.wpi.grip.core.events.StepStartedEvent;
import edu.wpi.grip.core.events.StopPipelineEvent;
import edu.wpi.grip.core.util.SinglePermitSemaphore;
import edu.wpi.grip.core.util.service.AutoRestartingService;
Expand Down Expand Up @@ -47,6 +49,7 @@ public class PipelineRunner implements RestartableService {
private final Supplier<ImmutableList<Step>> stepSupplier;
private final AutoRestartingService pipelineService;

private final EventBus eventBus;

@Inject
PipelineRunner(EventBus eventBus, Provider<Pipeline> pipelineProvider) {
Expand All @@ -56,6 +59,7 @@ public class PipelineRunner implements RestartableService {

PipelineRunner(EventBus eventBus, Supplier<ImmutableList<Source>> sourceSupplier,
Supplier<ImmutableList<Step>> stepSupplier) {
this.eventBus = checkNotNull(eventBus, "eventBus");
this.sourceSupplier = sourceSupplier;
this.stepSupplier = stepSupplier;
this.pipelineService = new AutoRestartingService<>(
Expand All @@ -79,10 +83,10 @@ protected void runOneIteration() throws InterruptedException {
}
runPipeline(super::isRunning);
// This should not block access to the steps array
eventBus.post(new RunStoppedEvent());
if (super.isRunning()) {
eventBus.post(new RenderEvent());
}
eventBus.post(new RunStoppedEvent());
}

@Override
Expand Down Expand Up @@ -195,7 +199,9 @@ private void runPipeline(Supplier<Boolean> isRunning) {
if (!isRunning.get()) {
break;
}
eventBus.post(new StepStartedEvent(step));
step.runPerformIfPossible();
eventBus.post(new StepFinishedEvent(step));
}
}

Expand Down
22 changes: 22 additions & 0 deletions core/src/main/java/edu/wpi/grip/core/events/StepFinishedEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package edu.wpi.grip.core.events;

import edu.wpi.grip.core.Step;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* An event fired when a step has finished running.
*/
public class StepFinishedEvent {

private final Step step;

public StepFinishedEvent(Step step) {
this.step = checkNotNull(step, "step");
}

public boolean isRegarding(Step step) {
return this.step.equals(step);
}

}
23 changes: 23 additions & 0 deletions core/src/main/java/edu/wpi/grip/core/events/StepStartedEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package edu.wpi.grip.core.events;

import edu.wpi.grip.core.Step;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* An event fired when a step has started to be run. This will be accompanied by a
* {@link StepFinishedEvent} after the step has finished running.
*/
public class StepStartedEvent {

private final Step step;

public StepStartedEvent(Step step) {
this.step = checkNotNull(step, "step");
}

public boolean isRegarding(Step step) {
return this.step.equals(step);
}

}
35 changes: 34 additions & 1 deletion ui/src/main/java/edu/wpi/grip/ui/MainWindowController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import edu.wpi.grip.core.Pipeline;
import edu.wpi.grip.core.PipelineRunner;
import edu.wpi.grip.core.events.ProjectSettingsChangedEvent;
import edu.wpi.grip.core.events.RunStartedEvent;
import edu.wpi.grip.core.events.RunStoppedEvent;
import edu.wpi.grip.core.serialization.Project;
import edu.wpi.grip.core.settings.ProjectSettings;
import edu.wpi.grip.core.settings.SettingsProvider;
Expand All @@ -13,26 +15,31 @@
import edu.wpi.grip.ui.util.DPIUtility;

import com.google.common.base.CaseFormat;
import com.google.common.base.Stopwatch;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.google.common.util.concurrent.Service;

import org.controlsfx.control.StatusBar;

import java.io.File;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.text.TextAlignment;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Stage;
Expand All @@ -59,6 +66,7 @@ public class MainWindowController {
private Pane aboutPane;
@FXML
private StatusBar statusBar;
private Label elapsedTimeLabel; // TODO improve the layout of this label
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This label isn't centered vertically in the status bar, and it separates the start/stop button from the "Pipeline STATE" text.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move the Pipeline status into its own label and then center both (i.e. do not use statusBar.setText() for the status)

@Inject
private EventBus eventBus;
@Inject
Expand All @@ -76,10 +84,16 @@ public class MainWindowController {

private Stage aboutDialogStage;

private final Stopwatch stopwatch = Stopwatch.createUnstarted();

@FXML
protected void initialize() {
elapsedTimeLabel = new Label();
updateElapsedTimeLabel(0);
elapsedTimeLabel.setTextAlignment(TextAlignment.CENTER);
pipelineView.prefHeightProperty().bind(bottomPane.heightProperty());
statusBar.getLeftItems().add(startStoppableButtonFactory.create(pipelineRunner));
statusBar.getLeftItems().add(elapsedTimeLabel);
pipelineRunner.addListener(new SingleActionListener(() -> {
final Service.State state = pipelineRunner.state();
final String stateMessage =
Expand All @@ -89,7 +103,6 @@ protected void initialize() {
.toString());
statusBar.setText(" Pipeline " + stateMessage);
}), Platform::runLater);

}

/**
Expand Down Expand Up @@ -261,4 +274,24 @@ protected void deploy() {
dialog.setResizable(true);
dialog.showAndWait();
}

@Subscribe
private void runStarted(RunStartedEvent event) {
stopwatch.reset().start();
}

@Subscribe
private void runStopped(RunStoppedEvent event) {
// Compute elapsed time first because another run
// may start before updateElapsedTimeLabel gets called
final long elapsed = stopwatch.elapsed(TimeUnit.MICROSECONDS);
Platform.runLater(() -> updateElapsedTimeLabel(elapsed));
}

private void updateElapsedTimeLabel(long elapsed) {
elapsedTimeLabel.setText(
String.format("Ran in %.1f ms (%.1f fps)",
elapsed / 1e3,
elapsed != 0 ? (1e6 / elapsed) : Double.NaN));
}
}
29 changes: 29 additions & 0 deletions ui/src/main/java/edu/wpi/grip/ui/pipeline/StepController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import edu.wpi.grip.core.Pipeline;
import edu.wpi.grip.core.Step;
import edu.wpi.grip.core.events.StepFinishedEvent;
import edu.wpi.grip.core.events.StepStartedEvent;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import edu.wpi.grip.ui.Controller;
Expand All @@ -13,13 +15,18 @@
import edu.wpi.grip.ui.util.ControllerMap;
import edu.wpi.grip.ui.util.StyleClassNameUtility;

import com.google.common.base.Stopwatch;
import com.google.common.eventbus.Subscribe;
import com.google.inject.assistedinject.Assisted;

import java.io.InputStream;
import java.util.Collection;
import java.util.concurrent.TimeUnit;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Labeled;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
Expand All @@ -46,6 +53,8 @@ public class StepController implements Controller {
@FXML
private Labeled title;
@FXML
private Label elapsedTime;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can fix it in the fxml with padding

@FXML
private ImageView icon;
@FXML
private HBox buttons;
Expand All @@ -56,6 +65,8 @@ public class StepController implements Controller {
private ControllerMap<InputSocketController, Node> inputSocketMapManager;
private ControllerMap<OutputSocketController, Node> outputSocketMapManager;

private final Stopwatch stopwatch = Stopwatch.createUnstarted();

@Inject
StepController(Pipeline pipeline,
InputSocketControllerFactory inputSocketControllerFactory,
Expand Down Expand Up @@ -142,6 +153,24 @@ private void moveStepRight() {
pipeline.moveStep(step, +1);
}

@Subscribe
private void started(StepStartedEvent event) {
if (!event.isRegarding(this.step)) {
return;
}
stopwatch.reset().start();
}

@Subscribe
private void finished(StepFinishedEvent event) {
if (!event.isRegarding(this.step)) {
return;
}
// Use micros and divide by 1e3 to get decimal points (e.g. 0.3ms instead of 0ms)
final long elapsed = stopwatch.elapsed(TimeUnit.MICROSECONDS);
Platform.runLater(() -> elapsedTime.setText(String.format("Ran in %.1f ms", elapsed / 1e3)));
}

/**
* Used for assisted injects. Guice will automatically create an instance of this interface so we
* can create step controllers. This lets us use injection with StepController even though it
Expand Down
27 changes: 15 additions & 12 deletions ui/src/main/resources/edu/wpi/grip/ui/pipeline/Step.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,21 @@
</HBox>
</HBox>
<Separator orientation="HORIZONTAL" />
<Label fx:id="title" maxWidth="Infinity" styleClass="title">
<graphic>
<ImageView fx:id="icon">
<fitWidth>
<DPIUtility fx:constant="SMALL_ICON_SIZE" />
</fitWidth>
<fitHeight>
<DPIUtility fx:constant="SMALL_ICON_SIZE" />
</fitHeight>
</ImageView>
</graphic>
</Label>
<VBox>
<Label fx:id="title" maxWidth="Infinity" styleClass="title">
<graphic>
<ImageView fx:id="icon">
<fitWidth>
<DPIUtility fx:constant="SMALL_ICON_SIZE" />
</fitWidth>
<fitHeight>
<DPIUtility fx:constant="SMALL_ICON_SIZE" />
</fitHeight>
</ImageView>
</graphic>
</Label>
<Label fx:id="elapsedTime" maxWidth="Infinity" />
</VBox>
<Separator orientation="HORIZONTAL" />
<VBox fx:id="inputs" styleClass="sockets" />
<Separator orientation="HORIZONTAL" />
Expand Down