Commit | Line | Data |
---|---|---|
739b9fec AM |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir | |
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 | ||
10 | package org.eclipse.tracecompass.internal.provisional.tmf.ui.views.timegraph2; | |
11 | ||
12 | import java.util.logging.Logger; | |
13 | ||
14 | import org.eclipse.jdt.annotation.Nullable; | |
15 | import org.eclipse.tracecompass.common.core.log.TraceCompassLog; | |
16 | import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; | |
17 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; | |
18 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; | |
19 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; | |
20 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalThrottler; | |
21 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; | |
22 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | |
23 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal; | |
24 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; | |
25 | import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal; | |
26 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; | |
27 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; | |
28 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
29 | ||
30 | public class SignallingContext { | |
31 | ||
32 | private static final Logger LOGGER = TraceCompassLog.getLogger(SignallingContext.class); | |
33 | ||
34 | private static final int SIGNAL_DELAY_MS = 200; | |
35 | ||
36 | private final TmfSignalThrottler fVisibleRangeSignalThrottler = new TmfSignalThrottler(null, SIGNAL_DELAY_MS); | |
37 | ||
38 | private final TimeGraphModelViewer fViewer; | |
39 | ||
40 | private @Nullable ITmfTrace fCurrentTrace = null; | |
41 | ||
42 | public SignallingContext(TimeGraphModelViewer viewer) { | |
43 | TmfSignalManager.register(this); | |
44 | fViewer = viewer; | |
45 | } | |
46 | ||
47 | public void dispose() { | |
48 | TmfSignalManager.deregister(this); | |
49 | } | |
50 | ||
51 | @Nullable ITmfTrace getCurrentTrace() { | |
52 | return fCurrentTrace; | |
53 | } | |
54 | ||
55 | public void sendTimeRangeSelectionUpdate(long startTs, long endTs) { | |
56 | TmfSignal signal = new TmfSelectionRangeUpdatedSignal(this, | |
57 | TmfTimestamp.fromNanos(startTs), | |
58 | TmfTimestamp.fromNanos(endTs)); | |
59 | TmfSignalManager.dispatchSignal(signal); | |
60 | } | |
61 | ||
62 | public void sendVisibleWindowRangeUpdate(long startTs, long endTs) { | |
63 | TmfSignal signal = new TmfWindowRangeUpdatedSignal(this, | |
64 | new TmfTimeRange(TmfTimestamp.fromNanos(startTs), TmfTimestamp.fromNanos(endTs))); | |
65 | fVisibleRangeSignalThrottler.queue(signal); | |
66 | } | |
67 | ||
68 | public void initializeForTrace(@Nullable ITmfTrace trace) { | |
69 | fCurrentTrace = trace; | |
70 | ||
71 | if (trace == null) { | |
72 | // TODO Clear the viewer? | |
73 | return; | |
74 | } | |
75 | ||
76 | long traceStartTime = trace.getStartTime().toNanos(); | |
77 | long traceEndTime = trace.getEndTime().toNanos(); | |
78 | ||
79 | /* The window's start time is the same as the trace's start time initially */ | |
80 | long windowStartTime = traceStartTime; | |
81 | long windowEndtime = Math.min(traceEndTime, traceStartTime + trace.getInitialRangeOffset().toNanos()); | |
82 | ||
83 | fViewer.setTimeGraphAreaRange(traceStartTime, traceEndTime); | |
84 | fViewer.seekVisibleRange(windowStartTime, windowEndtime); | |
85 | fViewer.paintArea(trace, windowStartTime, windowEndtime); | |
86 | } | |
87 | ||
88 | // ------------------------------------------------------------------------ | |
89 | // Signal handlers | |
90 | // ------------------------------------------------------------------------ | |
91 | ||
92 | @TmfSignalHandler | |
93 | public void traceOpened(TmfTraceOpenedSignal signal) { | |
94 | LOGGER.fine(() -> "[SignallingContext:ReceivedTraceOpen] trace=" + signal.getTrace().toString()); //$NON-NLS-1$ | |
95 | ||
96 | ITmfTrace newTrace = signal.getTrace(); | |
97 | fCurrentTrace = newTrace; | |
98 | initializeForTrace(newTrace); | |
99 | } | |
100 | ||
101 | @TmfSignalHandler | |
102 | public void traceSelected(final TmfTraceSelectedSignal signal) { | |
103 | LOGGER.fine(() -> "[SignallingContext:ReceivedTraceSelected] trace=" + signal.getTrace().toString()); | |
104 | ||
105 | ITmfTrace newTrace = signal.getTrace(); | |
106 | fCurrentTrace = newTrace; | |
107 | initializeForTrace(newTrace); | |
108 | } | |
109 | ||
110 | /** | |
111 | * @param signal | |
112 | */ | |
113 | @TmfSignalHandler | |
114 | public void traceClosed(final TmfTraceClosedSignal signal) { | |
115 | LOGGER.fine(() -> "[SignallingContext:ReceivedTraceClosed] " + //$NON-NLS-1$ | |
116 | signal.getTrace().getName()); | |
117 | ||
118 | // How does this signal work anyway? | |
119 | // TODO Implement this! | |
120 | //fViewer.clearViewer() | |
121 | } | |
122 | ||
123 | /** | |
124 | * @param signal | |
125 | */ | |
126 | @TmfSignalHandler | |
127 | public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) { | |
128 | long rangeStart = signal.getRange().getStartTime().toNanos(); | |
129 | long rangeEnd = signal.getRange().getEndTime().toNanos(); | |
130 | ||
131 | LOGGER.finer(() -> "[SignallingContext:ReceivedTraceRangeUpdated] " + //$NON-NLS-1$ | |
132 | String.format("rangeStart=%,d, rangeEnd=%,d", //$NON-NLS-1$ | |
133 | rangeStart, rangeEnd)); | |
134 | /* | |
135 | * This signal is a disaster, it's very inconsistent, has no guarantee | |
136 | * of even showing up and sometimes gives values outside of the trace's | |
137 | * own range. Best to ignore its contents completely. | |
138 | */ | |
139 | ||
140 | ITmfTrace trace = fCurrentTrace; | |
141 | if (trace != null) { | |
142 | long traceStart = trace.getStartTime().toNanos(); | |
143 | long traceEnd = trace.getEndTime().toNanos(); | |
144 | fViewer.setTimeGraphAreaRange(traceStart, traceEnd); | |
145 | } | |
146 | } | |
147 | ||
148 | /** | |
149 | * @param signal | |
150 | */ | |
151 | @TmfSignalHandler | |
152 | public void selectionRangeUpdated(final TmfSelectionRangeUpdatedSignal signal) { | |
153 | long rangeStart = signal.getBeginTime().toNanos(); | |
154 | long rangeEnd = signal.getEndTime().toNanos(); | |
155 | ||
156 | LOGGER.finer(() -> "[SignallingContext:ReceivedSelectionRangeUpdated] " + //$NON-NLS-1$ | |
157 | String.format("rangeStart=%,d, rangeEnd=%,d", //$NON-NLS-1$ | |
158 | rangeStart, rangeEnd)); | |
159 | ||
160 | if (rangeStart > rangeEnd) { | |
161 | /* This signal's end can be before its start time, against all logic */ | |
162 | fViewer.drawSelection(rangeEnd, rangeStart); | |
163 | } else { | |
164 | fViewer.drawSelection(rangeStart, rangeEnd); | |
165 | } | |
166 | } | |
167 | ||
168 | /** | |
169 | * @param signal | |
170 | */ | |
171 | @TmfSignalHandler | |
172 | public void windowRangeUpdated(final TmfWindowRangeUpdatedSignal signal) { | |
173 | ITmfTrace trace = fCurrentTrace; | |
174 | if (trace == null) { | |
175 | return; | |
176 | } | |
177 | ||
178 | long traceStart = trace.getStartTime().toNanos(); | |
179 | long traceEnd = trace.getEndTime().toNanos(); | |
180 | ||
181 | TmfTimeRange windowRange = signal.getCurrentRange(); | |
182 | long windowStart = Math.max(traceStart, windowRange.getStartTime().toNanos()); | |
183 | long windowEnd = Math.min(traceEnd, windowRange.getEndTime().toNanos()); | |
184 | ||
185 | LOGGER.finer(() -> "[SignallingContext:ReceivedWindowRangeUpdated] " + //$NON-NLS-1$ | |
186 | String.format("windowStart=%,d, windowEnd=%,d", //$NON-NLS-1$ | |
187 | windowStart, windowEnd)); | |
188 | ||
189 | fViewer.setTimeGraphAreaRange(traceStart, traceEnd); | |
190 | ||
191 | if (signal.getSource() != this) { | |
192 | /* | |
193 | * If the signal came from the time graph's own scrollbar, then the | |
194 | * zoom level did not change, and the view is already at the | |
195 | * position we want it. | |
196 | * | |
197 | * TODO May not be true when it comes from a zoom in/out event | |
198 | */ | |
199 | fViewer.seekVisibleRange(windowStart, windowEnd); | |
200 | } else { | |
201 | fViewer.updateLatestVisibleRange(windowStart, windowEnd); | |
202 | } | |
203 | ||
204 | fViewer.paintArea(trace, windowStart, windowEnd); | |
205 | } | |
206 | } |