tmf: Add periodic marker event source
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / markers / PeriodicMarkerEventSource.java
1 /*******************************************************************************
2 * Copyright (c) 2016 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 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.tmf.ui.markers;
14
15 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.Collections;
20 import java.util.List;
21
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.eclipse.swt.graphics.RGBA;
26 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
27 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEventSource;
28 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent;
29
30 /**
31 * Marker event source that produces periodic markers.
32 *
33 * @since 2.0
34 */
35 @NonNullByDefault
36 public class PeriodicMarkerEventSource implements IMarkerEventSource {
37
38 /**
39 * Reference marker time and index
40 */
41 public static class Reference {
42
43 /** Reference marker index 0 at time 0 */
44 public static final Reference ZERO = new Reference(0L, 0);
45
46 private final long time;
47 private final int index;
48
49 /**
50 * Constructor
51 *
52 * @param time
53 * the reference marker time in time units
54 * @param index
55 * the reference marker index
56 */
57 public Reference(long time, int index) {
58 this.time = time;
59 this.index = index;
60 }
61 }
62
63 private final String fCategory;
64 private final Reference fReference;
65 private final double fPeriod;
66 private final long fRollover;
67 private final RGBA fColor;
68 private final @Nullable RGBA fOddColor;
69 private final boolean fForeground;
70
71 /**
72 * Constructs a periodic marker event source with line markers at period
73 * boundaries.
74 * <p>
75 * The markers will have the given category and color. The reference defines
76 * the marker with the given index to be at the specified time.
77 *
78 * @param category
79 * the marker category
80 * @param reference
81 * the reference marker time and index
82 * @param period
83 * the period in time units
84 * @param rollover
85 * the number of periods before the index rolls-over to 0, or 0
86 * for no roll-over
87 * @param color
88 * the marker color
89 * @param foreground
90 * true if the marker is drawn in foreground, and false otherwise
91 */
92 public PeriodicMarkerEventSource(String category, Reference reference, double period, long rollover, RGBA color, boolean foreground) {
93 this(category, reference, period, rollover, foreground, color, null);
94 }
95
96 /**
97 * Constructs a periodic marker event source with alternating shading
98 * markers.
99 * <p>
100 * The markers will have the given category. Periods with even index will be
101 * shaded with the even color. Periods with odd index will be shaded with
102 * the odd color. The reference defines the marker with the given index to
103 * be at the specified time.
104 *
105 * @param category
106 * the marker category
107 * @param reference
108 * the reference marker time and index
109 * @param period
110 * the period in time units
111 * @param rollover
112 * the number of periods before the index rolls-over to 0, or 0
113 * for no roll-over
114 * @param evenColor
115 * the even marker color
116 * @param oddColor
117 * the odd marker color
118 * @param foreground
119 * true if the marker is drawn in foreground, and false otherwise
120 */
121 public PeriodicMarkerEventSource(String category, Reference reference, double period, long rollover, RGBA evenColor, RGBA oddColor, boolean foreground) {
122 this(category, reference, period, rollover, foreground, evenColor, oddColor);
123 }
124
125 /* Private constructor. The order of parameters is changed to make it unique. */
126 private PeriodicMarkerEventSource(String category, Reference reference, double period, long rollover, boolean foreground, RGBA evenColor, @Nullable RGBA oddColor) {
127 if (period <= 0) {
128 throw new IllegalArgumentException("period cannot be less than or equal to zero"); //$NON-NLS-1$
129 }
130 if (rollover < 0) {
131 throw new IllegalArgumentException("rollover cannot be less than zero"); //$NON-NLS-1$
132 }
133 fCategory = category;
134 fReference = reference;
135 fPeriod = period;
136 fRollover = rollover;
137 fColor = evenColor;
138 fOddColor = oddColor;
139 fForeground = foreground;
140 }
141
142 @Override
143 public List<String> getMarkerCategories() {
144 return Arrays.asList(fCategory);
145 }
146
147 @Override
148 public List<IMarkerEvent> getMarkerList(String category, long startTime, long endTime, long resolution, IProgressMonitor monitor) {
149 if (startTime > endTime) {
150 return Collections.emptyList();
151 }
152 List<IMarkerEvent> markers = new ArrayList<>();
153 long time = startTime;
154 if (Math.round((Math.round((time - fReference.time) / fPeriod)) * fPeriod + fReference.time) >= time) {
155 /* Subtract one period to ensure previous marker is included */
156 time -= fPeriod;
157 }
158 while (true) {
159 long index = Math.round((time - fReference.time) / fPeriod) + fReference.index;
160 time = Math.round((index - fReference.index) * fPeriod) + fReference.time;
161 long labelIndex = index;
162 if (fRollover != 0) {
163 labelIndex %= fRollover;
164 if (labelIndex < 0) {
165 labelIndex += fRollover;
166 }
167 }
168 if (fOddColor == null) {
169 markers.add(new MarkerEvent(null, time, 0, fCategory, fColor, getMarkerLabel(labelIndex), fForeground));
170 } else {
171 RGBA color = index % 2 == 0 ? fColor : fOddColor;
172 long duration = Math.round((index + 1 - fReference.index) * fPeriod + fReference.time) - time;
173 markers.add(new MarkerEvent(null, time, duration, fCategory, color, getMarkerLabel(labelIndex), fForeground));
174 }
175 if (time > endTime) {
176 /* The next marker out of range is included */
177 break;
178 }
179 time += Math.max(fPeriod, resolution);
180 }
181 return markers;
182 }
183
184 /**
185 * Get the marker label for the given marker index.
186 * <p>
187 * This method can be overridden by clients.
188 *
189 * @param index
190 * the marker index
191 * @return the marker label
192 */
193 public String getMarkerLabel(long index) {
194 return checkNotNull(Long.toString(index));
195 }
196 }
This page took 0.034084 seconds and 5 git commands to generate.