DepthTimeCanvas.java
Go to the documentation of this file.00001 package edu.rice.cs.hpc.traceviewer.depth;
00002
00003 import java.util.concurrent.ExecutorService;
00004 import java.util.concurrent.Executors;
00005
00006 import org.eclipse.core.commands.ExecutionException;
00007 import org.eclipse.core.commands.operations.IOperationHistoryListener;
00008 import org.eclipse.core.commands.operations.IUndoableOperation;
00009 import org.eclipse.core.commands.operations.OperationHistoryEvent;
00010 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
00011 import org.eclipse.core.runtime.jobs.IJobChangeListener;
00012 import org.eclipse.swt.SWT;
00013 import org.eclipse.swt.events.DisposeEvent;
00014 import org.eclipse.swt.events.DisposeListener;
00015 import org.eclipse.swt.events.PaintEvent;
00016 import org.eclipse.swt.graphics.GC;
00017 import org.eclipse.swt.graphics.Image;
00018 import org.eclipse.swt.graphics.Point;
00019 import org.eclipse.swt.graphics.Rectangle;
00020 import org.eclipse.swt.widgets.Composite;
00021 import edu.rice.cs.hpc.common.ui.Util;
00022 import edu.rice.cs.hpc.traceviewer.operation.BufferRefreshOperation;
00023 import edu.rice.cs.hpc.traceviewer.operation.PositionOperation;
00024 import edu.rice.cs.hpc.traceviewer.operation.TraceOperation;
00025 import edu.rice.cs.hpc.traceviewer.operation.ZoomOperation;
00026 import edu.rice.cs.hpc.traceviewer.painter.AbstractTimeCanvas;
00027 import edu.rice.cs.hpc.traceviewer.painter.BaseViewPaint;
00028 import edu.rice.cs.hpc.traceviewer.painter.ISpaceTimeCanvas;
00029 import edu.rice.cs.hpc.traceviewer.painter.ImageTraceAttributes;
00030 import edu.rice.cs.hpc.traceviewer.spaceTimeData.Frame;
00031 import edu.rice.cs.hpc.traceviewer.spaceTimeData.Position;
00032 import edu.rice.cs.hpc.traceviewer.spaceTimeData.SpaceTimeDataController;
00033 import edu.rice.cs.hpc.traceviewer.util.Utility;
00034 import edu.rice.cs.hpc.traceviewer.data.util.Constants;
00035 import edu.rice.cs.hpc.traceviewer.data.util.Debugger;
00036
00038 public class DepthTimeCanvas extends AbstractTimeCanvas
00039 implements IOperationHistoryListener, ISpaceTimeCanvas
00040 {
00041 final private ExecutorService threadExecutor;
00042
00043 private SpaceTimeDataController stData;
00044 private int currentProcess = Integer.MIN_VALUE;
00045 private boolean needToRedraw = false;
00046
00047
00048
00049
00050
00051
00052 public DepthTimeCanvas(Composite composite)
00053 {
00054 super(composite, SWT.NONE);
00055
00056 threadExecutor = Executors.newFixedThreadPool( Utility.getNumThreads(0) );
00057 addDisposeListener( new DisposeListener() {
00058
00059 @Override
00060 public void widgetDisposed(DisposeEvent e) {
00061 dispose();
00062 }
00063 });
00064 }
00065
00066
00067
00068
00069
00070 public void updateView(SpaceTimeDataController stData)
00071 {
00072 super.init();
00073 setVisible(true);
00074
00075 if (this.stData == null) {
00076
00077 TraceOperation.getOperationHistory().addOperationHistoryListener(this);
00078 }
00079 this.stData = stData;
00080 }
00081
00082
00083
00084
00085
00086 public void paintControl(PaintEvent event)
00087 {
00088 if (this.stData == null)
00089 return;
00090
00091 if (needToRedraw) {
00092 refreshWithCondition();
00093
00094
00095 needToRedraw = false;
00096 }
00097 super.paintControl(event);
00098
00099 final long topLeftPixelX = Math.round(stData.getAttributes().getTimeBegin()*getScalePixelsPerTime());
00100 final int viewHeight = getClientArea().height;
00101
00102
00103
00104
00105
00106 event.gc.setBackground(Constants.COLOR_WHITE);
00107 event.gc.setAlpha(240);
00108
00109 long selectedTime = stData.getAttributes().getFrame().position.time;
00110
00111 int topPixelCrossHairX = (int)(Math.round(selectedTime*getScalePixelsPerTime())-2-topLeftPixelX);
00112 event.gc.fillRectangle(topPixelCrossHairX,0,4,viewHeight);
00113
00114 final int maxDepth = stData.getMaxDepth();
00115 final int depth = stData.getAttributes().getDepth();
00116
00117 final int width = depth*viewHeight/maxDepth+viewHeight/(2*maxDepth);
00118 event.gc.fillRectangle(topPixelCrossHairX-8,width-1,20,4);
00119 }
00120
00121
00122
00123
00124
00125 public void refresh()
00126 {
00127 rebuffer();
00128 }
00129
00130 public void activate(boolean isActivated)
00131 {
00132 this.needToRedraw = isActivated;
00133 }
00134
00135
00136
00137
00138 private void refreshWithCondition()
00139 {
00140 if (imageBuffer == null) {
00141 if (stData != null) {
00142 rebuffer();
00143 }
00144 return;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154 final Rectangle r1 = imageBuffer.getBounds();
00155 final Rectangle r2 = getClientArea();
00156
00157 if (!(r1.height == r2.height && r1.width == r2.width))
00158 {
00159
00160 rebuffer();
00161 }
00162 }
00163
00164
00165 public double getScalePixelsPerTime()
00166 {
00167 final int viewWidth = getClientArea().width;
00168
00169 return (double)viewWidth / (double)getNumTimeDisplayed();
00170 }
00171
00172 public double getScalePixelsPerRank() {
00173 final Rectangle r = this.getClientArea();
00174 return Math.max(r.height/(double)stData.getMaxDepth(), 1);
00175 }
00176
00177
00178
00179
00180
00181
00182 private long getNumTimeDisplayed()
00183 {
00184 return (stData.getAttributes().getTimeInterval());
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 private void rebuffer()
00194 {
00195 if (stData == null || !isVisible())
00196 return;
00197
00198 final ImageTraceAttributes attributes = stData.getAttributes();
00199 final Frame frame = attributes.getFrame();
00200
00201
00202
00203 currentProcess = frame.position.process;
00204
00205 final Rectangle rb = getBounds();
00206
00207 final int viewWidth = rb.width;
00208 final int viewHeight = rb.height;
00209
00210 if (viewWidth>0 && viewHeight>0) {
00211 if (imageBuffer != null) {
00212 imageBuffer.dispose();
00213 }
00214
00215 imageBuffer = new Image(getDisplay(), viewWidth, viewHeight);
00216 } else {
00217
00218 return;
00219 }
00220 final GC bufferGC = new GC(imageBuffer);
00221 bufferGC.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
00222 bufferGC.fillRectangle(0,0,viewWidth,viewHeight);
00223
00224 attributes.numPixelsDepthV = viewHeight;
00225
00226 Debugger.printDebug(1, "DTC rebuffering " + attributes);
00227
00228 BaseViewPaint depthPaint = new DepthViewPaint(Util.getActiveWindow(), bufferGC,
00229 stData, attributes, true, this, threadExecutor);
00230
00231 depthPaint.setUser(true);
00232 depthPaint.addJobChangeListener(new DepthJobListener(bufferGC));
00233 depthPaint.schedule();
00234 }
00235
00236
00237
00238
00239
00240 public void dispose()
00241 {
00242 threadExecutor.shutdown();
00243 super.dispose();
00244 }
00245
00246
00247 @Override
00248
00249
00250
00251
00252 public void historyNotification(final OperationHistoryEvent event) {
00253
00254 if (event.getEventType() == OperationHistoryEvent.DONE)
00255 {
00256 final IUndoableOperation operation = event.getOperation();
00257
00258 if (operation.hasContext(BufferRefreshOperation.context)) {
00259
00260
00261 super.init();
00262 rebuffer();
00263
00264 } else if (operation.hasContext(PositionOperation.context)) {
00265 PositionOperation opPos = (PositionOperation) operation;
00266 Position position = opPos.getPosition();
00267 if (position.process == currentProcess)
00268 {
00269
00270 redraw();
00271 } else {
00272
00273 rebuffer();
00274 }
00275 }
00276 }
00277 }
00278
00279 @Override
00280 protected void changePosition(Point point) {
00281 long closeTime = stData.getAttributes().getTimeBegin() + (long)(point.x / getScalePixelsPerTime());
00282
00283 Position currentPosition = stData.getAttributes().getPosition();
00284 Position newPosition = new Position(closeTime, currentPosition.process);
00285
00286 try {
00287 TraceOperation.getOperationHistory().execute(
00288 new PositionOperation(newPosition),
00289 null, null);
00290 } catch (ExecutionException e) {
00291 e.printStackTrace();
00292 }
00293
00294 }
00295
00296 @Override
00297 protected void changeRegion(Rectangle region)
00298 {
00299 final ImageTraceAttributes attributes = stData.getAttributes();
00300
00301 long topLeftTime = attributes.getTimeBegin() + (long)(region.x / getScalePixelsPerTime());
00302 long bottomRightTime = attributes.getTimeBegin() + (long)((region.width+region.x) / getScalePixelsPerTime());
00303
00304 final Frame oldFrame = attributes.getFrame();
00305 final Position position = oldFrame.position;
00306
00307 Frame frame = new Frame(topLeftTime, bottomRightTime,
00308 attributes.getProcessBegin(), attributes.getProcessEnd(),
00309 attributes.getDepth(), position.time, position.process);
00310 try {
00311 TraceOperation.getOperationHistory().execute(
00312 new ZoomOperation("Time zoom out", frame),
00313 null, null);
00314 } catch (ExecutionException e) {
00315 e.printStackTrace();
00316 }
00317 }
00318
00319 private class DepthJobListener implements IJobChangeListener
00320 {
00321 final private GC bufferGC;
00322
00323 public DepthJobListener(GC bufferGC)
00324 {
00325 this.bufferGC = bufferGC;
00326 }
00327
00328 @Override
00329 public void sleeping(IJobChangeEvent event) {}
00330
00331 @Override
00332 public void scheduled(IJobChangeEvent event) {}
00333
00334 @Override
00335 public void running(IJobChangeEvent event) {}
00336
00337 @Override
00338 public void done(IJobChangeEvent event) {
00339 bufferGC.dispose();
00340 redraw();
00341 }
00342
00343 @Override
00344 public void awake(IJobChangeEvent event) {}
00345
00346 @Override
00347 public void aboutToRun(IJobChangeEvent event) {}
00348
00349 }
00350 }