Adapt views plugins to TMF
[deliverable/tracecompass.git] / tmf / org.lttng.scope.tmf2.views.core / src / org / lttng / scope / tmf2 / views / core / timegraph / model / provider / statesystem / StateSystemModelProvider.java
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.lttng.scope.tmf2.views.core.timegraph.model.provider.statesystem;
11
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15 import java.util.WeakHashMap;
16 import java.util.function.Function;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
21 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
22 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
23 import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
24 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
25 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.TimeGraphModelProvider;
26 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.arrows.ITimeGraphModelArrowProvider;
27 import org.lttng.scope.tmf2.views.core.timegraph.model.provider.states.ITimeGraphModelStateProvider;
28 import org.lttng.scope.tmf2.views.core.timegraph.model.render.tree.TimeGraphTreeRender;
29
30 /**
31 * Basic implementation of a {@link TimeGraphModelProvider} backed by a state
32 * system.
33 *
34 * @author Alexandre Montplaisir
35 */
36 public abstract class StateSystemModelProvider extends TimeGraphModelProvider {
37
38 /**
39 * The context of a tree render. Should contain all the information to
40 * generate the corresponding tree render, according to all configuration
41 * options like sorting, filtering etc. specified by the user.
42 */
43 protected static final class TreeRenderContext {
44
45 /** Trace name */
46 public final String traceName;
47 /** State system */
48 public final ITmfStateSystem ss;
49 /** Sorting mode */
50 public final SortingMode sortingMode;
51 /** Filter modes */
52 public final Set<FilterMode> filterModes;
53 /** Full query */
54 public final List<ITmfStateInterval> fullQueryAtRangeStart;
55
56 /**
57 * Constructor
58 *
59 * @param ss
60 * State system
61 * @param sortingMode
62 * Current sorting mode
63 * @param filterModes
64 * Current filter modes
65 * @param fullQueryAtRangeStart
66 * Full query at the start of the time range.
67 */
68 public TreeRenderContext(String traceName,
69 ITmfStateSystem ss,
70 SortingMode sortingMode,
71 Set<FilterMode> filterModes,
72 List<ITmfStateInterval> fullQueryAtRangeStart) {
73 this.traceName = traceName;
74 this.ss = ss;
75 this.sortingMode = sortingMode;
76 this.filterModes = filterModes;
77 this.fullQueryAtRangeStart = fullQueryAtRangeStart;
78 }
79 }
80
81 /**
82 * Class to encapsulate a cached {@link TimeGraphTreeRender}. This render
83 * should never change, except if the number of attributes in the state
84 * system does (for example, if queries were made before the state system
85 * was done building).
86 */
87 private static final class CachedTreeRender {
88
89 public final int nbAttributes;
90 public final TimeGraphTreeRender treeRender;
91
92 public CachedTreeRender(int nbAttributes, TimeGraphTreeRender treeRender) {
93 this.nbAttributes = nbAttributes;
94 this.treeRender = treeRender;
95 }
96 }
97
98 private final String fStateSystemModuleId;
99 private final Function<TreeRenderContext, TimeGraphTreeRender> fTreeRenderFunction;
100
101 private final Map<ITmfStateSystem, CachedTreeRender> fLastTreeRenders = new WeakHashMap<>();
102
103 private transient @Nullable ITmfStateSystem fStateSystem = null;
104
105 /**
106 * Constructor
107 *
108 * @param name
109 * The name of this provider
110 * @param sortingModes
111 * The available sorting modes
112 * @param filterModes
113 * The available filter modes
114 * @param stateProvider
115 * The state provider part of this model provider
116 * @param arrowProviders
117 * The arrow provider(s) supplied by this model provider
118 * @param stateSystemModuleId
119 * ID of the state system from which data will be fetched
120 * @param treeRenderFunction
121 * Function to generate a tree render for a given tree context
122 */
123 public StateSystemModelProvider(String name,
124 @Nullable List<SortingMode> sortingModes,
125 @Nullable List<FilterMode> filterModes,
126 ITimeGraphModelStateProvider stateProvider,
127 @Nullable List<ITimeGraphModelArrowProvider> arrowProviders,
128 String stateSystemModuleId,
129 Function<TreeRenderContext, TimeGraphTreeRender> treeRenderFunction) {
130
131 super(name, sortingModes, filterModes, stateProvider, arrowProviders);
132
133 fStateSystemModuleId = stateSystemModuleId;
134 fTreeRenderFunction = treeRenderFunction;
135
136 /*
137 * Change listener which will take care of keeping the target state
138 * system up to date.
139 */
140 traceProperty().addListener((obs, oldValue, newValue) -> {
141 ITmfTrace trace = newValue;
142 if (trace == null) {
143 fStateSystem = null;
144 return;
145 }
146
147 /*
148 * Set the state system in another thread, so that if it blocks on
149 * waitForInitialization, it does not block the application
150 * thread...
151 *
152 * FIXME We ought to get rid of this blocking in Jabberwocky.
153 */
154 Thread thread = new Thread(() -> {
155 fStateSystem = TmfStateSystemAnalysisModule.getStateSystem(trace, fStateSystemModuleId);
156 });
157 thread.start();
158 });
159 }
160
161 // ------------------------------------------------------------------------
162 // Render generation methods
163 // ------------------------------------------------------------------------
164
165 @Override
166 public @NonNull TimeGraphTreeRender getTreeRender() {
167 ITmfStateSystem ss = fStateSystem;
168 if (ss == null) {
169 /* This trace does not provide the expected state system */
170 return TimeGraphTreeRender.EMPTY_RENDER;
171 }
172
173 CachedTreeRender cachedRender = fLastTreeRenders.get(ss);
174 if (cachedRender != null && cachedRender.nbAttributes == ss.getNbAttributes()) {
175 /* The last render is still valid, we can re-use it */
176 return cachedRender.treeRender;
177 }
178
179 /* First generate the tree render context */
180 List<ITmfStateInterval> fullStateAtStart;
181 try {
182 fullStateAtStart = ss.queryFullState(ss.getStartTime());
183 } catch (StateSystemDisposedException e) {
184 return TimeGraphTreeRender.EMPTY_RENDER;
185 }
186
187 ITmfTrace trace = getTrace();
188 String traceName = (trace == null ? "" : trace.getName()); //$NON-NLS-1$
189
190 TreeRenderContext treeContext = new TreeRenderContext(traceName,
191 ss,
192 getCurrentSortingMode(),
193 getActiveFilterModes(),
194 fullStateAtStart);
195
196 /* Generate a new tree render */
197 TimeGraphTreeRender treeRender = fTreeRenderFunction.apply(treeContext);
198
199 fLastTreeRenders.put(ss, new CachedTreeRender(ss.getNbAttributes(), treeRender));
200 return treeRender;
201 }
202
203 }
This page took 0.034798 seconds and 5 git commands to generate.