/******************************************************************************* * Copyright (c) 2013, 2014 Ericsson and others. * 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 * * Contributors: * Marc Dumais (Ericsson) - Initial API and implementation (Bug 405390) * Marc Dumais (Ericsson) - Bug 407673 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.IVisualizerModelObject; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCPU; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCore; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerModel; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerThread; import org.eclipse.cdt.visualizer.ui.util.SelectionUtils; import org.eclipse.jface.viewers.ISelection; /** * White-list Filter for the graphical objects displayed in the multicore * visualizer canvas. */ public class MulticoreVisualizerCanvasFilter { /** white list of objects on which the filter is based */ List<IVisualizerModelObject> m_filterList = null; /** * the dynamically expanded list, containing elements in the * white list and their parents - recalculated as required * since some elements can move around and change parent */ List<IVisualizerModelObject> m_dynamicFilterList = null; /** reference to the canvas */ private MulticoreVisualizerCanvas m_canvas = null; /** whether the filter is active */ private boolean m_filterActive = false; /** counter that reflects the number of CPUs shown once the filter is applied */ private int m_shownCpu = 0; /** counter that reflects the number of cores shown once the filter is applied */ private int m_shownCore = 0; /** counter that reflects the number of threads shown once the filter is applied */ private int m_shownThread = 0; /** total number of CPUs in the current MV model */ private int m_totalCpu = 0; /** total number of cores in the current MV model */ private int m_totalCore = 0; /** total number of threads in the current MV model */ private int m_totalThread = 0; /** String constant used to denote that the filter is not active */ private static final String STR_FILTER_NOT_ACTIVE = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.NotActive.text"); //$NON-NLS-1$ /** String constant used to denote that the filter is active */ private static final String STR_FILTER_ACTIVE = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.Active.text"); //$NON-NLS-1$ /** String constant used to represent CPUs */ private static final String STR_CPU = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.cpu.text"); //$NON-NLS-1$ /** String constant used to represent cores */ private static final String STR_CORE = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.core.text"); //$NON-NLS-1$ /** String constant used to represent threads */ private static final String STR_THREAD = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.thread.text"); //$NON-NLS-1$ // --- constructors/destructors --- /** Constructor. */ public MulticoreVisualizerCanvasFilter(MulticoreVisualizerCanvas canvas) { m_canvas = canvas; } /** Dispose method */ public void dispose() { clearFilter(); m_canvas = null; } // --- filter methods --- /** * Sets-up a canvas white-list filter from the current canvas selection. * Any applicable selected objects are added to the filter. */ public void applyFilter() { // replace current filter? Clear old one first. if (isFilterActive()) { clearFilter(); } m_filterList = new ArrayList<IVisualizerModelObject>(); m_dynamicFilterList = new ArrayList<IVisualizerModelObject>(); m_filterActive = true; // get list of selected objects the filter applies-for ISelection selection = m_canvas.getSelection(); List<Object> selectedObjects = SelectionUtils.getSelectedObjects(selection); for (Object obj : selectedObjects) { if (obj instanceof IVisualizerModelObject) { m_filterList.add((IVisualizerModelObject)obj); } } } /** Removes any canvas filter currently in place */ public void clearFilter() { if (m_filterList != null) { m_filterList.clear(); m_filterList = null; } if (m_dynamicFilterList != null) { m_dynamicFilterList.clear(); m_dynamicFilterList = null; } resetCounters(); m_filterActive = false; } /** returns whether a canvas filter is currently in place */ public boolean isFilterActive() { return m_filterActive; } /** * Updates the dynamic filter so it contains the up-to-date parent objects */ public void updateFilter() { if (m_filterList == null || m_canvas == null) return; VisualizerModel model = m_canvas.getModel(); resetCounters(); m_dynamicFilterList.clear(); for (IVisualizerModelObject elem : m_filterList) { // element still in current model? if (isElementInCurrentModel(elem)) { // add element to list addElementToFilterList(elem); // also add all its ancestors IVisualizerModelObject parent; // Bug 407673 - if element is a thread, lookup the parent (core) // from the current model, to be sure it's up-to-date if (elem instanceof VisualizerThread && model != null) { parent = model.getThread(((VisualizerThread) elem).getGDBTID()).getParent(); } else { parent = elem.getParent(); } while (parent != null) { addElementToFilterList(parent); parent = parent.getParent(); } } } } /** * returns whether a candidate model object should be displayed, * according to the current filter. */ public boolean displayObject(final IVisualizerModelObject candidate) { // filter not active? Let anything be displayed if (!m_filterActive) { return true; } // Candidate is in white list? if (isElementInFilterList(candidate)) { return true; } return false; } // --- filter list management --- /** * Adds an element to the dynamic filter list, if an equivalent * element is not already in there. */ private void addElementToFilterList(final IVisualizerModelObject elem) { if (!isElementInFilterList(elem)) { m_dynamicFilterList.add(elem); stepStatsCounter(elem); } } /** * Returns whether an element already has an equivalent in the * dynamic filter list. */ private boolean isElementInFilterList(final IVisualizerModelObject candidate) { // is the candidate in the dynamic filter list? for (IVisualizerModelObject elem : m_dynamicFilterList) { // Note: we are comparing the content (IDs), not references. if (candidate.compareTo(elem) == 0) { return true; } } return false; } /** returns whether a model object currently in the filter still exists in * the current model. */ private boolean isElementInCurrentModel(IVisualizerModelObject element) { VisualizerModel model = m_canvas.getModel(); if (model != null) { if (element instanceof VisualizerThread) { VisualizerThread thread = model.getThread(((VisualizerThread) element).getGDBTID()); if (thread != null) { // Note: we are comparing the content (IDs), not references. if (thread.compareTo(element) == 0) { return true; } } } else if (element instanceof VisualizerCore) { VisualizerCore core = model.getCore(element.getID()); if (core != null) { // Note: we are comparing the content (IDs), not references. if (core.compareTo(element) == 0) { return true; } } } else if (element instanceof VisualizerCPU) { VisualizerCPU cpu = model.getCPU(element.getID()); if (cpu != null) { // Note: we are comparing the content (IDs), not references. if (cpu.compareTo(element) == 0) { return true; } } } } return false; } // --- Stats counters --- /** * Steps the filter counters for a given type of model object. */ private void stepStatsCounter(IVisualizerModelObject modelObj) { if (modelObj instanceof VisualizerCPU) { m_shownCpu++; } else if (modelObj instanceof VisualizerCore) { m_shownCore++; } else if (modelObj instanceof VisualizerThread) { m_shownThread++; } } /** Resets the filter counters */ private void resetCounters() { m_shownCpu = 0; m_shownCore = 0; m_shownThread = 0; // refresh total counts since the model can change if (m_canvas != null) { VisualizerModel model = m_canvas.getModel(); if (model != null) { m_totalCpu = model.getCPUCount(); m_totalCore = model.getCoreCount(); m_totalThread = model.getThreadCount(); } } } /** returns a String giving the current filtering stats */ private String getStats() { return STR_FILTER_ACTIVE + " " + STR_CPU + " " + m_shownCpu + "/" + m_totalCpu + ", " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ STR_CORE + " " + m_shownCore + "/" + m_totalCore + ", " + //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ STR_THREAD + " " + m_shownThread + "/" + m_totalThread; //$NON-NLS-1$//$NON-NLS-2$ } @Override public String toString() { if (isFilterActive()) { return getStats(); } else { return STR_FILTER_NOT_ACTIVE; } } }