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.core.views.timegraph2.statesystem; | |
11 | ||
12 | import java.util.Collections; | |
13 | import java.util.List; | |
14 | import java.util.Map; | |
15 | import java.util.Set; | |
16 | import java.util.function.Function; | |
17 | import java.util.function.Supplier; | |
18 | import java.util.stream.Collectors; | |
19 | ||
20 | import org.eclipse.core.runtime.IProgressMonitor; | |
21 | import org.eclipse.jdt.annotation.NonNull; | |
22 | import org.eclipse.jdt.annotation.Nullable; | |
23 | import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.ColorDefinition; | |
24 | import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphModelRender; | |
25 | import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphModelRenderProvider; | |
26 | import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphStateInterval; | |
27 | import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphStateInterval.LineThickness; | |
28 | import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphTreeRender; | |
29 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; | |
30 | import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; | |
31 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; | |
32 | import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; | |
33 | import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; | |
34 | import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule; | |
35 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
36 | ||
37 | public abstract class StateSystemModelRenderProvider extends TimeGraphModelRenderProvider { | |
38 | ||
39 | /** | |
40 | * The context of a tree render. Should contain all the information to | |
41 | * generate the corresponding tree render, according to all configuration | |
42 | * options like sorting, filtering etc. specified by the user. | |
43 | */ | |
44 | protected static final class TreeRenderContext { | |
45 | ||
46 | public final ITmfStateSystem ss; | |
47 | public final SortingMode sortingMode; | |
48 | public final Set<FilterMode> filterModes; | |
49 | public final long renderTimeRangeStart; | |
50 | public final long renderTimeRangeEnd; | |
51 | public final List<ITmfStateInterval> fullQueryAtRangeStart; | |
52 | ||
53 | public TreeRenderContext(ITmfStateSystem ss, | |
54 | SortingMode sortingMode, | |
55 | Set<FilterMode> filterModes, | |
56 | long renderTimeRangeStart, | |
57 | long renderTimeRangeEnd, | |
58 | List<ITmfStateInterval> fullQueryAtRangeStart) { | |
59 | this.ss = ss; | |
60 | this.sortingMode = sortingMode; | |
61 | this.filterModes = filterModes; | |
62 | this.renderTimeRangeStart = renderTimeRangeStart; | |
63 | this.renderTimeRangeEnd = renderTimeRangeEnd; | |
64 | this.fullQueryAtRangeStart = fullQueryAtRangeStart; | |
65 | } | |
66 | } | |
67 | ||
68 | /** | |
69 | * The context of a single state interval. Should contain all the | |
70 | * information required to generate the state interval in the render (name, | |
71 | * color, etc.) | |
72 | */ | |
73 | protected static final class StateIntervalContext { | |
74 | ||
75 | public final ITmfStateSystem ss; | |
76 | public final StateSystemTimeGraphTreeElement baseTreeElement; | |
77 | public final ITmfStateInterval sourceInterval; | |
78 | public final List<ITmfStateInterval> fullQueryAtIntervalStart; | |
79 | ||
80 | public StateIntervalContext(ITmfStateSystem ss, | |
81 | StateSystemTimeGraphTreeElement baseTreeElement, | |
82 | ITmfStateInterval sourceInterval, | |
83 | List<ITmfStateInterval> fullQueryAtIntervalStart) { | |
84 | this.ss = ss; | |
85 | this.baseTreeElement = baseTreeElement; | |
86 | this.sourceInterval = sourceInterval; | |
87 | this.fullQueryAtIntervalStart = fullQueryAtIntervalStart; | |
88 | } | |
89 | } | |
90 | ||
91 | private final String fStateSystemModuleId; | |
92 | private final Function<TreeRenderContext, TimeGraphTreeRender> fTreeRenderFunction; | |
93 | private final Function<StateIntervalContext, TimeGraphStateInterval> fIntervalMappingFunction; | |
94 | ||
95 | // private final Map<ITmfStateSystem, TimeGraphTreeRender> fLastTreeRenders = new WeakHashMap<>(); | |
96 | ||
97 | /** | |
98 | * @param stateSystemModuleId | |
99 | * @param stateNameMappingFunction | |
100 | * @param colorMappingFunction | |
101 | * @param lineThicknessMappingFunction | |
102 | * @param propertyMappingFunction | |
103 | * @param baseQuarkPattern | |
104 | */ | |
105 | protected StateSystemModelRenderProvider( | |
106 | @Nullable List<SortingMode> sortingModes, | |
107 | @Nullable List<FilterMode> filterModes, | |
108 | String stateSystemModuleId, | |
109 | Function<TreeRenderContext, TimeGraphTreeRender> treeRenderFunction, | |
110 | Function<StateIntervalContext, String> stateNameMappingFunction, | |
111 | Function<StateIntervalContext, ColorDefinition> colorMappingFunction, | |
112 | Function<StateIntervalContext, LineThickness> lineThicknessMappingFunction, | |
113 | Function<StateIntervalContext, @Nullable Supplier<Map<String, String>>> propertyMappingFunction) { | |
114 | ||
115 | super(sortingModes, filterModes); | |
116 | ||
117 | fStateSystemModuleId = stateSystemModuleId; | |
118 | fTreeRenderFunction = treeRenderFunction; | |
119 | ||
120 | fIntervalMappingFunction = ssCtx -> { | |
121 | return new TimeGraphStateInterval( | |
122 | ssCtx.sourceInterval.getStartTime(), | |
123 | ssCtx.sourceInterval.getEndTime(), | |
124 | ssCtx.baseTreeElement, | |
125 | stateNameMappingFunction.apply(ssCtx), | |
126 | colorMappingFunction.apply(ssCtx), | |
127 | lineThicknessMappingFunction.apply(ssCtx), | |
128 | propertyMappingFunction.apply(ssCtx)); | |
129 | }; | |
130 | } | |
131 | ||
132 | private synchronized TimeGraphTreeRender getTreeRender(final ITmfStateSystem ss) { | |
133 | TimeGraphTreeRender lastRender = null; | |
134 | // TimeGraphTreeRender lastRender = fLastTreeRenders.get(ss); | |
135 | // if (lastRender != null && lastRender.getAllTreeElements().size() == ss.getNbAttributes()) { | |
136 | // /* The last render is still valid, we can re-use it */ | |
137 | // return lastRender; | |
138 | // } | |
139 | ||
140 | /* First generate the tree render context */ | |
141 | long start = getConfiguredTimeRangeStart(); | |
142 | long end = getConfiguredTimeRangeEnd(); | |
143 | List<ITmfStateInterval> fullStateAtStart; | |
144 | try { | |
145 | fullStateAtStart = ss.queryFullState(start); | |
146 | } catch (StateSystemDisposedException e) { | |
147 | return new TimeGraphTreeRender(Collections.EMPTY_LIST); | |
148 | } | |
149 | ||
150 | TreeRenderContext treeContext = new TreeRenderContext(ss, | |
151 | getCurrentSortingMode(), | |
152 | getActiveFilterModes(), | |
153 | start, | |
154 | end, | |
155 | fullStateAtStart); | |
156 | ||
157 | /* Generate a new tree render */ | |
158 | lastRender = fTreeRenderFunction.apply(treeContext); | |
159 | ||
160 | // fLastTreeRenders.put(ss, lastRender); | |
161 | return lastRender; | |
162 | } | |
163 | ||
164 | @Override | |
165 | public @NonNull TimeGraphModelRender getRender(ITmfTrace trace, long rangeStart, long rangeEnd, | |
166 | long resolution, @Nullable IProgressMonitor monitor) { | |
167 | // FIXME Potentially costly to query this every time, cache it? | |
168 | final ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(trace, fStateSystemModuleId); | |
169 | if (ss == null) { | |
170 | /* This trace does not provide the expected state system */ | |
171 | return TimeGraphModelRender.EMPTY_RENDER; | |
172 | } | |
173 | TimeGraphTreeRender treeRender = getTreeRender(ss); | |
174 | ||
175 | /* Prepare the state intervals */ | |
176 | /* | |
177 | * FIXME Inefficient series of queryHistoryRange() calls, replace with a | |
178 | * 2D query once those become available. | |
179 | */ | |
180 | List<List<TimeGraphStateInterval>> stateIntervals = treeRender.getAllTreeElements().stream() | |
181 | .map(treeElem -> (StateSystemTimeGraphTreeElement) treeElem) // FIXME, generic type? | |
182 | .map(treeElem -> { | |
183 | List<ITmfStateInterval> intervals; | |
184 | try { | |
185 | intervals = StateSystemUtils.queryHistoryRange(ss, treeElem.getSourceQuark(), rangeStart, rangeEnd, resolution, monitor); | |
186 | } catch (AttributeNotFoundException | StateSystemDisposedException e) { | |
187 | intervals = Collections.emptyList(); | |
188 | } | |
189 | return intervals.stream() | |
190 | .map(interval -> { | |
191 | List<ITmfStateInterval> fullState; | |
192 | try { | |
193 | fullState = ss.queryFullState(interval.getStartTime()); | |
194 | } catch (StateSystemDisposedException e) { | |
195 | fullState = Collections.emptyList(); | |
196 | } | |
197 | return new StateIntervalContext(ss, treeElem, interval, fullState); | |
198 | }) | |
199 | .map(fIntervalMappingFunction) | |
200 | .collect(Collectors.toList()); | |
201 | }) | |
202 | .collect(Collectors.toList()); | |
203 | ||
204 | /* TODO Prepare the drawn events */ | |
205 | ||
206 | /* TODO Prepare the arrows series */ | |
207 | ||
208 | TimeGraphModelRender render = new TimeGraphModelRender( | |
209 | rangeStart, rangeEnd, | |
210 | treeRender, | |
211 | stateIntervals, | |
212 | Collections.EMPTY_LIST, | |
213 | Collections.EMPTY_LIST); | |
214 | return render; | |
215 | } | |
216 | ||
217 | } |