Commit | Line | Data |
---|---|---|
6e512b93 | 1 | /******************************************************************************* |
8827c197 | 2 | * Copyright (c) 2009, 2010 Ericsson |
6e512b93 ASL |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation | |
de7ddc02 | 11 | * Bernd Hufmann - Bug fixes |
6e512b93 ASL |
12 | *******************************************************************************/ |
13 | package org.eclipse.linuxtools.lttng.ui.views.common; | |
14 | ||
8827c197 FC |
15 | import java.util.Arrays; |
16 | ||
5945cec9 FC |
17 | import org.eclipse.linuxtools.internal.lttng.core.LttngConstants; |
18 | import org.eclipse.linuxtools.internal.lttng.core.control.LttngCoreProviderFactory; | |
19 | import org.eclipse.linuxtools.internal.lttng.core.control.LttngSyntheticEventProvider; | |
20 | import org.eclipse.linuxtools.internal.lttng.core.event.LttngSyntheticEvent; | |
21 | import org.eclipse.linuxtools.internal.lttng.core.event.LttngTimestamp; | |
22 | import org.eclipse.linuxtools.internal.lttng.core.request.ILttngSyntEventRequest; | |
23 | import org.eclipse.linuxtools.internal.lttng.core.request.IRequestStatusListener; | |
24 | import org.eclipse.linuxtools.internal.lttng.core.request.LttngSyntEventRequest; | |
25 | import org.eclipse.linuxtools.internal.lttng.core.request.RequestCompletedSignal; | |
26 | import org.eclipse.linuxtools.internal.lttng.core.request.RequestStartedSignal; | |
27 | import org.eclipse.linuxtools.internal.lttng.core.state.evProcessor.ITransEventProcessor; | |
6e512b93 | 28 | import org.eclipse.linuxtools.lttng.ui.TraceDebug; |
8827c197 | 29 | import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer; |
4df4581d | 30 | import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp; |
6c13869b FC |
31 | import org.eclipse.linuxtools.tmf.core.event.TmfEvent; |
32 | import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange; | |
6c13869b | 33 | import org.eclipse.linuxtools.tmf.core.experiment.TmfExperiment; |
6c13869b | 34 | import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType; |
4df4581d | 35 | import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest; |
6c13869b FC |
36 | import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentDisposedSignal; |
37 | import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; | |
38 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; | |
39 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; | |
40 | import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; | |
8827c197 FC |
41 | import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITimeAnalysisViewer; |
42 | import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent; | |
43 | import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent; | |
44 | import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry; | |
6e512b93 | 45 | import org.eclipse.linuxtools.tmf.ui.views.TmfView; |
8827c197 | 46 | import org.eclipse.swt.widgets.Display; |
6e512b93 ASL |
47 | |
48 | /** | |
49 | * <p> | |
50 | * Abstract class used as a base for views handling specific time range data | |
51 | * requests | |
52 | * </p> | |
53 | * <p> | |
8827c197 FC |
54 | * The class handles a single element queue of data requests, i.e. request can |
55 | * be triggered from different sources e.g. opening a file as well as a new | |
56 | * selected time window | |
6e512b93 ASL |
57 | * </p> |
58 | * | |
59 | * @author alvaro | |
60 | * | |
61 | */ | |
c1c69938 | 62 | public abstract class AbsTimeUpdateView extends TmfView implements IRequestStatusListener { |
6e512b93 ASL |
63 | |
64 | // ======================================================================== | |
65 | // Data | |
66 | // ======================================================================== | |
777ead16 | 67 | |
0c2a2e08 FC |
68 | // private static final long INITIAL_WINDOW_OFFSET = (1L * 1 * 1000 * 1000); // .001sec |
69 | // private static final long INITIAL_WINDOW_OFFSET = (1L * 10 * 1000 * 1000); // .01sec | |
70 | private static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec | |
71 | // private static final long INITIAL_WINDOW_OFFSET = (1L * 1000 * 1000 * 1000); // 1sec | |
777ead16 | 72 | |
8827c197 FC |
73 | /** |
74 | * Number of events before a GUI refresh | |
75 | */ | |
b12f4544 | 76 | protected static final Long INPUT_CHANGED_REFRESH = 75000L; |
a79913eb | 77 | private static final long DEFAULT_OFFSET = 0; |
8827c197 | 78 | |
0c2a2e08 | 79 | protected boolean synch = true; // time synchronization, used to be an option |
8827c197 | 80 | protected ITimeAnalysisViewer tsfviewer = null; |
6e512b93 | 81 | |
cb866e08 FC |
82 | private LttngSyntEventRequest fCurrentRequest = null; |
83 | ||
c1c69938 FC |
84 | protected LttngSyntheticEventProvider fProvider = LttngCoreProviderFactory.getEventProvider(getProviderId()); |
85 | ||
86 | // ======================================================================== | |
6e512b93 ASL |
87 | // Constructor |
88 | // ======================================================================== | |
89 | public AbsTimeUpdateView(String viewID) { | |
8827c197 FC |
90 | super(viewID); |
91 | // freqState = UiCommonFactory.getQueue(this); | |
6e512b93 ASL |
92 | } |
93 | ||
94 | // ======================================================================== | |
95 | // Methods | |
96 | // ======================================================================== | |
c1c69938 FC |
97 | |
98 | /** | |
99 | * Returns the number of events after which the relevant display will | |
100 | * be refreshed | |
101 | * | |
102 | * @return | |
103 | */ | |
104 | protected Long getInputChangedRefresh() { | |
105 | return INPUT_CHANGED_REFRESH; | |
106 | } | |
107 | ||
90de83da BH |
108 | /** |
109 | * Cancel the ongoing request if another experiment is being selected | |
110 | * @param experimentDisposedSignal | |
111 | */ | |
112 | @TmfSignalHandler | |
113 | public void experimentDisposed(TmfExperimentDisposedSignal<? extends TmfEvent> experimentDisposedSignal) { | |
828e5592 PT |
114 | if (experimentDisposedSignal.getExperiment() != TmfExperiment.getCurrentExperiment()) { |
115 | return; | |
116 | } | |
90de83da BH |
117 | fProvider.conditionallyCancelRequests(); |
118 | } | |
119 | ||
6e512b93 ASL |
120 | /* |
121 | * (non-Javadoc) | |
122 | * | |
123 | * @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener# | |
124 | * processingStarted(org.eclipse.linuxtools.lttng.state.StateDataRequest) | |
125 | */ | |
d4011df2 | 126 | @Override |
6e512b93 ASL |
127 | @TmfSignalHandler |
128 | public synchronized void processingStarted(RequestStartedSignal signal) { | |
8827c197 | 129 | LttngSyntEventRequest request = signal.getRequest(); |
6e512b93 | 130 | if (request != null) { |
8827c197 FC |
131 | // update queue with the id of the current request. |
132 | // freqState.requestStarted(request); | |
133 | ||
134 | // if there was no new request then this one is still on | |
135 | // prepare for the reception of new data | |
136 | waitCursor(true); | |
137 | ||
138 | // no new time range for zoom orders | |
139 | TmfTimeRange trange = null; | |
140 | // Time Range will be used to filter out events which are | |
141 | // not visible in one pixel | |
142 | trange = request.getRange(); | |
143 | ||
144 | // indicate if the data model needs to be cleared e.g. a new | |
145 | // experiment is being selected | |
146 | boolean clearData = request.isclearDataInd(); | |
147 | // Indicate if current data needs to be cleared and if so | |
148 | // specify the new experiment time range that applies | |
c6f55e56 | 149 | modelUpdatePrep(trange, clearData); |
6e512b93 ASL |
150 | } |
151 | } | |
152 | ||
153 | /* | |
154 | * (non-Javadoc) | |
155 | * | |
156 | * @seeorg.eclipse.linuxtools.lttng.state.IStateDataRequestListener# | |
157 | * processingCompleted(org.eclipse.linuxtools.lttng.state.StateDataRequest) | |
158 | */ | |
d4011df2 | 159 | @Override |
6e512b93 | 160 | @TmfSignalHandler |
8827c197 FC |
161 | public void processingCompleted(RequestCompletedSignal signal) { |
162 | ILttngSyntEventRequest request = signal.getRequest(); | |
6e512b93 ASL |
163 | |
164 | if (request == null) { | |
165 | return; | |
8035003b | 166 | } |
6e512b93 | 167 | |
8827c197 FC |
168 | // Update wait cursor |
169 | waitCursor(false); | |
170 | ||
6e512b93 ASL |
171 | // No data refresh actions for cancelled requests. |
172 | if (request.isCancelled() || request.isFailed()) { | |
173 | if (TraceDebug.isDEBUG()) { | |
174 | TmfTimeRange trange = request.getRange(); | |
175 | if (request.isCancelled()) { | |
3b38ea61 FC |
176 | TraceDebug.debug("Request cancelled " //$NON-NLS-1$ |
177 | + trange.getStartTime() + "-" + trange.getEndTime() //$NON-NLS-1$ | |
178 | + " Handled Events: " + request.getSynEventCount() //$NON-NLS-1$ | |
179 | + " " + request.toString(), 15); //$NON-NLS-1$ | |
6e512b93 | 180 | } else if (request.isFailed()) { |
3b38ea61 FC |
181 | TraceDebug.debug("Request Failed " + trange.getStartTime() //$NON-NLS-1$ |
182 | + "-" + trange.getEndTime() + " Handled Events: " //$NON-NLS-1$ //$NON-NLS-2$ | |
183 | + request.getSynEventCount() + " " //$NON-NLS-1$ | |
8827c197 | 184 | + request.toString()); |
6e512b93 ASL |
185 | } |
186 | } | |
187 | ||
188 | return; | |
189 | } else { | |
8827c197 | 190 | modelInputChanged(request, true); |
6e512b93 ASL |
191 | } |
192 | } | |
193 | ||
194 | /** | |
8827c197 | 195 | * Registers as listener of time selection from other views |
6e512b93 | 196 | * |
8827c197 | 197 | * @param signal |
6e512b93 | 198 | */ |
8827c197 | 199 | public void synchToTime(TmfTimeSynchSignal signal) { |
f9a8715c FC |
200 | if (signal == null) |
201 | return; | |
8827c197 FC |
202 | if (synch) { |
203 | Object source = signal.getSource(); | |
f9a8715c | 204 | if (source != null && source != this) { |
de7ddc02 BH |
205 | |
206 | if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) { | |
207 | ||
208 | // Check for GUI thread | |
209 | if (Display.getCurrent() != null) { | |
210 | // GUI thread - execute update right away. | |
211 | ||
212 | // Internal value is expected in nano seconds. | |
213 | long selectedTime = signal.getCurrentTime().getValue(); | |
214 | if (tsfviewer != null) { | |
215 | tsfviewer.setSelectedTime(selectedTime, true, source); | |
216 | ||
217 | ParamsUpdater paramUpdater = getParamsUpdater(); | |
218 | Long savedSelTime = paramUpdater.getSelectedTime(); | |
219 | if ((savedSelTime == null) || (savedSelTime != selectedTime)) { | |
220 | // Update the parameter updater to save the selected time | |
221 | paramUpdater.setSelectedTime(selectedTime); | |
222 | } | |
223 | } | |
224 | } else { | |
225 | // Perform the updates on the UI thread | |
226 | ||
227 | // We need to clone the timestamp in the signal so that it won't be overwritten duo to multipe thread access | |
228 | final TmfTimeSynchSignal savedSignal = new TmfTimeSynchSignal(signal.getSource(), signal.getCurrentTime().clone()); | |
229 | tsfviewer.getControl().getDisplay().asyncExec(new Runnable() { | |
230 | @Override | |
231 | public void run() { | |
232 | if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) { | |
233 | synchToTime(savedSignal); | |
234 | } | |
235 | } | |
236 | }); | |
237 | } | |
41dc35d0 | 238 | } |
8827c197 FC |
239 | } |
240 | } | |
241 | } | |
242 | ||
243 | /** | |
244 | * Process the reception of time window adjustment in this view if the | |
245 | * source of the update is not this view. | |
246 | * | |
247 | * @param signal | |
248 | * @param clearingData | |
249 | */ | |
250 | public void synchToTimeRange(TmfRangeSynchSignal signal, boolean clearingData) { | |
f9a8715c FC |
251 | if (signal == null) |
252 | return; | |
8827c197 FC |
253 | if (synch) { |
254 | Object source = signal.getSource(); | |
f9a8715c | 255 | if (source != null && source != this) { |
8827c197 FC |
256 | // Internal value is expected in nano seconds. |
257 | TmfTimeRange trange = signal.getCurrentRange(); | |
258 | TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment(); | |
259 | if (experiment == null) { | |
3b38ea61 | 260 | TraceDebug.debug("Current selected experiment is null"); //$NON-NLS-1$ |
8827c197 | 261 | return; |
63eecb47 | 262 | } |
6e512b93 | 263 | |
8827c197 | 264 | // Clearing of process data is configurable |
a79913eb | 265 | eventRequest(trange, experiment.getTimeRange(), clearingData, ExecutionType.FOREGROUND); |
41dc35d0 | 266 | } |
6e512b93 ASL |
267 | } |
268 | } | |
269 | ||
270 | /** | |
8827c197 FC |
271 | * Trigger time synchronisation to other views this method shall be called |
272 | * when a check has been performed to note that an actual change of time has | |
273 | * been performed vs a pure re-selection of the same time | |
274 | * | |
275 | * @param time | |
276 | * @param source | |
6e512b93 | 277 | */ |
8827c197 FC |
278 | protected void synchTimeNotification(long time, Object source) { |
279 | // if synchronisation selected | |
280 | if (synch) { | |
281 | // Notify other views | |
282 | TmfSignalManager.dispatchSignal(new TmfTimeSynchSignal(source, new LttngTimestamp(time))); | |
283 | } | |
284 | } | |
285 | ||
286 | /** | |
287 | * Common implementation of ITmfTimeSelectionListener, not used by all the | |
288 | * views extending this abstract class | |
289 | * | |
290 | * @param event | |
291 | */ | |
292 | protected void tsfTmProcessSelEvent(TmfTimeSelectionEvent event) { | |
293 | Object source = event.getSource(); | |
294 | if (source == null) { | |
295 | return; | |
296 | } | |
297 | ||
298 | ParamsUpdater paramUpdater = getParamsUpdater(); | |
299 | Long savedSelTime = paramUpdater.getSelectedTime(); | |
300 | ||
301 | long selTimens = event.getSelectedTime(); | |
302 | ||
303 | // make sure the new selected time is different than saved before | |
304 | // executing update | |
305 | if (savedSelTime == null || savedSelTime != selTimens) { | |
306 | // Notify listener views. | |
307 | synchTimeNotification(selTimens, source); | |
308 | ||
309 | // Update the parameter updater to save the selected time | |
310 | paramUpdater.setSelectedTime(selTimens); | |
311 | ||
63eecb47 | 312 | if (TraceDebug.isDEBUG()) { |
3b38ea61 | 313 | TraceDebug.debug("Selected Time: " + new LttngTimestamp(selTimens) + "\n\t\t" + getName()); //$NON-NLS-1$ //$NON-NLS-2$ |
63eecb47 | 314 | } |
8827c197 FC |
315 | } |
316 | } | |
63eecb47 | 317 | |
8827c197 FC |
318 | /** |
319 | * Common implementation of ITmfTimeScaleSelectionListener, not used by all | |
320 | * the views extending this abstract class | |
321 | * | |
322 | * @param event | |
323 | */ | |
c1c69938 FC |
324 | protected void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event) { |
325 | // source needed to keep track of source values | |
326 | Object source = event.getSource(); | |
327 | ||
328 | boolean newParams = false; | |
329 | TmfTimeRange trange = null; | |
330 | Long selectedTime = null; | |
331 | ||
332 | // update all information and get relevant data | |
333 | synchronized (this) { | |
334 | if (source != null) { | |
335 | // Update the parameter updater before carrying out a read request | |
336 | ParamsUpdater paramUpdater = getParamsUpdater(); | |
337 | newParams = paramUpdater.processTimeScaleEvent(event); | |
338 | ||
339 | if (newParams) { | |
340 | // Read the updated time window | |
341 | trange = paramUpdater.getTrange(); | |
342 | if (trange != null) { | |
343 | selectedTime = paramUpdater.getSelectedTime(); | |
344 | } | |
345 | } | |
346 | } | |
347 | } | |
348 | ||
349 | // Check for selectedTime is sufficient since it is only set if | |
350 | // newParams is true and trange is not null | |
351 | if (selectedTime != null) { | |
352 | // Notify listener views. to perform data requests | |
353 | // upon this notification | |
354 | ||
355 | // Note that this has to be done outside the synchronized statement | |
356 | // because otherwise we could end-up in a deadlock if a ongoing | |
357 | // request needs to be canceled. | |
358 | synchTimeRangeNotification(trange, selectedTime, source); | |
8827c197 FC |
359 | } |
360 | } | |
361 | ||
362 | /** | |
363 | * Inform registered listeners about the new time range | |
364 | * | |
365 | * @param trange | |
366 | * @param selectedTime | |
367 | * @param source | |
368 | */ | |
369 | protected void synchTimeRangeNotification(TmfTimeRange trange, Long selectedTime, Object source) { | |
370 | // if synchronisation selected | |
371 | if (synch) { | |
372 | // Notify other views | |
373 | TmfSignalManager.dispatchSignal(new TmfRangeSynchSignal(source, trange, new LttngTimestamp(selectedTime))); | |
374 | } | |
375 | } | |
376 | ||
377 | /** | |
378 | * @param zoomedTRange | |
379 | * @param experimentTRange | |
a79913eb FC |
380 | * @param clearingData |
381 | * @param execType | |
382 | */ | |
383 | public void eventRequest(TmfTimeRange zoomedTRange, TmfTimeRange experimentTRange, boolean clearingData, ExecutionType execType) { | |
384 | ||
385 | // timeRange is the Experiment time range | |
386 | boolean sent = processDataRequest(zoomedTRange, experimentTRange, DEFAULT_OFFSET, TmfDataRequest.ALL_DATA, clearingData, execType); | |
387 | ||
388 | if (sent) { | |
389 | waitCursor(true); | |
390 | } | |
391 | } | |
392 | ||
393 | /** | |
394 | * @param offset | |
395 | * @param nbRequested | |
396 | * @param startTime | |
397 | * @param clearingData | |
9b635e61 | 398 | * @param execType |
8827c197 | 399 | */ |
a79913eb | 400 | public void eventRequest(long offset, TmfTimeRange range, boolean clearingData, ExecutionType execType) { |
8827c197 FC |
401 | |
402 | // timeRange is the Experiment time range | |
a79913eb | 403 | boolean sent = processDataRequest(range, null, offset, TmfDataRequest.ALL_DATA, clearingData, execType); |
8827c197 FC |
404 | |
405 | if (sent) { | |
406 | waitCursor(true); | |
407 | } | |
408 | } | |
409 | ||
9b635e61 FC |
410 | // /** |
411 | // * @param zoomedTRange | |
412 | // * @param experimentTRange | |
413 | // * @param execType | |
414 | // */ | |
415 | // public void dataRequest(TmfTimeRange zoomedTRange, | |
416 | // TmfTimeRange experimentTRange, boolean clearingData) { | |
417 | // | |
418 | // // timeRange is the Experiment time range | |
419 | // boolean sent = processDataRequest(zoomedTRange, experimentTRange, clearingData); | |
420 | // | |
421 | // if (sent) { | |
422 | // waitCursor(true); | |
423 | // } | |
424 | // } | |
425 | ||
8827c197 FC |
426 | /** |
427 | * send data request directly e.g. doesn't use a queue | |
428 | * | |
429 | * @param requestTrange | |
430 | * @param listener | |
431 | * @param experimentTRange | |
9b635e61 | 432 | * @param execType |
8827c197 FC |
433 | * @param processor |
434 | * @return | |
435 | */ | |
436 | private boolean processDataRequest(TmfTimeRange requestTrange, | |
a79913eb | 437 | TmfTimeRange experimentTRange, long offset, int nbRequested, boolean clearingData, ExecutionType execType) { |
8827c197 | 438 | // Validate input |
a79913eb | 439 | if (requestTrange == null) { |
3b38ea61 | 440 | TraceDebug.debug("Invalid input"); //$NON-NLS-1$ |
8827c197 FC |
441 | return false; |
442 | } | |
443 | ||
cb866e08 | 444 | // Cancel the currently executing request before starting a new one |
c1c69938 | 445 | fProvider.conditionallyCancelRequests(); |
cb866e08 | 446 | fCurrentRequest = new LttngSyntEventRequest( |
a79913eb | 447 | requestTrange, offset, nbRequested, |
8016d660 | 448 | LttngConstants.DEFAULT_BLOCK_SIZE, this, experimentTRange, getEventProcessor(), |
c1c69938 | 449 | TmfExperiment.getCurrentExperiment().getName(), execType) { |
8827c197 FC |
450 | |
451 | Long fCount = getSynEventCount(); | |
452 | ITransEventProcessor processor = getProcessor(); | |
4df4581d | 453 | ITmfTimestamp frunningTimeStamp; |
8827c197 FC |
454 | |
455 | /* | |
456 | * (non-Javadoc) | |
457 | * | |
458 | * @see | |
459 | * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData | |
460 | * () | |
461 | */ | |
f9673903 FC |
462 | //// int handleDataCount = 0; |
463 | //// int handleDataValidCount = 0; | |
464 | // @Override | |
465 | // public void handleData() { | |
466 | // LttngSyntheticEvent[] result = getData(); | |
467 | // | |
468 | // TmfEvent evt = (result.length > 0) ? result[0] : null; | |
469 | //// handleDataCount++; | |
470 | ||
550d787e | 471 | @Override |
f9673903 FC |
472 | public void handleData(LttngSyntheticEvent event) { |
473 | super.handleData(event); | |
474 | if (event != null) { | |
cb866e08 | 475 | // handleDataValidCount++; |
f9673903 | 476 | LttngSyntheticEvent synEvent = (LttngSyntheticEvent) event; |
8827c197 | 477 | // process event |
c1c69938 FC |
478 | switch (synEvent.getSynType()) { |
479 | ||
480 | case STARTREQ: { | |
481 | handleRequestStarted(); | |
482 | break; | |
483 | } | |
484 | ||
485 | case BEFORE: { | |
486 | processor.process(event, synEvent.getTraceModel()); | |
487 | fCount++; | |
488 | if ((fCount != 0) && (fCount % getInputChangedRefresh() == 0)) { | |
489 | // send partial update | |
490 | modelInputChanged(this, false); | |
491 | ||
492 | if (TraceDebug.isDEBUG()) { | |
493 | frunningTimeStamp = event.getTimestamp(); | |
3b38ea61 | 494 | TraceDebug.debug("handled: " + fCount + " sequence: " + synEvent.getSynType()); //$NON-NLS-1$ //$NON-NLS-2$ |
c1c69938 FC |
495 | } |
496 | } | |
497 | break; | |
498 | } | |
499 | ||
500 | case AFTER: | |
501 | // fall-through | |
502 | case ENDREQ:{ | |
503 | processor.process(event, synEvent.getTraceModel()); | |
504 | break; | |
505 | } | |
506 | ||
507 | default: | |
508 | // nothing to do | |
509 | break; | |
510 | } | |
8827c197 FC |
511 | } |
512 | } | |
513 | ||
514 | public void handleRequestStarted() { | |
515 | notifyStarting(); | |
516 | } | |
550d787e FC |
517 | |
518 | @Override | |
519 | public void done() { | |
cb866e08 FC |
520 | // if (TraceDebug.isDEBUG()) { |
521 | // TraceDebug.debug("AbsTimeUpdateView: Received=" + handleDataCount + ", Valid=" + handleDataCount + ", fCount=" + fCount); | |
522 | // } | |
550d787e FC |
523 | super.done(); |
524 | } | |
8827c197 | 525 | |
550d787e | 526 | @Override |
8827c197 FC |
527 | public void handleCompleted() { |
528 | super.handleCompleted(); | |
529 | ||
530 | // Data is not complete and should be handled as such | |
531 | if (isFailed() || isCancelled()) { | |
532 | modelIncomplete(this); | |
533 | } | |
534 | ||
535 | if (TraceDebug.isDEBUG()) { | |
536 | if (frunningTimeStamp != null) { | |
3b38ea61 | 537 | TraceDebug.debug("Last event time stamp: " + frunningTimeStamp.getValue()); //$NON-NLS-1$ |
8827c197 FC |
538 | } |
539 | } | |
540 | } | |
541 | }; | |
542 | ||
8827c197 | 543 | // send the request to TMF |
c1c69938 | 544 | fCurrentRequest.startRequestInd(fProvider); |
cb866e08 | 545 | fCurrentRequest.setclearDataInd(clearingData); |
8827c197 FC |
546 | return true; |
547 | } | |
548 | ||
549 | /** | |
550 | * Returns an initial smaller window to allow the user to select the area of | |
551 | * interest | |
552 | * | |
553 | * @param experimentTRange | |
554 | * @return | |
555 | */ | |
556 | protected TmfTimeRange getInitTRange(TmfTimeRange experimentTRange) { | |
4df4581d | 557 | ITmfTimestamp expStartTime = experimentTRange.getStartTime(); |
558 | ITmfTimestamp expEndTime = experimentTRange.getEndTime(); | |
d7dbf09a | 559 | ITmfTimestamp initialEndOfWindow = new LttngTimestamp(expStartTime |
8827c197 FC |
560 | .getValue() |
561 | + INITIAL_WINDOW_OFFSET); | |
562 | if (initialEndOfWindow.compareTo(expEndTime, false) < 0) { | |
563 | return new TmfTimeRange(expStartTime, initialEndOfWindow); | |
6e512b93 | 564 | } |
8827c197 FC |
565 | |
566 | // The original size of the experiment is smaller than proposed adjusted | |
567 | // time | |
568 | return experimentTRange; | |
6e512b93 ASL |
569 | } |
570 | ||
571 | /** | |
572 | * Request the Time Analysis widget to enable or disable the wait cursor | |
573 | * e.g. data request in progress or data request completed | |
574 | * | |
575 | * @param waitInd | |
576 | */ | |
8827c197 | 577 | protected void waitCursor(final boolean waitInd) { |
db1ea19b | 578 | if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) { |
8827c197 FC |
579 | Display display = tsfviewer.getControl().getDisplay(); |
580 | ||
581 | // Perform the updates on the UI thread | |
582 | display.asyncExec(new Runnable() { | |
d4011df2 | 583 | @Override |
8827c197 | 584 | public void run() { |
db1ea19b FC |
585 | if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) { |
586 | tsfviewer.waitCursor(waitInd); | |
587 | } | |
8827c197 FC |
588 | } |
589 | }); | |
590 | } | |
591 | } | |
6e512b93 ASL |
592 | |
593 | /** | |
8827c197 | 594 | * View preparation to override the current local information |
6e512b93 | 595 | * |
d712a5f3 FC |
596 | * @param timeRange |
597 | * - new total time range e.g. Experiment level | |
8827c197 FC |
598 | * @param clearAllData |
599 | */ | |
c6f55e56 | 600 | protected void modelUpdatePrep(TmfTimeRange timeRange, boolean clearAllData) { |
8827c197 FC |
601 | ItemContainer<?> itemContainer = getItemContainer(); |
602 | if (clearAllData) { | |
603 | // start fresh e.g. new experiment selected | |
604 | itemContainer.clearItems(); | |
605 | } else { | |
606 | // clear children but keep processes | |
607 | itemContainer.clearChildren(); | |
608 | } | |
609 | ||
610 | // Obtain the current resource array | |
611 | ITmfTimeAnalysisEntry[] itemArr = itemContainer.readItems(); | |
612 | ||
613 | // clean up data and boundaries | |
614 | displayModel(itemArr, -1, -1, false, -1, -1, null); | |
615 | ||
616 | ParamsUpdater updater = getParamsUpdater(); | |
617 | if (updater != null) { | |
618 | // Start over | |
619 | updater.setEventsDiscarded(0); | |
620 | ||
621 | // Update new visible time range if available | |
622 | if (timeRange != null) { | |
623 | updater.update(timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue()); | |
624 | } | |
625 | } | |
626 | } | |
627 | ||
628 | /** | |
629 | * Initialize the model and view before reloading items | |
630 | * | |
631 | * @param boundaryRange | |
632 | * @param visibleRange | |
633 | * @param source | |
6e512b93 | 634 | */ |
c6f55e56 | 635 | protected void modelUpdateInit(TmfTimeRange boundaryRange, TmfTimeRange visibleRange, Object source) { |
8827c197 FC |
636 | // Update the view boundaries |
637 | if (boundaryRange != null) { | |
638 | ItemContainer<?> itemContainer = getItemContainer(); | |
639 | if (itemContainer != null) { | |
640 | itemContainer.clearItems(); | |
641 | // Obtain the current process array | |
642 | ITmfTimeAnalysisEntry[] itemArr = itemContainer.readItems(); | |
643 | ||
644 | long startTime = boundaryRange.getStartTime().getValue(); | |
645 | long endTime = boundaryRange.getEndTime().getValue(); | |
646 | ||
647 | // Update the view part | |
648 | displayModel(itemArr, startTime, endTime, true, visibleRange.getStartTime().getValue(), visibleRange | |
649 | .getEndTime().getValue(), source); | |
650 | } | |
651 | } | |
652 | ||
653 | // update the view filtering parameters | |
654 | if (visibleRange != null) { | |
655 | ParamsUpdater updater = getParamsUpdater(); | |
656 | if (updater != null) { | |
657 | // Start over | |
658 | updater.setEventsDiscarded(0); | |
659 | // Update new visible time range if available | |
660 | updater.update(visibleRange.getStartTime().getValue(), visibleRange.getEndTime().getValue()); | |
661 | } | |
662 | } | |
663 | } | |
6e512b93 ASL |
664 | |
665 | /** | |
666 | * Actions taken by the view to refresh its widget(s) with the updated data | |
667 | * model | |
668 | * | |
669 | * @param request | |
8827c197 FC |
670 | * @param complete |
671 | * true: yes, false: partial update | |
672 | */ | |
a79913eb | 673 | @SuppressWarnings("deprecation") |
8827c197 FC |
674 | protected void modelInputChanged(ILttngSyntEventRequest request, boolean complete) { |
675 | long experimentStartTime = -1; | |
676 | long experimentEndTime = -1; | |
677 | TmfTimeRange experimentTimeRange = request.getExperimentTimeRange(); | |
678 | if (experimentTimeRange != null) { | |
679 | experimentStartTime = experimentTimeRange.getStartTime().getValue(); | |
680 | experimentEndTime = experimentTimeRange.getEndTime().getValue(); | |
681 | } | |
682 | ||
683 | // Obtain the current resource list | |
684 | ITmfTimeAnalysisEntry[] itemArr = getItemContainer().readItems(); | |
685 | ||
686 | if (itemArr != null) { | |
687 | // Sort the array by pid | |
688 | Arrays.sort(itemArr); | |
689 | ||
690 | // Update the view part | |
691 | displayModel(itemArr, experimentStartTime, experimentEndTime, false, request.getRange().getStartTime() | |
692 | .getValue(), request.getRange().getEndTime().getValue(), request.getSource()); | |
693 | } | |
694 | ||
695 | if (complete) { | |
696 | // reselect to original time | |
5dbe4d3b | 697 | ParamsUpdater paramUpdater = getParamsUpdater(); |
db1ea19b | 698 | if ((paramUpdater != null) && (tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) { |
8827c197 FC |
699 | final Long selTime = paramUpdater.getSelectedTime(); |
700 | if (selTime != null) { | |
3b38ea61 | 701 | TraceDebug.debug("View: " + getName() + "\n\t\tRestoring the selected time to: " + selTime); //$NON-NLS-1$ //$NON-NLS-2$ |
8827c197 FC |
702 | Display display = tsfviewer.getControl().getDisplay(); |
703 | display.asyncExec(new Runnable() { | |
d4011df2 | 704 | @Override |
8827c197 | 705 | public void run() { |
db1ea19b FC |
706 | if ((tsfviewer != null) && (!tsfviewer.getControl().isDisposed())) { |
707 | tsfviewer.setSelectedTime(selTime, false, this); | |
708 | } | |
8827c197 FC |
709 | } |
710 | }); | |
711 | } | |
712 | ||
9b635e61 FC |
713 | // System.out.println(System.currentTimeMillis() + ": AbsTimeUpdate (" + getName() + ") completed"); |
714 | ||
8827c197 FC |
715 | if (TraceDebug.isDEBUG()) { |
716 | int eventCount = 0; | |
717 | Long count = request.getSynEventCount(); | |
718 | for (int pos = 0; pos < itemArr.length; pos++) { | |
719 | eventCount += itemArr[pos].getTraceEvents().size(); | |
720 | } | |
721 | ||
5dbe4d3b | 722 | int discarded = paramUpdater.getEventsDiscarded(); |
8827c197 | 723 | int discardedOutofOrder = paramUpdater.getEventsDiscardedWrongOrder(); |
5dbe4d3b ASL |
724 | int discardedOutofViewRange = paramUpdater.getEventsDiscardedOutOfViewRange(); |
725 | int dicardedNotVisible = paramUpdater.getEventsDiscardedNotVisible(); | |
726 | ||
8827c197 | 727 | TmfTimeRange range = request.getRange(); |
3b38ea61 FC |
728 | StringBuilder sb = new StringBuilder("View: " + getName() + ", Events handled: " + count //$NON-NLS-1$ //$NON-NLS-2$ |
729 | + ", Events loaded in view: " + eventCount + ", Number of events discarded: " + discarded //$NON-NLS-1$ //$NON-NLS-2$ | |
730 | + "\n\tNumber of events discarded with start time earlier than next good time: " //$NON-NLS-1$ | |
731 | + discardedOutofOrder + "\n\tDiscarded Not visible: " + dicardedNotVisible //$NON-NLS-1$ | |
732 | + "\n\tDiscarded out of view Range: " + discardedOutofViewRange); //$NON-NLS-1$ | |
733 | ||
734 | sb.append("\n\t\tRequested Time Range: " + range.getStartTime() + "-" + range.getEndTime()); //$NON-NLS-1$ //$NON-NLS-2$ | |
735 | sb.append("\n\t\tExperiment Time Range: " + experimentStartTime + "-" + experimentEndTime); //$NON-NLS-1$ //$NON-NLS-2$ | |
8827c197 FC |
736 | TraceDebug.debug(sb.toString()); |
737 | } | |
738 | } | |
739 | ||
740 | } | |
741 | } | |
742 | ||
743 | // /** | |
744 | // * Obtains the remainder fraction on unit Seconds of the entered value in | |
745 | // * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds | |
746 | // can | |
747 | // * be obtain by removing the last 9 digits: 1241207054 the fractional | |
748 | // * portion of seconds, expressed in ns is: 171080214 | |
749 | // * | |
750 | // * @param v | |
751 | // * @return | |
752 | // */ | |
753 | // protected String formatNs(long v) { | |
754 | // StringBuffer str = new StringBuffer(); | |
755 | // boolean neg = v < 0; | |
756 | // if (neg) { | |
757 | // v = -v; | |
758 | // str.append('-'); | |
759 | // } | |
760 | // | |
761 | // String strVal = String.valueOf(v); | |
762 | // if (v < 1000000000) { | |
763 | // return strVal; | |
764 | // } | |
765 | // | |
766 | // // Extract the last nine digits (e.g. fraction of a S expressed in ns | |
767 | // return strVal.substring(strVal.length() - 9); | |
768 | // } | |
769 | ||
770 | /** | |
771 | * The request was stopped, the data is incomplete | |
772 | * | |
773 | * @param request | |
774 | */ | |
775 | protected abstract void modelIncomplete(ILttngSyntEventRequest request); | |
776 | ||
777 | /** | |
778 | * Returns the Event processor instance related to a specific view | |
779 | * | |
780 | * @return | |
781 | */ | |
782 | protected abstract ITransEventProcessor getEventProcessor(); | |
783 | ||
784 | /** | |
785 | * To be overridden by some sub-classes although may not be needed in some | |
786 | * e.g. statistics view | |
787 | * | |
788 | * @param items | |
789 | * @param startBoundTime | |
790 | * @param endBoundTime | |
791 | * @param updateTimeBounds | |
792 | * - Time bounds updated needed e.g. if a new Experiment or trace | |
793 | * is selected | |
794 | * @param startVisibleWindow | |
795 | * @param endVisibleWindow | |
796 | * @param source | |
797 | */ | |
798 | protected abstract void displayModel(final ITmfTimeAnalysisEntry[] items, final long startBoundTime, | |
799 | final long endBoundTime, final boolean updateTimeBounds, final long startVisibleWindow, | |
800 | final long endVisibleWindow, final Object source); | |
801 | ||
802 | /** | |
803 | * To be overridden by some sub-classes although may not be needed in some | |
804 | * e.g. statistics view | |
805 | * | |
806 | * @return | |
807 | */ | |
808 | protected abstract ParamsUpdater getParamsUpdater(); | |
809 | ||
810 | /** | |
811 | * Returns the model's item container | |
812 | * | |
813 | * @return | |
6e512b93 | 814 | */ |
8827c197 | 815 | protected abstract ItemContainer<?> getItemContainer(); |
c1c69938 FC |
816 | |
817 | /** | |
818 | * Returns LTTng Synthetic Provider ID used for current view | |
819 | * | |
820 | * @return | |
821 | */ | |
822 | protected abstract int getProviderId(); | |
6e512b93 | 823 | } |