Mercurial > hg > truffle
diff visualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java @ 4512:015fb895586b
Moved visualizer to new directory.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Tue, 07 Feb 2012 22:41:09 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java Tue Feb 07 22:41:09 2012 +0100 @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.graph; + +import com.sun.hotspot.igv.data.InputNode; +import com.sun.hotspot.igv.data.Properties; +import com.sun.hotspot.igv.data.Source; +import com.sun.hotspot.igv.layout.Vertex; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.List; +import java.util.*; + +/** + * + * @author Thomas Wuerthinger + */ +public class Figure extends Properties.Entity implements Source.Provider, Vertex { + + public static final int INSET = 12; + public static int SLOT_WIDTH = 12; + public static final int OVERLAPPING = 6; + public static final int SLOT_START = 4; + public static final int SLOT_OFFSET = 8; + public static final boolean VERTICAL_LAYOUT = true; + protected List<InputSlot> inputSlots; + protected List<OutputSlot> outputSlots; + private Source source; + private Diagram diagram; + private Point position; + private List<Figure> predecessors; + private List<Figure> successors; + private Color color; + private int id; + private String idString; + private String[] lines; + private int heightCash = -1; + private int widthCash = -1; + + public int getHeight() { + if (heightCash == -1) { + BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + Graphics g = image.getGraphics(); + g.setFont(diagram.getFont().deriveFont(Font.BOLD)); + FontMetrics metrics = g.getFontMetrics(); + String nodeText = diagram.getNodeText(); + heightCash = nodeText.split("\n").length * metrics.getHeight() + INSET; + } + return heightCash; + } + + public static <T> List<T> getAllBefore(List<T> inputList, T tIn) { + List<T> result = new ArrayList<>(); + for(T t : inputList) { + if(t.equals(tIn)) { + break; + } + result.add(t); + } + return result; + } + + public static int getSlotsWidth(Collection<? extends Slot> slots) { + int result = Figure.SLOT_OFFSET; + for(Slot s : slots) { + result += s.getWidth() + Figure.SLOT_OFFSET; + } + return result; + } + + public int getWidth() { + if (widthCash == -1) { + int max = 0; + BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + Graphics g = image.getGraphics(); + g.setFont(diagram.getFont().deriveFont(Font.BOLD)); + FontMetrics metrics = g.getFontMetrics(); + for (String s : getLines()) { + int cur = metrics.stringWidth(s); + if (cur > max) { + max = cur; + } + } + widthCash = max + INSET; + widthCash = Math.max(widthCash, Figure.getSlotsWidth(inputSlots)); + widthCash = Math.max(widthCash, Figure.getSlotsWidth(outputSlots)); + } + return widthCash; + } + + protected Figure(Diagram diagram, int id) { + this.diagram = diagram; + this.source = new Source(); + inputSlots = new ArrayList<>(5); + outputSlots = new ArrayList<>(1); + predecessors = new ArrayList<>(6); + successors = new ArrayList<>(6); + this.id = id; + idString = Integer.toString(id); + + this.position = new Point(0, 0); + this.color = Color.WHITE; + } + + public int getId() { + return id; + } + + public void setColor(Color color) { + this.color = color; + } + + public Color getColor() { + return color; + } + + public List<Figure> getPredecessors() { + return Collections.unmodifiableList(predecessors); + } + + public Set<Figure> getPredecessorSet() { + Set<Figure> result = new HashSet<>(); + for (Figure f : getPredecessors()) { + result.add(f); + } + return Collections.unmodifiableSet(result); + } + + public Set<Figure> getSuccessorSet() { + Set<Figure> result = new HashSet<>(); + for (Figure f : getSuccessors()) { + result.add(f); + } + return Collections.unmodifiableSet(result); + } + + public List<Figure> getSuccessors() { + return Collections.unmodifiableList(successors); + } + + protected void addPredecessor(Figure f) { + this.predecessors.add(f); + } + + protected void addSuccessor(Figure f) { + this.successors.add(f); + } + + protected void removePredecessor(Figure f) { + assert predecessors.contains(f); + predecessors.remove(f); + } + + protected void removeSuccessor(Figure f) { + assert successors.contains(f); + successors.remove(f); + } + + @Override + public void setPosition(Point p) { + this.position = p; + } + + @Override + public Point getPosition() { + return position; + } + + public Diagram getDiagram() { + return diagram; + } + + @Override + public Source getSource() { + return source; + } + + public InputSlot createInputSlot() { + InputSlot slot = new InputSlot(this, -1); + inputSlots.add(slot); + return slot; + } + + public InputSlot createInputSlot(int index) { + InputSlot slot = new InputSlot(this, index); + inputSlots.add(slot); + Collections.sort(inputSlots, Slot.slotIndexComparator); + return slot; + } + + public void removeSlot(Slot s) { + + assert inputSlots.contains(s) || outputSlots.contains(s); + + List<Connection> connections = new ArrayList<>(s.getConnections()); + for (Connection c : connections) { + c.remove(); + } + + if (inputSlots.contains(s)) { + inputSlots.remove(s); + } else if (outputSlots.contains(s)) { + outputSlots.remove(s); + } + } + + public OutputSlot createOutputSlot() { + OutputSlot slot = new OutputSlot(this, -1); + outputSlots.add(slot); + return slot; + } + + public OutputSlot createOutputSlot(int index) { + OutputSlot slot = new OutputSlot(this, index); + outputSlots.add(slot); + Collections.sort(outputSlots, Slot.slotIndexComparator); + return slot; + } + + public List<InputSlot> getInputSlots() { + return Collections.unmodifiableList(inputSlots); + } + + public Set<Slot> getSlots() { + Set<Slot> result = new HashSet<>(); + result.addAll(getInputSlots()); + result.addAll(getOutputSlots()); + return result; + } + + public List<OutputSlot> getOutputSlots() { + return Collections.unmodifiableList(outputSlots); + } + + void removeInputSlot(InputSlot s) { + s.removeAllConnections(); + inputSlots.remove(s); + } + + void removeOutputSlot(OutputSlot s) { + s.removeAllConnections(); + outputSlots.remove(s); + } + + public String[] getLines() { + if (lines == null) { + updateLines(); + } + return lines; + } + + public void updateLines() { + String[] strings = diagram.getNodeText().split("\n"); + String[] result = new String[strings.length]; + + for (int i = 0; i < strings.length; i++) { + result[i] = resolveString(strings[i], getProperties()); + } + + lines = result; + } + + public static final String resolveString(String string, Properties properties) { + + StringBuilder sb = new StringBuilder(); + boolean inBrackets = false; + StringBuilder curIdent = new StringBuilder(); + + for (int i = 0; i < string.length(); i++) { + char c = string.charAt(i); + if (inBrackets) { + if (c == ']') { + String value = properties.get(curIdent.toString()); + if (value == null) { + value = ""; + } + sb.append(value); + inBrackets = false; + } else { + curIdent.append(c); + } + } else { + if (c == '[') { + inBrackets = true; + curIdent = new StringBuilder(); + } else { + sb.append(c); + } + } + } + + return sb.toString(); + } + + @Override + public Dimension getSize() { + if (VERTICAL_LAYOUT) { + int width = Math.max(getWidth(), Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1)); + int height = getHeight() + 2 * Figure.SLOT_WIDTH - 2 * Figure.OVERLAPPING; + + + return new Dimension(width, height); + } else { + int width = getWidth() + 2 * Figure.SLOT_WIDTH - 2*Figure.OVERLAPPING; + int height = Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1); + return new Dimension(width, height); + } + } + + @Override + public String toString() { + return idString; + } + + @Override + public boolean isRoot() { + + List<InputNode> sourceNodes = source.getSourceNodes(); + if (sourceNodes.size() > 0 && sourceNodes.get(0).getProperties().get("name") != null) { + return source.getSourceNodes().get(0).getProperties().get("name").equals("Root"); + } else { + return false; + } + } + + @Override + public int compareTo(Vertex f) { + return toString().compareTo(f.toString()); + } + + public Rectangle getBounds() { + return new Rectangle(this.getPosition(), new Dimension(this.getWidth(), this.getHeight())); + } +}