lttng/tmf: Set line delimiters and encoding for help plugins
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfTraceManager.java
CommitLineData
fc526aef
AM
1/*******************************************************************************
2 * Copyright (c) 2013 Ericsson
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 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.core.trace;
14
15import java.util.LinkedHashMap;
16import java.util.Map;
17
18import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
19import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
20import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
21import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
22import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
23import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
24import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
25import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
26import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
27import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
28
29/**
30 * Central trace manager for TMF. It tracks the currently opened traces and
31 * experiment, as well as the currently-selected timestamps and time ranges for
32 * each one of those.
33 *
34 * It's a singleton class, so only one instance should exist (available via
35 * {@link #getInstance()}).
36 *
37 * @author Alexandre Montplaisir
38 * @since 2.0
39 */
40public final class TmfTraceManager {
41
42 // ------------------------------------------------------------------------
43 // Attributes
44 // ------------------------------------------------------------------------
45
46 private final Map<ITmfTrace, TmfTraceContext> fTraces;
47
48 /** The currently-selected trace. Should always be part of the trace map */
49 private ITmfTrace fCurrentTrace = null;
50
51 // ------------------------------------------------------------------------
52 // Constructor
53 // ------------------------------------------------------------------------
54
55 private TmfTraceManager() {
56 fTraces = new LinkedHashMap<ITmfTrace, TmfTraceContext>();
57 TmfSignalManager.registerVIP(this);
58 }
59
60 /** Singleton instance */
61 private static TmfTraceManager tm = null;
62
63 /**
64 * Get an instance of the trace manager.
65 *
66 * @return The trace manager
67 */
68 public static synchronized TmfTraceManager getInstance() {
69 if (tm == null) {
70 tm = new TmfTraceManager();
71 }
72 return tm;
73 }
74
75 // ------------------------------------------------------------------------
76 // Accessors
77 // ------------------------------------------------------------------------
78
79 /**
80 * Return the current selected time.
81 *
82 * @return the current time stamp
83 */
84 public synchronized ITmfTimestamp getCurrentTime() {
85 return getCurrentTraceContext().getTimestamp();
86 }
87
88 /**
89 * Return the current selected range.
90 *
91 * @return the current time range
92 */
93 public synchronized TmfTimeRange getCurrentRange() {
94 return getCurrentTraceContext().getTimerange();
95 }
96
97 /**
98 * Get the currently selected trace (normally, the focused editor).
99 *
100 * @return The active trace
101 */
102 public synchronized ITmfTrace getActiveTrace() {
103 return fCurrentTrace;
104 }
105
106 /**
107 * Get the currently active trace set. For a 'normal' trace, this is simply
108 * an array with only that trace in it. For trace experiments, this will be
109 * an array containing the 'real' child traces in the experiment.
110 *
111 * @return The active trace set
112 */
113 public synchronized ITmfTrace[] getActiveTraceSet() {
114 final ITmfTrace trace = fCurrentTrace;
115 if (trace instanceof TmfExperiment) {
116 final TmfExperiment exp = (TmfExperiment) trace;
117 return exp.getTraces();
118 }
119 return new ITmfTrace[] { trace };
120 }
121
122 private TmfTraceContext getCurrentTraceContext() {
123 TmfTraceContext curCtx = fTraces.get(fCurrentTrace);
124 if (curCtx == null) {
125 /* There are no traces opened at the moment. */
126 return TmfTraceContext.NULL_CONTEXT;
127 }
128 return curCtx;
129 }
130
131 // ------------------------------------------------------------------------
132 // Signal handlers
133 // ------------------------------------------------------------------------
134
135 /**
136 * Signal handler for the traceOpened signal.
137 *
138 * @param signal
139 * The incoming signal
140 */
141 @TmfSignalHandler
142 public synchronized void traceOpened(final TmfTraceOpenedSignal signal) {
143 final ITmfTrace trace = signal.getTrace();
144 final ITmfTimestamp startTs = trace.getStartTime();
145
146 /* Calculate the initial time range */
147 final int SCALE = ITmfTimestamp.NANOSECOND_SCALE;
148 long offset = trace.getInitialRangeOffset().normalize(0, SCALE).getValue();
149 long endTime = startTs.normalize(0, SCALE).getValue() + offset;
150 final TmfTimeRange startTr = new TmfTimeRange(startTs, new TmfTimestamp(endTime, SCALE));
151
152 final TmfTraceContext startCtx = new TmfTraceContext(startTs, startTr);
153
154 fTraces.put(trace, startCtx);
155
156 /* We also want to set the newly-opened trace as the active trace */
157 fCurrentTrace = trace;
158 }
159
160
161 /**
162 * Handler for the TmfTraceSelectedSignal.
163 *
164 * @param signal
165 * The incoming signal
166 */
167 @TmfSignalHandler
168 public synchronized void traceSelected(final TmfTraceSelectedSignal signal) {
169 final ITmfTrace newTrace = signal.getTrace();
170 if (!fTraces.containsKey(newTrace)) {
171 throw new RuntimeException();
172 }
173 fCurrentTrace = newTrace;
174 }
175
176 /**
177 * Signal handler for the traceClosed signal.
178 *
179 * @param signal
180 * The incoming signal
181 */
182 @TmfSignalHandler
183 public synchronized void traceClosed(final TmfTraceClosedSignal signal) {
3fcf269e 184 fTraces.remove(signal.getTrace());
fc526aef
AM
185 if (fTraces.size() == 0) {
186 fCurrentTrace = null;
187 /*
188 * In other cases, we should receive a traceSelected signal that
189 * will indicate which trace is the new one.
190 */
191 }
192 }
193
194 /**
195 * Signal handler for the TmfTimeSynchSignal signal.
196 *
197 * The current time of *all* traces whose range contains the requested new
198 * time will be updated.
199 *
200 * @param signal
201 * The incoming signal
202 */
203 @TmfSignalHandler
204 public synchronized void timeUpdated(final TmfTimeSynchSignal signal) {
205 final ITmfTimestamp ts = signal.getCurrentTime();
206
207 for (Map.Entry<ITmfTrace, TmfTraceContext> entry : fTraces.entrySet()) {
208 final ITmfTrace trace = entry.getKey();
209 if (ts.intersects(getValidTimeRange(trace))) {
210 TmfTraceContext prevCtx = entry.getValue();
211 TmfTraceContext newCtx = new TmfTraceContext(prevCtx, ts);
212 entry.setValue(newCtx);
213 }
214 }
215 }
216
217 /**
218 * Signal handler for the TmfRangeSynchSignal signal.
219 *
220 * The current timestamp and timerange of *all* valid traces will be updated
221 * to the new requested times.
222 *
223 * @param signal
224 * The incoming signal
225 */
226 @TmfSignalHandler
227 public synchronized void timeRangeUpdated(final TmfRangeSynchSignal signal) {
228 final ITmfTimestamp signalTs = signal.getCurrentTime();
229
230 for (Map.Entry<ITmfTrace, TmfTraceContext> entry : fTraces.entrySet()) {
231 final ITmfTrace trace = entry.getKey();
232 final TmfTraceContext curCtx = entry.getValue();
233
234 final TmfTimeRange validTr = getValidTimeRange(trace);
235
236 /* Determine the new time stamp */
237 ITmfTimestamp newTs;
238 if (signalTs != null && signalTs.intersects(validTr)) {
239 newTs = signalTs;
240 } else {
241 newTs = curCtx.getTimestamp();
242 }
243
244 /* Determine the new time range */
245 TmfTimeRange targetTr = signal.getCurrentRange().getIntersection(validTr);
246 TmfTimeRange newTr = (targetTr == null ? curCtx.getTimerange() : targetTr);
247
248 /* Update the values */
249 TmfTraceContext newCtx = new TmfTraceContext(newTs, newTr);
250 entry.setValue(newCtx);
251 }
252 }
253
254 // ------------------------------------------------------------------------
255 // Utility methods
256 // ------------------------------------------------------------------------
257
258 /**
259 * Return the valid time range of a trace (not the "current time range", but
260 * the range of all possible valid timestamps).
261 *
262 * For a real trace this is the whole range of the trace. For an experiment,
263 * it goes from the start time of the earliest trace to the end time of the
264 * latest one.
265 *
266 * @param trace
267 * The trace to check for
268 * @return The valid time span, or 'null' if the trace is not valid
269 */
270 private TmfTimeRange getValidTimeRange(ITmfTrace trace) {
271 if (!fTraces.containsKey(trace)) {
272 /* Trace is not part of the currently opened traces */
273 return null;
274 }
275 if (!(trace instanceof TmfExperiment)) {
276 /* "trace" is a single trace, return its time range directly */
277 return trace.getTimeRange();
278 }
279 final ITmfTrace[] traces = ((TmfExperiment) trace).getTraces();
280 if (traces.length == 0) {
281 /* We are being trolled */
282 return null;
283 }
284 if (traces.length == 1) {
285 /* Trace is an experiment with only 1 trace */
286 return traces[0].getTimeRange();
287 }
288 /*
289 * Trace is an experiment with 2+ traces, so get the earliest start and
290 * the latest end.
291 */
292 ITmfTimestamp start = traces[0].getStartTime();
293 ITmfTimestamp end = traces[0].getEndTime();
294 for (int i = 1; i < traces.length; i++) {
295 ITmfTrace curTrace = traces[i];
296 if (curTrace.getStartTime().compareTo(start) < 0) {
297 start = curTrace.getStartTime();
298 }
299 if (curTrace.getEndTime().compareTo(end) > 0) {
300 end = curTrace.getEndTime();
301 }
302 }
303 return new TmfTimeRange(start, end);
304 }
305}
This page took 0.038405 seconds and 5 git commands to generate.