[WIP] CFV Refactor
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / internal / provisional / tmf / core / views / timegraph2 / statesystem / StateSystemModelRenderProvider.java
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/views/timegraph2/statesystem/StateSystemModelRenderProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/views/timegraph2/statesystem/StateSystemModelRenderProvider.java
new file mode 100644 (file)
index 0000000..60ecb2f
--- /dev/null
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.statesystem;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.ColorDefinition;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphModelRender;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphModelRenderProvider;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphStateInterval;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphStateInterval.LineThickness;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.views.timegraph2.TimeGraphTreeRender;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
+import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+
+public abstract class StateSystemModelRenderProvider extends TimeGraphModelRenderProvider {
+
+    /**
+     * The context of a tree render. Should contain all the information to
+     * generate the corresponding tree render, according to all configuration
+     * options like sorting, filtering etc. specified by the user.
+     */
+    protected static final class TreeRenderContext {
+
+        public final ITmfStateSystem ss;
+        public final SortingMode sortingMode;
+        public final Set<FilterMode> filterModes;
+        public final long renderTimeRangeStart;
+        public final long renderTimeRangeEnd;
+        public final List<ITmfStateInterval> fullQueryAtRangeStart;
+
+        public TreeRenderContext(ITmfStateSystem ss,
+                SortingMode sortingMode,
+                Set<FilterMode> filterModes,
+                long renderTimeRangeStart,
+                long renderTimeRangeEnd,
+                List<ITmfStateInterval> fullQueryAtRangeStart) {
+            this.ss = ss;
+            this.sortingMode = sortingMode;
+            this.filterModes = filterModes;
+            this.renderTimeRangeStart = renderTimeRangeStart;
+            this.renderTimeRangeEnd = renderTimeRangeEnd;
+            this.fullQueryAtRangeStart = fullQueryAtRangeStart;
+        }
+    }
+
+    /**
+     * The context of a single state interval. Should contain all the
+     * information required to generate the state interval in the render (name,
+     * color, etc.)
+     */
+    protected static final class StateIntervalContext {
+
+        public final ITmfStateSystem ss;
+        public final StateSystemTimeGraphTreeElement baseTreeElement;
+        public final ITmfStateInterval sourceInterval;
+        public final List<ITmfStateInterval> fullQueryAtIntervalStart;
+
+        public StateIntervalContext(ITmfStateSystem ss,
+                StateSystemTimeGraphTreeElement baseTreeElement,
+                ITmfStateInterval sourceInterval,
+                List<ITmfStateInterval> fullQueryAtIntervalStart) {
+            this.ss = ss;
+            this.baseTreeElement = baseTreeElement;
+            this.sourceInterval = sourceInterval;
+            this.fullQueryAtIntervalStart = fullQueryAtIntervalStart;
+        }
+    }
+
+    private final String fStateSystemModuleId;
+    private final Function<TreeRenderContext, TimeGraphTreeRender> fTreeRenderFunction;
+    private final Function<StateIntervalContext, TimeGraphStateInterval> fIntervalMappingFunction;
+
+//    private final Map<ITmfStateSystem, TimeGraphTreeRender> fLastTreeRenders = new WeakHashMap<>();
+
+    /**
+     * @param stateSystemModuleId
+     * @param stateNameMappingFunction
+     * @param colorMappingFunction
+     * @param lineThicknessMappingFunction
+     * @param propertyMappingFunction
+     * @param baseQuarkPattern
+     */
+    protected StateSystemModelRenderProvider(
+            @Nullable List<SortingMode> sortingModes,
+            @Nullable List<FilterMode> filterModes,
+            String stateSystemModuleId,
+            Function<TreeRenderContext, TimeGraphTreeRender> treeRenderFunction,
+            Function<StateIntervalContext, String> stateNameMappingFunction,
+            Function<StateIntervalContext, ColorDefinition> colorMappingFunction,
+            Function<StateIntervalContext, LineThickness> lineThicknessMappingFunction,
+            Function<StateIntervalContext, @Nullable Supplier<Map<String, String>>> propertyMappingFunction) {
+
+        super(sortingModes, filterModes);
+
+        fStateSystemModuleId = stateSystemModuleId;
+        fTreeRenderFunction = treeRenderFunction;
+
+        fIntervalMappingFunction = ssCtx -> {
+            return new TimeGraphStateInterval(
+                    ssCtx.sourceInterval.getStartTime(),
+                    ssCtx.sourceInterval.getEndTime(),
+                    ssCtx.baseTreeElement,
+                    stateNameMappingFunction.apply(ssCtx),
+                    colorMappingFunction.apply(ssCtx),
+                    lineThicknessMappingFunction.apply(ssCtx),
+                    propertyMappingFunction.apply(ssCtx));
+        };
+    }
+
+    private synchronized TimeGraphTreeRender getTreeRender(final ITmfStateSystem ss) {
+        TimeGraphTreeRender lastRender = null;
+//        TimeGraphTreeRender lastRender = fLastTreeRenders.get(ss);
+//        if (lastRender != null && lastRender.getAllTreeElements().size() == ss.getNbAttributes()) {
+//            /* The last render is still valid, we can re-use it */
+//            return lastRender;
+//        }
+
+        /* First generate the tree render context */
+        long start = getConfiguredTimeRangeStart();
+        long end = getConfiguredTimeRangeEnd();
+        List<ITmfStateInterval> fullStateAtStart;
+        try {
+            fullStateAtStart = ss.queryFullState(start);
+        } catch (StateSystemDisposedException e) {
+            return new TimeGraphTreeRender(Collections.EMPTY_LIST);
+        }
+
+        TreeRenderContext treeContext = new TreeRenderContext(ss,
+                getCurrentSortingMode(),
+                getActiveFilterModes(),
+                start,
+                end,
+                fullStateAtStart);
+
+        /* Generate a new tree render */
+        lastRender = fTreeRenderFunction.apply(treeContext);
+
+//        fLastTreeRenders.put(ss, lastRender);
+        return lastRender;
+    }
+
+    @Override
+    public @NonNull TimeGraphModelRender getRender(ITmfTrace trace, long rangeStart, long rangeEnd,
+            long resolution, @Nullable IProgressMonitor monitor) {
+        // FIXME Potentially costly to query this every time, cache it?
+        final ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(trace, fStateSystemModuleId);
+        if (ss == null) {
+            /* This trace does not provide the expected state system */
+            return TimeGraphModelRender.EMPTY_RENDER;
+        }
+        TimeGraphTreeRender treeRender = getTreeRender(ss);
+
+        /* Prepare the state intervals */
+        /*
+         * FIXME Inefficient series of queryHistoryRange() calls, replace with a
+         * 2D query once those become available.
+         */
+        List<List<TimeGraphStateInterval>> stateIntervals = treeRender.getAllTreeElements().stream()
+            .map(treeElem -> (StateSystemTimeGraphTreeElement) treeElem) // FIXME, generic type?
+            .map(treeElem -> {
+                List<ITmfStateInterval> intervals;
+                try {
+                    intervals = StateSystemUtils.queryHistoryRange(ss, treeElem.getSourceQuark(), rangeStart, rangeEnd, resolution, monitor);
+                } catch (AttributeNotFoundException | StateSystemDisposedException e) {
+                    intervals = Collections.emptyList();
+                }
+                return intervals.stream()
+                    .map(interval -> {
+                        List<ITmfStateInterval> fullState;
+                        try {
+                            fullState = ss.queryFullState(interval.getStartTime());
+                        } catch (StateSystemDisposedException e) {
+                            fullState = Collections.emptyList();
+                        }
+                        return new StateIntervalContext(ss, treeElem, interval, fullState);
+                    })
+                    .map(fIntervalMappingFunction)
+                    .collect(Collectors.toList());
+            })
+            .collect(Collectors.toList());
+
+        /* TODO Prepare the drawn events */
+
+        /* TODO Prepare the arrows series */
+
+        TimeGraphModelRender render = new TimeGraphModelRender(
+                rangeStart, rangeEnd,
+                treeRender,
+                stateIntervals,
+                Collections.EMPTY_LIST,
+                Collections.EMPTY_LIST);
+        return render;
+    }
+
+}
This page took 0.031562 seconds and 5 git commands to generate.