fixes for netlist

This commit is contained in:
Bane Stojkovic
2025-03-11 23:18:36 +01:00
parent eedc370a6e
commit f966f8873a
5 changed files with 950 additions and 1025 deletions
@@ -1,381 +1,281 @@
/* /*
* *
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
* *
* This file is part of DIYLC. * This file is part of DIYLC.
* *
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation, either version 3 of the * General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version. * License, or (at your option) any later version.
* *
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * DIYLC 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 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. * Public License for more details.
* *
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see * You should have received a copy of the GNU General Public License along with DIYLC. If not, see
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
*/ */
package org.diylc.netlist; package org.diylc.netlist;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
public abstract class NetlistAnalyzer { public abstract class NetlistAnalyzer {
public NetlistAnalyzer() {} public NetlistAnalyzer() {
}
public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput) throws TreeException {
Map<String, Summary> summaries = new HashMap<String, Summary>(); public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput)
for (Netlist n : netlists) { throws TreeException {
Summary s = summarize(n, preferredOutput); Map<String, Summary> summaries = new HashMap<String, Summary>();
if (summaries.containsKey(s.getSummary())) for (Netlist n : netlists) {
summaries.get(s.getSummary()).append(n); Summary s = summarize(n, preferredOutput);
else if (summaries.containsKey(s.getSummary()))
summaries.put(s.getSummary(), s); summaries.get(s.getSummary()).append(n);
} else
summaries.put(s.getSummary(), s);
List<Summary> res = new ArrayList<Summary>(summaries.values()); }
Collections.sort(res);
return res; List<Summary> res = new ArrayList<Summary>(summaries.values());
} Collections.sort(res);
return res;
protected abstract Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException; }
public Tree constructTreeBetween(Netlist netlist, Node nodeA, Node nodeB) { protected abstract Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException;
Tree tree = new Tree(TreeConnectionType.Parallel);
connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series), new HashSet<Node>()); public Tree constructTreeBetween(Netlist netlist, Node nodeA, Node nodeB) {
Tree tree = new Tree(TreeConnectionType.Parallel);
return tree; connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series),
} new HashSet<Node>());
// protected Tree removeRedundantElements(Tree tree) { return tree;
// List<Tree> children = tree.getChildren() }
// .stream()
// .map(t -> removeRedundantElements(t)) protected void connectNodes(Netlist netlist, Node nodeA, Node nodeB, List<Tree> concurrentPaths,
// .collect(Collectors.toList()); Tree currentPath, Set<Node> visited) {
// if (children.size() == 1) { if (nodeA == nodeB) {
// Tree first = children.get(0); concurrentPaths.add(currentPath);
// return first; return;
// } }
// }
Group groupA = findGroup(netlist, nodeA);
protected void connectNodes(Netlist netlist, Node nodeA, Node nodeB, List<Tree> concurrentPaths, Tree currentPath, if (groupA == null)
Set<Node> visited) { return;
if (nodeA == nodeB) {
concurrentPaths.add(currentPath); if (groupA.getNodes().contains(nodeB)) {
return; concurrentPaths.add(currentPath);
} return;
}
Group groupA = findGroup(netlist, nodeA);
Set<Node> pathVisited = new HashSet<>(visited);
if (groupA == null) pathVisited.add(nodeA);
return;
// First collect all immediate next nodes and their paths
if (groupA.getNodes().contains(nodeB)) { Map<Node, List<Tree>> nextNodes = new HashMap<>();
concurrentPaths.add(currentPath); for (Node n : groupA.getNodes()) {
return; if (pathVisited.contains(n))
} continue;
// Only mark the current node as visited to allow proper path exploration IDIYComponent<?> c = n.getComponent();
visited.add(nodeA); for (int i = 0; i < c.getControlPointCount(); i++) {
int targetPoint = i;
List<Tree> newConcurrentPaths = new ArrayList<Tree>(); int sourcePoint = n.getPointIndex();
// Track processed connections to prevent duplicates from bidirectional links if (targetPoint == sourcePoint)
Set<String> processedConnections = new HashSet<String>(); continue;
for (Node n : groupA.getNodes()) { if (c.getInternalLinkName(targetPoint, sourcePoint) != null) {
IDIYComponent<?> c = n.getComponent(); Node newNodeA = new Node(c, targetPoint, n.getZIndex());
for (int i = 0; i < c.getControlPointCount(); i++) { if (pathVisited.contains(newNodeA))
int targetPoint = i; continue;
int sourcePoint = n.getPointIndex();
try {
// Skip self-connections Tree newPath = (Tree) currentPath.clone();
if (targetPoint == sourcePoint) continue; TreeLeaf leaf = new TreeLeaf(c, targetPoint, sourcePoint);
Tree newItem = new Tree(leaf);
// Check if there's a connection between these points
if (c.getInternalLinkName(targetPoint, sourcePoint) != null) { if (!newPath.getChildren().contains(newItem)) {
// Create a unique identifier for this connection regardless of direction newPath.getChildren().add(newItem);
String connectionId = c.getName() + "_" + nextNodes.computeIfAbsent(newNodeA, k -> new ArrayList<>()).add(newPath);
Math.min(sourcePoint, targetPoint) + "_" + }
Math.max(sourcePoint, targetPoint); } catch (CloneNotSupportedException e) {
// Skip this path if clone fails
// Skip if we've already processed this connection (prevents duplicate branches) }
if (processedConnections.contains(connectionId)) continue; }
processedConnections.add(connectionId); }
TreeLeaf l = new TreeLeaf(c, targetPoint, sourcePoint); }
Node newNodeA = new Node(c, targetPoint, n.getZIndex());
if (!visited.contains(newNodeA)) { // Now explore each next node
// visited.add(n); List<Tree> allPaths = new ArrayList<>();
Tree newCurrentPath = null; for (Map.Entry<Node, List<Tree>> entry : nextNodes.entrySet()) {
try { for (Tree path : entry.getValue()) {
newCurrentPath = (Tree) currentPath.clone(); List<Tree> branchPaths = new ArrayList<>();
} catch (CloneNotSupportedException e) { connectNodes(netlist, entry.getKey(), nodeB, branchPaths, path, pathVisited);
} allPaths.addAll(branchPaths);
Tree newItem = new Tree(l); }
if (!newCurrentPath.getChildren().contains(newItem)) }
newCurrentPath.getChildren().add(newItem);
// if (!currentPath.contains(l)) if (allPaths.isEmpty())
// newCurrentPath.add(l); return;
Set<Node> newVisited = new HashSet<Node>(visited);
connectNodes(netlist, newNodeA, nodeB, newConcurrentPaths, newCurrentPath, newVisited); if (allPaths.size() > 1) {
} // Find common prefix among all paths
} List<Tree> commonPrefix = findCommonElements(allPaths, true, false);
}
} // Create a new tree for the merged result
Tree mergedTree = new Tree(TreeConnectionType.Series);
if (newConcurrentPaths.size() == 0)
return; // Add common prefix elements
for (Tree prefixElement : commonPrefix) {
if (newConcurrentPaths.size() == 1) { mergedTree.getChildren().add(prefixElement);
if (newConcurrentPaths.get(0).getConnectionType() == TreeConnectionType.Series) { }
currentPath.getChildren().clear();
currentPath.getChildren().addAll(newConcurrentPaths.get(0).getChildren()); // Extract unique parts
} else { List<Tree> uniqueParts = new ArrayList<>();
currentPath.getChildren().add(newConcurrentPaths.get(0)); for (Tree path : allPaths) {
} Tree uniquePart = extractUniquePart(path, commonPrefix.size(), 0);
concurrentPaths.add(currentPath); if (uniquePart != null) {
return; if (uniquePart.getChildren().size() == 1) {
} uniqueParts.add(uniquePart.getChildren().get(0));
} else {
mergePaths(newConcurrentPaths, false); uniqueParts.add(uniquePart);
concurrentPaths.addAll(newConcurrentPaths); }
} }
}
/**
* Merges paths that share common elements, taking into account bidirectional connections. // Create parallel section for unique parts
* if (!uniqueParts.isEmpty()) {
* @param paths List of paths to merge Tree parallelSection = new Tree(TreeConnectionType.Parallel);
* @param backward Direction for merging (forward/backward) parallelSection.getChildren().addAll(uniqueParts);
*/
protected void mergePaths(List<Tree> paths, boolean backward) { // Add parallel section to series container
// Skip if there are no paths or only one path Tree parallelContainer = new Tree(TreeConnectionType.Series);
if (paths == null || paths.size() <= 1) { parallelContainer.getChildren().add(parallelSection);
return; mergedTree.getChildren().add(parallelContainer);
} }
Map<Tree, Integer> uniques = new HashMap<Tree, Integer>();
for (Tree t : paths) { concurrentPaths.add(mergedTree);
if (t.getConnectionType() != TreeConnectionType.Series) } else {
continue; concurrentPaths.add(allPaths.get(0));
Tree key = t.getChildren().get(backward ? t.getChildren().size() - 1 : 0); }
Integer count = uniques.get(key); }
uniques.put(key, count == null ? 1 : count + 1);
} private List<Tree> findCommonElements(List<Tree> paths, boolean fromStart, boolean backward) {
if (paths.isEmpty())
List<Tree> unmerged = new ArrayList<Tree>(paths); return new ArrayList<>();
for (Map.Entry<Tree, Integer> e : uniques.entrySet()) { List<Tree> common = new ArrayList<>();
if (e.getValue() > 1) { Tree template = paths.get(0);
List<Tree> pathsToMerge = new ArrayList<Tree>(); int maxLength = template.getChildren().size();
for (Tree t : paths) {
Tree key = t.getChildren().get(backward ? t.getChildren().size() - 1 : 0); for (int i = 0; i < maxLength; i++) {
if (key.equals(e.getKey())) int index = fromStart ?
pathsToMerge.add(t); (backward ? template.getChildren().size() - i - 1 : i) :
} (backward ? i : template.getChildren().size() - i - 1);
unmerged.removeAll(pathsToMerge);
if (index < 0 || index >= template.getChildren().size())
Tree jointStart = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series); break;
Tree jointFinish = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series);
Tree element = template.getChildren().get(index);
Tree unique = e.getKey(); boolean isCommon = true;
for (int i = 0; i < pathsToMerge.get(0).getChildren().size(); i++) { for (int j = 1; j < paths.size(); j++) {
boolean canMerge = true; Tree current = paths.get(j);
unique = pathsToMerge.get(0).getChildren().get(backward ? pathsToMerge.get(0).getChildren().size() - i - 1 : i); if (current.getChildren().size() <= i || index >= current.getChildren()
for (Tree t : pathsToMerge) { .size() || !current.getChildren().get(index).equals(element)) {
if (t.getChildren().size() <= i || !t.getChildren().get(backward ? t.getChildren().size() - i - 1 : i).equals(unique)) { isCommon = false;
canMerge = false; break;
break; }
} }
}
if (canMerge) if (isCommon) {
(backward ? jointFinish : jointStart).getChildren().add(unique); common.add(element);
else } else {
break; break;
} }
}
for (int i = 0; i < pathsToMerge.get(0).getChildren().size(); i++) {
boolean canMerge = true; return common;
unique = pathsToMerge.get(0).getChildren().get(backward ? i : pathsToMerge.get(0).getChildren().size() - i - 1); }
for (Tree t : pathsToMerge) {
// Fix: Correct index calculation to check the proper element in each path private Tree extractUniquePart(Tree path, int prefixSize, int suffixSize) {
if (t.getChildren().size() <= i || !t.getChildren().get(backward ? i : t.getChildren().size() - i - 1).equals(unique)) { if (path.getChildren().size() <= prefixSize + suffixSize)
canMerge = false; return null;
break;
} Tree uniquePart = new Tree(TreeConnectionType.Series);
} for (int i = prefixSize; i < path.getChildren().size() - suffixSize; i++) {
if (canMerge) uniquePart.getChildren().add(path.getChildren().get(i));
(backward ? jointStart : jointFinish).getChildren().add(unique); }
else
break; return uniquePart.getChildren().isEmpty() ? null : uniquePart;
} }
if (!jointStart.getChildren().isEmpty() || !jointFinish.getChildren().isEmpty()) { protected Group findGroup(Netlist netlist, Node node) {
Tree mergedTree = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series); for (Group g : netlist.getGroups())
Tree parallelSection = new Tree(new ArrayList<Tree>(pathsToMerge), TreeConnectionType.Parallel); if (g.getNodes().contains(node))
if (!jointStart.getChildren().isEmpty()) { return g;
mergedTree.getChildren().add(jointStart); return null;
for (Tree t : parallelSection.getChildren()) { }
t.trimChildrenLeft(jointStart.getChildren().size());
} protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist) {
} List<Node> res = new ArrayList<Node>();
mergedTree.getChildren().add(parallelSection); for (Group g : netlist.getGroups()) {
if (!jointFinish.getChildren().isEmpty()) { for (Node n : g.getNodes()) {
mergedTree.getChildren().add(jointFinish); if (typeNames.contains(n.getComponent().getClass()
for (Tree t : parallelSection.getChildren()) { .getCanonicalName()) && (nodeName == null || n.getDisplayName()
t.trimChildrenRight(jointFinish.getChildren().size()); .equalsIgnoreCase(nodeName))) {
} res.add(n);
} }
paths.removeAll(pathsToMerge); }
paths.add(mergedTree); }
} return res;
} }
}
public static List<Set<IDIYComponent<?>>> extractComponentGroups(List<Netlist> netlists) {
// try in the opposite direction for paths we haven't merged List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
if (!backward && !unmerged.isEmpty()) { for (Netlist n : netlists) {
paths.removeAll(unmerged); res.addAll(extractComponentGroups(n));
mergePaths(unmerged, true); }
paths.addAll(unmerged); return res;
} }
}
public static List<Set<IDIYComponent<?>>> extractComponentGroups(Netlist netlist) {
/** List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
* Creates a unique identifier for a connection between two points for (Group g : netlist.getGroups()) {
* that is the same regardless of the direction of connection. Set<IDIYComponent<?>> components = new HashSet<IDIYComponent<?>>();
* This helps prevent duplicate paths in bidirectional connections. for (Node n : g.getNodes())
* components.add(n.getComponent());
* @param component The component containing the connection res.add(components);
* @param point1 First point index }
* @param point2 Second point index return res;
* @return A direction-agnostic connection identifier }
*/
protected String createBidirectionalConnectionId(IDIYComponent<?> component, int point1, int point2) { protected int find(Node node, List<Group> groups) {
if (component == null) return null; for (int i = 0; i < groups.size(); i++)
if (groups.get(i).getNodes().contains(node))
// Always use min/max to ensure the same ID regardless of direction return i;
int minPoint = Math.min(point1, point2); return -1;
int maxPoint = Math.max(point1, point2); }
return component.getName() + "_" + minPoint + "_" + maxPoint; protected boolean intersect(List<Group> groups, Node node) {
} for (Group g : groups)
if (g.getNodes().contains(node))
/** return true;
* Compares two tree paths to check if they represent the same physical connection path return false;
* but possibly in reverse directions. This helps identify paths that should be merged }
* due to bidirectional connections.
* protected Node intersect(List<Group> groups, Group group) {
* @param path1 First path to compare for (Group g : groups)
* @param path2 Second path to compare for (Node node : group.getNodes())
* @return true if the paths represent the same physical connection (possibly in reverse order) if (g.getNodes().contains(node))
*/ return node;
protected boolean arePathsEquivalent(Tree path1, Tree path2) { return null;
if (path1 == null || path2 == null) return false; }
if (path1 == path2) return true; }
// Different connection types can't be equivalent
if (path1.getConnectionType() != path2.getConnectionType()) return false;
// Must have same number of elements
List<Tree> children1 = path1.getChildren();
List<Tree> children2 = path2.getChildren();
if (children1.size() != children2.size()) return false;
// Simple path with no children
if (children1.isEmpty()) return true;
// Check forward direction (standard comparison)
boolean forwardMatch = true;
for (int i = 0; i < children1.size(); i++) {
if (!children1.get(i).equals(children2.get(i))) {
forwardMatch = false;
break;
}
}
if (forwardMatch) return true;
// Check reverse direction (bidirectional check)
boolean reverseMatch = true;
for (int i = 0; i < children1.size(); i++) {
if (!children1.get(i).equals(children2.get(children2.size() - 1 - i))) {
reverseMatch = false;
break;
}
}
return reverseMatch;
}
protected Group findGroup(Netlist netlist, Node node) {
for (Group g : netlist.getGroups())
if (g.getNodes().contains(node))
return g;
return null;
}
protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist) {
List<Node> res = new ArrayList<Node>();
for (Group g : netlist.getGroups()) {
for (Node n : g.getNodes()) {
if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
&& (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
res.add(n);
}
}
}
return res;
}
protected String extractName(IDIYComponent<?> c) {
return c.getName() + " " + (c.getValueForDisplay() == null ? "" : c.getValueForDisplay());
}
public static List<Set<IDIYComponent<?>>> extractComponentGroups(List<Netlist> netlists) {
List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
for (Netlist n : netlists) {
res.addAll(extractComponentGroups(n));
}
return res;
}
public static List<Set<IDIYComponent<?>>> extractComponentGroups(Netlist netlist) {
List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
for (Group g : netlist.getGroups()) {
Set<IDIYComponent<?>> components = new HashSet<IDIYComponent<?>>();
for (Node n : g.getNodes())
components.add(n.getComponent());
res.add(components);
}
return res;
}
protected int find(Node node, List<Group> groups) {
for (int i = 0; i < groups.size(); i++)
if (groups.get(i).getNodes().contains(node))
return i;
return -1;
}
protected boolean intersect(List<Group> groups, Node node) {
for (Group g : groups)
if (g.getNodes().contains(node))
return true;
return false;
}
protected Node intersect(List<Group> groups, Group group) {
for (Group g : groups)
for (Node node : group.getNodes())
if (g.getNodes().contains(node))
return node;
return null;
}
}
@@ -1,332 +1,343 @@
/* /*
DIY Layout Creator (DIYLC). DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors. Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC. This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
DIYLC is distributed in the hope that it will be useful, DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>. along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.diylc.netlist; package org.diylc.netlist;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
public class Tree { public class Tree {
private List<Tree> children; private List<Tree> children;
private TreeConnectionType connectionType; private TreeConnectionType connectionType;
private TreeLeaf leaf; private TreeLeaf leaf;
public Tree(TreeConnectionType connectionType) { public Tree(TreeConnectionType connectionType) {
this.children = new ArrayList<Tree>(); this.children = new ArrayList<Tree>();
this.connectionType = connectionType; this.connectionType = connectionType;
} }
public Tree(TreeLeaf leaf) { public Tree(TreeLeaf leaf) {
this.leaf = leaf; this.leaf = leaf;
} }
public Tree(List<Tree> children, TreeConnectionType connectionType) { public Tree(List<Tree> children, TreeConnectionType connectionType) {
this.children = children; this.children = children;
this.connectionType = connectionType; this.connectionType = connectionType;
} }
public List<Tree> getChildren() { public List<Tree> getChildren() {
return children; return children;
} }
public void trimChildrenLeft(int count) { public void trimChildrenLeft(int count) {
children = children.subList(count, children.size()); children = children.subList(count, children.size());
} }
public void trimChildrenRight(int count) { public void trimChildrenRight(int count) {
children = children.subList(0, children.size() - count); children = children.subList(0, children.size() - count);
} }
public TreeConnectionType getConnectionType() { public TreeConnectionType getConnectionType() {
return connectionType; return connectionType;
} }
public TreeLeaf getLeaf() { public TreeLeaf getLeaf() {
return leaf; return leaf;
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((children == null) ? 0 : children.hashCode()); result = prime * result + ((children == null) ? 0 : children.hashCode());
result = prime * result + ((connectionType == null) ? 0 : connectionType.hashCode()); result = prime * result + ((connectionType == null) ? 0 : connectionType.hashCode());
result = prime * result + ((leaf == null) ? 0 : leaf.hashCode()); result = prime * result + ((leaf == null) ? 0 : leaf.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
return true; return true;
if (obj == null) if (obj == null)
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
Tree other = (Tree) obj; Tree other = (Tree) obj;
if (children == null) { if (children == null) {
if (other.children != null) if (other.children != null)
return false; return false;
} else if (!children.equals(other.children)) } else if (!children.equals(other.children))
return false; return false;
if (connectionType != other.connectionType) if (connectionType != other.connectionType)
return false; return false;
if (leaf == null) { if (leaf == null) {
if (other.leaf != null) if (other.leaf != null)
return false; return false;
} else if (!leaf.equals(other.leaf)) } else if (!leaf.equals(other.leaf))
return false; return false;
return true; return true;
} }
private List<Tree> getOrderedChildren() { private List<Tree> getOrderedChildren() {
if (getConnectionType() == TreeConnectionType.Series) if (getConnectionType() == TreeConnectionType.Series)
return children; return children;
List<Tree> ordered = new ArrayList<Tree>(children); List<Tree> ordered = new ArrayList<Tree>(children);
Collections.sort(ordered, new Comparator<Tree>() { Collections.sort(ordered, new Comparator<Tree>() {
@Override @Override
public int compare(Tree o1, Tree o2) { public int compare(Tree o1, Tree o2) {
return o1.toString().compareToIgnoreCase(o2.toString()); return o1.toString().compareToIgnoreCase(o2.toString());
}}); }
return ordered; });
} return ordered;
}
@Override
public String toString() { @Override
if (leaf != null) public String toString() {
return leaf.toString(); if (leaf != null)
return leaf.toString();
StringBuilder sb = new StringBuilder("(");
boolean first = true; // If we only have one child, no need for parentheses
for(Tree child : getOrderedChildren()) { if (children.size() == 1)
if (!first) return children.get(0).toString();
sb.append(" " ).append(connectionType).append(" ");
first = false; StringBuilder sb = new StringBuilder("(");
sb.append(child); boolean first = true;
} for (Tree child : getOrderedChildren()) {
sb.append(")"); if (!first)
return sb.toString(); sb.append(" ").append(connectionType).append(" ");
} first = false;
// Only include child's parentheses if it has multiple children with a different connection type
public String toHTML(int depth) { String childStr = child.toString();
if (leaf != null) if (child.children != null && child.children.size() > 1 && child.connectionType != connectionType) {
return leaf.toHTML(); sb.append(childStr);
} else {
List<Tree> children = getOrderedChildren(); sb.append(childStr.replaceAll("^\\((.*)\\)$", "$1"));
}
StringBuilder sb = new StringBuilder(); }
if (depth > 0 && children.size() > 1) sb.append(")");
sb.append("("); return sb.toString();
boolean first = true; }
for(Tree child : children) {
if (!first) { public String toHTML(int depth) {
sb.append("&nbsp;").append(connectionType.toHTML()).append("&nbsp;"); if (leaf != null)
if (depth == 0) return leaf.toHTML();
sb.append("<br>");
} List<Tree> children = getOrderedChildren();
first = false;
sb.append(child.toHTML(depth + children.size() > 1 ? 1 : 0)); StringBuilder sb = new StringBuilder();
} if (depth > 0 && children.size() > 1)
if (depth > 0 && children.size() > 1) sb.append("(");
sb.append(")"); boolean first = true;
return sb.toString(); for (Tree child : children) {
} if (!first) {
sb.append("&nbsp;").append(connectionType.toHTML()).append("&nbsp;");
public String toAsciiString() { if (depth == 0)
return String.join("<br>", toAscii()); sb.append("<br>");
} }
first = false;
private List<String> toAscii() { sb.append(child.toHTML(depth + children.size() > 1 ? 1 : 0));
if (leaf != null) { }
return Arrays.asList(TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1) + " " + leaf.toHTML() + " " + TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1)); if (depth > 0 && children.size() > 1)
} sb.append(")");
return sb.toString();
List<Tree> children = getOrderedChildren(); }
List<List<String>> childrenAscii = public String toAsciiString() {
children.stream().map(c -> c.toAscii()).collect(Collectors.toList()); return String.join("<br>", toAscii());
}
if (TreeConnectionType.Series.equals(connectionType)) {
return TreeAsciiUtil.concatenateMultiLineSerial(TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1), childrenAscii); private List<String> toAscii() {
} else { if (leaf != null) {
return TreeAsciiUtil.concatenateMultiLineParallel(childrenAscii); return Arrays.asList(TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH,
} 1) + " " + leaf.toHTML() + " " + TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1));
} }
@Override List<Tree> children = getOrderedChildren();
protected Object clone() throws CloneNotSupportedException {
if (leaf != null) List<List<String>> childrenAscii =
return new Tree(leaf); children.stream().map(c -> c.toAscii()).collect(Collectors.toList());
List<Tree> newChildren = new ArrayList<Tree>();
for (Tree t : children) if (TreeConnectionType.Series.equals(connectionType)) {
newChildren.add((Tree) t.clone()); return TreeAsciiUtil.concatenateMultiLineSerial(
return new Tree(newChildren, connectionType); TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1), childrenAscii);
} } else {
return TreeAsciiUtil.concatenateMultiLineParallel(childrenAscii);
public Tree filter(Set<String> types) { }
if (leaf != null) { }
if (types.contains(leaf.getComponent().getClass().getCanonicalName()))
return new Tree(leaf); @Override
return null; protected Object clone() throws CloneNotSupportedException {
} if (leaf != null)
List<Tree> newChildren = new ArrayList<Tree>(); return new Tree(leaf);
for (Tree t : children) { List<Tree> newChildren = new ArrayList<Tree>();
Tree child = t.filter(types); for (Tree t : children)
if (child != null) newChildren.add((Tree) t.clone());
newChildren.add(child); return new Tree(newChildren, connectionType);
} }
if (newChildren.isEmpty())
return null; public Tree filter(Set<String> types) {
return new Tree(newChildren, connectionType); if (leaf != null) {
} if (types.contains(leaf.getComponent().getClass().getCanonicalName()))
return new Tree(leaf);
public void walk(ITreeWalker walker) { return null;
if (leaf != null) { }
walker.visit(leaf); List<Tree> newChildren = new ArrayList<Tree>();
} else { for (Tree t : children) {
for (Tree t : children) { Tree child = t.filter(types);
walker.visit(t); if (child != null)
t.walk(walker); newChildren.add(child);
} }
} if (newChildren.isEmpty())
} return null;
return new Tree(newChildren, connectionType);
public Set<IDIYComponent<?>> extractComponents(Set<String> types) { }
Set<IDIYComponent<?>> res = new HashSet<IDIYComponent<?>>();
if (leaf != null && types.contains(leaf.getComponent().getClass().getCanonicalName())) { public void walk(ITreeWalker walker) {
res.add(leaf.getComponent()); if (leaf != null) {
} else if (children != null) { walker.visit(leaf);
for (Tree t : children) { } else {
Set<IDIYComponent<?>> childRes = t.extractComponents(types); for (Tree t : children) {
if (childRes != null) walker.visit(t);
res.addAll(childRes); t.walk(walker);
} }
} }
return res; }
}
public Set<IDIYComponent<?>> extractComponents(Set<String> types) {
public Tree locate(TreeLeaf l, boolean forceDirection) { Set<IDIYComponent<?>> res = new HashSet<IDIYComponent<?>>();
if (leaf != null && leaf.equals(l, forceDirection)) if (leaf != null && types.contains(leaf.getComponent().getClass().getCanonicalName())) {
return this; res.add(leaf.getComponent());
if (children != null) { } else if (children != null) {
for (Tree t : children) { for (Tree t : children) {
Tree childL = t.locate(l, forceDirection); Set<IDIYComponent<?>> childRes = t.extractComponents(types);
if (childL != null) { if (childRes != null)
// if (t.getLeaf() != null) res.addAll(childRes);
// return this; }
return childL; }
} return res;
} }
}
return null; public Tree locate(TreeLeaf l, boolean forceDirection) {
} if (leaf != null && leaf.equals(l, forceDirection))
return this;
public Tree findCommonParent(Tree t1, Tree t2) { if (children != null) {
if (t1 == null) for (Tree t : children) {
return t2; Tree childL = t.locate(l, forceDirection);
if (t2 == null) if (childL != null) {
return t1; // if (t.getLeaf() != null)
// return this;
if (children == null) return childL;
return null; }
}
if (!this.contains(t1) || !this.contains(t2)) }
return null; return null;
}
Tree p1 = this;
Tree p2 = this; public Tree findCommonParent(Tree t1, Tree t2) {
for (Tree c : children) { if (t1 == null)
if (c.contains(t1)) return t2;
p1 = c; if (t2 == null)
if (c.contains(t2)) return t1;
p2 = c;
} if (children == null)
return null;
if (p1 != p2 || p1 == this || p2 == this)
return this; if (!this.contains(t1) || !this.contains(t2))
return null;
return p1.findCommonParent(t1, t2);
} Tree p1 = this;
Tree p2 = this;
public Tree findCommonParent(List<Tree> t) { for (Tree c : children) {
if (t.contains(null)) if (c.contains(t1))
{ p1 = c;
while(t.contains(null)) if (c.contains(t2))
t.remove(null); p2 = c;
return findCommonParent(t); }
}
if (p1 != p2 || p1 == this || p2 == this)
if (t.size() == 0) return this;
return null;
if (t.size() == 1) return p1.findCommonParent(t1, t2);
return t.get(0); }
if (t.size() == 2)
return findCommonParent(t.get(0), t.get(1)); public Tree findCommonParent(List<Tree> t) {
if (t.contains(null)) {
List<Tree> remainder = t.subList(1, t.size()); while (t.contains(null))
return findCommonParent(t.get(0), findCommonParent(remainder)); t.remove(null);
} return findCommonParent(t);
}
public Tree findParent(Tree t) {
if (children == null) if (t.size() == 0)
return null; return null;
if (children.contains(t)) if (t.size() == 1)
return this; return t.get(0);
for (Tree c : children) if (t.size() == 2)
{ return findCommonParent(t.get(0), t.get(1));
Tree p = c.findParent(t);
if (p != null) List<Tree> remainder = t.subList(1, t.size());
return p; return findCommonParent(t.get(0), findCommonParent(remainder));
} }
return null;
} public Tree findParent(Tree t) {
if (children == null)
public boolean contains(Tree t) { return null;
if (this == t) if (children.contains(t))
return true; return this;
for (Tree c : children) {
if (children == null) Tree p = c.findParent(t);
return false; if (p != null)
if (children.contains(t)) return p;
return true; }
for (Tree c : children) return null;
if (c.contains(t)) }
return true;
return false; public boolean contains(Tree t) {
} if (this == t)
return true;
public interface ITreeWalker {
if (children == null)
void visit(Tree t); return false;
if (children.contains(t))
void visit(TreeLeaf l); return true;
} for (Tree c : children)
} if (c.contains(t))
return true;
return false;
}
public interface ITreeWalker {
void visit(Tree t);
void visit(TreeLeaf l);
}
}
@@ -137,27 +137,9 @@ public class Presenter implements IPlugInPort, IConfigListener {
private static final Logger LOG = Logger.getLogger(Presenter.class); private static final Logger LOG = Logger.getLogger(Presenter.class);
public static VersionNumber CURRENT_VERSION = new VersionNumber(4, 0, 0); public static VersionNumber CURRENT_VERSION = null;
public static List<Version> RECENT_VERSIONS = null; private static List<Version> RECENT_VERSIONS = null;
// Read the latest version from the local update.xml file
static {
try {
BufferedInputStream in = new BufferedInputStream(Presenter.class.getResourceAsStream("/update.xml"));
XStream xStream = new XStream(new DomDriver());
xStream.addPermission(AnyTypePermission.ANY);
@SuppressWarnings("unchecked")
List<Version> allVersions = (List<Version>) xStream.fromXML(in);
CURRENT_VERSION = allVersions.get(allVersions.size() - 1).getVersionNumber();
LOG.info("Current DIYLC version: " + CURRENT_VERSION);
RECENT_VERSIONS = allVersions.stream()
.sorted(Comparator.comparing(x -> ((Version)x).getVersionNumber()).reversed())
.limit(10)
.collect(Collectors.toList());
in.close();
} catch (Exception e) {
LOG.error("Could not find version number, using default", e);
}
}
public static final String DEFAULTS_KEY_PREFIX = "default."; public static final String DEFAULTS_KEY_PREFIX = "default.";
public static final List<IDIYComponent<?>> EMPTY_SELECTION = Collections.emptyList(); public static final List<IDIYComponent<?>> EMPTY_SELECTION = Collections.emptyList();
@@ -1091,11 +1073,39 @@ public class Presenter implements IPlugInPort, IConfigListener {
@Override @Override
public VersionNumber getCurrentVersionNumber() { public VersionNumber getCurrentVersionNumber() {
if (CURRENT_VERSION == null) {
List<Version> recentUpdates = getRecentUpdates();
CURRENT_VERSION = recentUpdates.stream()
.findFirst().map(v -> v.getVersionNumber())
.orElse(new VersionNumber(5, 0, 0));
LOG.info("Current DIYLC version: " + CURRENT_VERSION);
}
return CURRENT_VERSION; return CURRENT_VERSION;
} }
@Override @Override
public List<Version> getRecentUpdates() { public List<Version> getRecentUpdates() {
return getRecentVersions();
}
private static List<Version> getRecentVersions() {
if (RECENT_VERSIONS == null) {
try {
BufferedInputStream in =
new BufferedInputStream(Presenter.class.getResourceAsStream("/update.xml"));
XStream xStream = new XStream(new DomDriver());
xStream.addPermission(AnyTypePermission.ANY);
@SuppressWarnings("unchecked")
List<Version> allVersions = (List<Version>) xStream.fromXML(in);
RECENT_VERSIONS = allVersions.stream()
.sorted(Comparator.comparing(x -> ((Version) x).getVersionNumber()).reversed())
.limit(10).collect(Collectors.toList());
in.close();
} catch (Exception e) {
LOG.error("Could not load recent versions", e);
RECENT_VERSIONS = new ArrayList<>();
}
}
return RECENT_VERSIONS; return RECENT_VERSIONS;
} }
@@ -253,6 +253,10 @@
<changeType>IMPROVEMENT</changeType> <changeType>IMPROVEMENT</changeType>
<description>Upgraded source code structure to modern standards and introduced Maven</description> <description>Upgraded source code structure to modern standards and introduced Maven</description>
</org.diylc.appframework.update.Change> </org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Improved robustness of series/parallel graph construction code used in circuit analysis</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change> <org.diylc.appframework.update.Change>
<changeType>BUG_FIX</changeType> <changeType>BUG_FIX</changeType>
<description>Moving selected components with a mouse doesn't register file modification action and doesn't enable Undo action</description> <description>Moving selected components with a mouse doesn't register file modification action and doesn't enable Undo action</description>
@@ -1,291 +1,291 @@
///* /*
// * *
// * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
// * *
// * This file is part of DIYLC. * This file is part of DIYLC.
// * *
// * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
// * General Public License as published by the Free Software Foundation, either version 3 of the * General Public License as published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version. * License, or (at your option) any later version.
// * *
// * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * DIYLC 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 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// * Public License for more details. * Public License for more details.
// * *
// * You should have received a copy of the GNU General Public License along with DIYLC. If not, see * You should have received a copy of the GNU General Public License along with DIYLC. If not, see
// * <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
// * *
// */ */
//package org.diylc.netlist; package org.diylc.netlist;
//
//import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
//import java.util.Arrays; import java.util.Arrays;
//
//import org.junit.Test; import org.junit.Test;
//
//import org.diylc.components.electromechanical.OpenJack1_4; import org.diylc.components.electromechanical.OpenJack1_4;
//import org.diylc.components.guitar.HumbuckerPickup; import org.diylc.components.guitar.HumbuckerPickup;
//import org.diylc.components.guitar.SingleCoilPickup; import org.diylc.components.guitar.SingleCoilPickup;
//import org.diylc.components.passive.PotentiometerPanel; import org.diylc.components.passive.PotentiometerPanel;
//import org.diylc.components.passive.RadialCeramicDiskCapacitor; import org.diylc.components.passive.RadialCeramicDiskCapacitor;
//import org.diylc.netlist.Group; import org.diylc.netlist.Group;
//import org.diylc.netlist.GuitarDiagramAnalyzer; import org.diylc.netlist.GuitarDiagramAnalyzer;
//import org.diylc.netlist.Netlist; import org.diylc.netlist.Netlist;
//import org.diylc.netlist.Tree; import org.diylc.netlist.Tree;
//import org.diylc.netlist.TreeException; import org.diylc.netlist.TreeException;
//
//public class GuitarNetlistAnalyzerTests { public class GuitarNetlistAnalyzerTests {
//
// @Test @Test
// public void testOneSinglePickup() throws TreeException { public void testOneSinglePickup() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// SingleCoilPickup pickup = new SingleCoilPickup(); SingleCoilPickup pickup = new SingleCoilPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup, 1); Group tipGroup = new Group().connect(jack, 0).connect(pickup, 1);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2);
// netlist.add(tipGroup).add(sleeveGroup); netlist.add(tipGroup).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup.North<-))", s); assertEquals("Pickup.North<-", s);
// } }
//
// @Test @Test
// public void testOneSinglePickupVolPot() throws TreeException { public void testOneSinglePickupVolPot() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// SingleCoilPickup pickup = new SingleCoilPickup(); SingleCoilPickup pickup = new SingleCoilPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// PotentiometerPanel vol = new PotentiometerPanel(); PotentiometerPanel vol = new PotentiometerPanel();
// vol.setName("Volume"); vol.setName("Volume");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol));
// Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0); Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0);
// Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2);
// netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup); netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Volume.1-2 + Pickup.North<-) || (Volume.2-3))", s); assertEquals("((Volume.1-2 + Pickup.North<-) || Volume.2-3)", s);
// } }
//
// @Test @Test
// public void testOneSinglePickupVolTonePot() throws TreeException { public void testOneSinglePickupVolTonePot() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// SingleCoilPickup pickup = new SingleCoilPickup(); SingleCoilPickup pickup = new SingleCoilPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// PotentiometerPanel vol = new PotentiometerPanel(); PotentiometerPanel vol = new PotentiometerPanel();
// vol.setName("Volume"); vol.setName("Volume");
// PotentiometerPanel tone = new PotentiometerPanel(); PotentiometerPanel tone = new PotentiometerPanel();
// tone.setName("Tone"); tone.setName("Tone");
// RadialCeramicDiskCapacitor cap = new RadialCeramicDiskCapacitor(); RadialCeramicDiskCapacitor cap = new RadialCeramicDiskCapacitor();
// cap.setName("Cap"); cap.setName("Cap");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol, tone, cap)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol, tone, cap));
// Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(tone, 2); Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(tone, 2);
// Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
// Group sleeveGroup = Group sleeveGroup =
// new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2).connect(cap, 0); new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2).connect(cap, 0);
// Group toneGroup = new Group().connect(tone, 1).connect(cap, 1); Group toneGroup = new Group().connect(tone, 1).connect(cap, 1);
// netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup); netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("(((Volume.1-2) + ((Pickup.North<-) || (Tone.2-3 + Cap))) || (Volume.2-3))", s); assertEquals("((Volume.1-2 + (Tone.2-3 + Cap) || Pickup.North<-) || Volume.2-3)", s);
// } }
//
// @Test @Test
// public void testTwoSinglePickupsMasterVolSeparateTone() throws TreeException { public void testTwoSinglePickupsMasterVolSeparateTone() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// SingleCoilPickup pickup1 = new SingleCoilPickup(); SingleCoilPickup pickup1 = new SingleCoilPickup();
// pickup1.setName("Pickup1"); pickup1.setName("Pickup1");
// SingleCoilPickup pickup2 = new SingleCoilPickup(); SingleCoilPickup pickup2 = new SingleCoilPickup();
// pickup2.setName("Pickup2"); pickup2.setName("Pickup2");
// PotentiometerPanel vol = new PotentiometerPanel(); PotentiometerPanel vol = new PotentiometerPanel();
// vol.setName("Volume"); vol.setName("Volume");
// PotentiometerPanel tone1 = new PotentiometerPanel(); PotentiometerPanel tone1 = new PotentiometerPanel();
// tone1.setName("Tone1"); tone1.setName("Tone1");
// PotentiometerPanel tone2 = new PotentiometerPanel(); PotentiometerPanel tone2 = new PotentiometerPanel();
// tone2.setName("Tone2"); tone2.setName("Tone2");
// RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor(); RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor();
// cap1.setName("Cap1"); cap1.setName("Cap1");
// RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor(); RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor();
// cap2.setName("Cap2"); cap2.setName("Cap2");
// Netlist netlist = Netlist netlist =
// new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2)); new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2));
// Group hotGroup = new Group().connect(pickup1, 1).connect(vol, 0).connect(tone1, 2) Group hotGroup = new Group().connect(pickup1, 1).connect(vol, 0).connect(tone1, 2)
// .connect(pickup2, 1).connect(tone2, 2); .connect(pickup2, 1).connect(tone2, 2);
// Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 2) Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 2)
// .connect(vol, 2).connect(cap1, 0).connect(cap2, 0); .connect(vol, 2).connect(cap1, 0).connect(cap2, 0);
// Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1); Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1);
// Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1); Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1);
// netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group) netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group)
// .add(tone2Group); .add(tone2Group);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals( assertEquals(
// "(((Volume.1-2) + ((Pickup1.North<-) || (Pickup2.North<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || (Volume.2-3))", "((Volume.1-2 + (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2) || Pickup1.North<- || Pickup2.North<-) || Volume.2-3)",
// s); s);
// } }
//
// @Test @Test
// public void testOneSinglePickupReverse() throws TreeException { public void testOneSinglePickupReverse() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// SingleCoilPickup pickup = new SingleCoilPickup(); SingleCoilPickup pickup = new SingleCoilPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup, 2); Group tipGroup = new Group().connect(jack, 0).connect(pickup, 2);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1);
// netlist.add(tipGroup).add(sleeveGroup); netlist.add(tipGroup).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup.North->))", s); assertEquals("Pickup.North->", s);
// } }
//
// @Test @Test
// public void testOneHumbuckerSeries() throws TreeException { public void testOneHumbuckerSeries() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup = new HumbuckerPickup(); HumbuckerPickup pickup = new HumbuckerPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0); Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0);
// Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2); Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 3); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 3);
// netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup); netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup.North<- + Pickup.South<-))", s); assertEquals("(Pickup.North<- + Pickup.South<-)", s);
// } }
//
// @Test @Test
// public void testOneHumbuckerSeriesReverse() throws TreeException { public void testOneHumbuckerSeriesReverse() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup = new HumbuckerPickup(); HumbuckerPickup pickup = new HumbuckerPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup, 3); Group tipGroup = new Group().connect(jack, 0).connect(pickup, 3);
// Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2); Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 0); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 0);
// netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup); netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup.South-> + Pickup.North->))", s); assertEquals("(Pickup.South-> + Pickup.North->)", s);
// } }
//
// @Test @Test
// public void testOneHumbuckerParallel() throws TreeException { public void testOneHumbuckerParallel() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup = new HumbuckerPickup(); HumbuckerPickup pickup = new HumbuckerPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 2); Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 2);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 3); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 3);
// netlist.add(tipGroup).add(sleeveGroup); netlist.add(tipGroup).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup.North<-) || (Pickup.South<-))", s); assertEquals("(Pickup.North<- || Pickup.South<-)", s);
// } }
//
// @Test @Test
// public void testOneHumbuckerParallelOutOfPhase() throws TreeException { public void testOneHumbuckerParallelOutOfPhase() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup = new HumbuckerPickup(); HumbuckerPickup pickup = new HumbuckerPickup();
// pickup.setName("Pickup"); pickup.setName("Pickup");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 3); Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 3);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 2); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 2);
// netlist.add(tipGroup).add(sleeveGroup); netlist.add(tipGroup).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup.North<-) || (Pickup.South->))", s); assertEquals("(Pickup.North<- || Pickup.South->)", s);
// } }
//
// @Test @Test
// public void testTwoHumbuckersSeries() throws TreeException { public void testTwoHumbuckersSeries() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup1 = new HumbuckerPickup(); HumbuckerPickup pickup1 = new HumbuckerPickup();
// pickup1.setName("Pickup1"); pickup1.setName("Pickup1");
// HumbuckerPickup pickup2 = new HumbuckerPickup(); HumbuckerPickup pickup2 = new HumbuckerPickup();
// pickup2.setName("Pickup2"); pickup2.setName("Pickup2");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0); Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0);
// Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2); Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
// Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2); Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
// Group joinGroup = new Group().connect(pickup1, 3).connect(pickup2, 0); Group joinGroup = new Group().connect(pickup1, 3).connect(pickup2, 0);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup2, 3); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup2, 3);
// netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(joinGroup).add(sleeveGroup); netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(joinGroup).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup1.North<- + Pickup1.South<- + Pickup2.North<- + Pickup2.South<-))", s); assertEquals("(Pickup1.North<- + Pickup1.South<- + Pickup2.North<- + Pickup2.South<-)", s);
// } }
//
// @Test @Test
// public void testTwoHumbuckersParallel() throws TreeException { public void testTwoHumbuckersParallel() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup1 = new HumbuckerPickup(); HumbuckerPickup pickup1 = new HumbuckerPickup();
// pickup1.setName("Pickup1"); pickup1.setName("Pickup1");
// HumbuckerPickup pickup2 = new HumbuckerPickup(); HumbuckerPickup pickup2 = new HumbuckerPickup();
// pickup2.setName("Pickup2"); pickup2.setName("Pickup2");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 0); Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 0);
// Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2); Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
// Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2); Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3);
// netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup); netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-))", s); assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-))", s);
// } }
//
// @Test @Test
// public void testTwoHumbuckersParallelOutOfPhase() throws TreeException { public void testTwoHumbuckersParallelOutOfPhase() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup1 = new HumbuckerPickup(); HumbuckerPickup pickup1 = new HumbuckerPickup();
// pickup1.setName("Pickup1"); pickup1.setName("Pickup1");
// HumbuckerPickup pickup2 = new HumbuckerPickup(); HumbuckerPickup pickup2 = new HumbuckerPickup();
// pickup2.setName("Pickup2"); pickup2.setName("Pickup2");
// Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2)); Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2));
// Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 3); Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 3);
// Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2); Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
// Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2); Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 0); Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 0);
// netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup); netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.South-> + Pickup2.North->))", s); assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.South-> + Pickup2.North->))", s);
// } }
//
// @Test @Test
// public void testTwoHumbuckersMasterVolSeparateTone() throws TreeException { public void testTwoHumbuckersMasterVolSeparateTone() throws TreeException {
// OpenJack1_4 jack = new OpenJack1_4(); OpenJack1_4 jack = new OpenJack1_4();
// HumbuckerPickup pickup1 = new HumbuckerPickup(); HumbuckerPickup pickup1 = new HumbuckerPickup();
// pickup1.setName("Pickup1"); pickup1.setName("Pickup1");
// HumbuckerPickup pickup2 = new HumbuckerPickup(); HumbuckerPickup pickup2 = new HumbuckerPickup();
// pickup2.setName("Pickup2"); pickup2.setName("Pickup2");
// PotentiometerPanel vol = new PotentiometerPanel(); PotentiometerPanel vol = new PotentiometerPanel();
// vol.setName("Volume"); vol.setName("Volume");
// PotentiometerPanel tone1 = new PotentiometerPanel(); PotentiometerPanel tone1 = new PotentiometerPanel();
// tone1.setName("Tone1"); tone1.setName("Tone1");
// PotentiometerPanel tone2 = new PotentiometerPanel(); PotentiometerPanel tone2 = new PotentiometerPanel();
// tone2.setName("Tone2"); tone2.setName("Tone2");
// RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor(); RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor();
// cap1.setName("Cap1"); cap1.setName("Cap1");
// RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor(); RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor();
// cap2.setName("Cap2"); cap2.setName("Cap2");
// Netlist netlist = Netlist netlist =
// new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2)); new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2));
// Group hotGroup = new Group().connect(pickup1, 0).connect(vol, 0).connect(tone1, 2) Group hotGroup = new Group().connect(pickup1, 0).connect(vol, 0).connect(tone1, 2)
// .connect(pickup2, 0).connect(tone2, 2); .connect(pickup2, 0).connect(tone2, 2);
// Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); Group tipGroup = new Group().connect(jack, 0).connect(vol, 1);
// Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3) Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3)
// .connect(vol, 2).connect(cap1, 0).connect(cap2, 0); .connect(vol, 2).connect(cap1, 0).connect(cap2, 0);
// Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1); Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1);
// Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1); Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1);
// Group coilTap1 = new Group().connect(pickup1, 1).connect(pickup1, 2); Group coilTap1 = new Group().connect(pickup1, 1).connect(pickup1, 2);
// Group coilTap2 = new Group().connect(pickup2, 1).connect(pickup2, 2); Group coilTap2 = new Group().connect(pickup2, 1).connect(pickup2, 2);
// netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group) netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group)
// .add(tone2Group).add(coilTap1).add(coilTap2); .add(tone2Group).add(coilTap1).add(coilTap2);
// Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist);
// String s = tree.toString(); String s = tree.toString();
// assertEquals( assertEquals(
// "(((Volume.1-2) + ((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || (Volume.2-3))", "((Volume.1-2 + (Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2)) || Volume.2-3)",
// s); s);
// } }
//} }