input bus added to builder

This commit is contained in:
hneemann 2016-05-09 19:59:03 +02:00
parent 7a3b7c77db
commit 7b42d3e0f9
3 changed files with 97 additions and 16 deletions

View File

@ -4,8 +4,12 @@ import de.neemann.digital.analyse.expression.*;
import de.neemann.digital.core.basic.And; import de.neemann.digital.core.basic.And;
import de.neemann.digital.core.basic.Or; import de.neemann.digital.core.basic.Or;
import de.neemann.digital.core.element.Keys; import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.Rotation;
import de.neemann.digital.core.io.In;
import de.neemann.digital.core.io.Out; import de.neemann.digital.core.io.Out;
import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.elements.Wire;
import de.neemann.digital.draw.graphics.Vector; import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.shapes.ShapeFactory; import de.neemann.digital.draw.shapes.ShapeFactory;
@ -13,10 +17,13 @@ import de.neemann.digital.gui.Main;
import javax.swing.*; import javax.swing.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE; import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
/** /**
* Builder to create a circuit from an expression
*
* @author hneemann * @author hneemann
*/ */
public class Builder { public class Builder {
@ -25,14 +32,28 @@ public class Builder {
private final VariableVisitor variableVisitor; private final VariableVisitor variableVisitor;
private final ShapeFactory shapeFactory; private final ShapeFactory shapeFactory;
private int pos; private int pos;
private ArrayList<FragmentVariable> fragmentVariables;
/**
* Creates a new builder
*
* @param shapeFactory ShapeFactory used ti set to the created VisualElements
*/
public Builder(ShapeFactory shapeFactory) { public Builder(ShapeFactory shapeFactory) {
this.shapeFactory = shapeFactory; this.shapeFactory = shapeFactory;
circuit = new Circuit(); circuit = new Circuit();
variableVisitor = new VariableVisitor(); variableVisitor = new VariableVisitor();
fragmentVariables = new ArrayList<>();
} }
public Builder addCircuit(String name, Expression expression) { /**
* Adds an expression to the circuit
*
* @param name the output name
* @param expression the expression
* @return this for chained calls
*/
public Builder addExpression(String name, Expression expression) {
Fragment fr = createFragment(expression); Fragment fr = createFragment(expression);
fr = new FragmentExpression(fr, new FragmentVisualElement(Out.DESCRIPTION, shapeFactory).setAttr(Keys.LABEL, name)); fr = new FragmentExpression(fr, new FragmentVisualElement(Out.DESCRIPTION, shapeFactory).setAttr(Keys.LABEL, name));
@ -63,17 +84,66 @@ public class Builder {
throw new RuntimeException("nyi"); throw new RuntimeException("nyi");
} else if (expression instanceof Not) { } else if (expression instanceof Not) {
Not n = (Not) expression; Not n = (Not) expression;
return new FragmentExpression(createFragment(n.getExpression()), new FragmentVisualElement(de.neemann.digital.core.basic.Not.DESCRIPTION, shapeFactory)); if (n.getExpression() instanceof Variable) {
FragmentVariable fragmentVariable = new FragmentVariable((Variable) n.getExpression(), true);
fragmentVariables.add(fragmentVariable);
return fragmentVariable;
} else
return new FragmentExpression(createFragment(n.getExpression()), new FragmentVisualElement(de.neemann.digital.core.basic.Not.DESCRIPTION, shapeFactory));
} else if (expression instanceof Variable) { } else if (expression instanceof Variable) {
return new FragmentVariable(((Variable) expression)); FragmentVariable fragmentVariable = new FragmentVariable((Variable) expression, false);
fragmentVariables.add(fragmentVariable);
return fragmentVariable;
} else } else
throw new RuntimeException("nyi"); throw new RuntimeException("nyi");
} }
public Circuit getCircuit() { private void createInputBus() {
HashMap<String, Integer> varPos = new HashMap<>();
int dx = -variableVisitor.getVariables().size() * SIZE * 2;
for (Variable v : variableVisitor.getVariables()) {
VisualElement visualElement = new VisualElement(In.DESCRIPTION.getName()).setShapeFactory(shapeFactory);
visualElement.getElementAttributes()
.set(Keys.ROTATE, new Rotation(3))
.set(Keys.LABEL, v.getIdentifier());
visualElement.setPos(new Vector(dx, -SIZE * 5));
circuit.add(visualElement);
visualElement = new VisualElement(de.neemann.digital.core.basic.Not.DESCRIPTION.getName()).setShapeFactory(shapeFactory);
visualElement.getElementAttributes()
.set(Keys.ROTATE, new Rotation(3));
visualElement.setPos(new Vector(dx + SIZE, -SIZE * 3));
circuit.add(visualElement);
circuit.add(new Wire(new Vector(dx, -SIZE * 4), new Vector(dx + SIZE, -SIZE * 4)));
circuit.add(new Wire(new Vector(dx + SIZE, -SIZE * 3), new Vector(dx + SIZE, -SIZE * 4)));
circuit.add(new Wire(new Vector(dx, -SIZE * 5), new Vector(dx, pos)));
circuit.add(new Wire(new Vector(dx + SIZE, -SIZE), new Vector(dx + SIZE, pos)));
varPos.put(v.getIdentifier(), dx);
dx += SIZE * 2;
}
for (FragmentVariable f : fragmentVariables) {
Vector p = f.getCircuitPos();
int in = varPos.get(f.getVariable().getIdentifier());
if (f.isNeg()) in += SIZE;
circuit.add(new Wire(p, new Vector(in, p.y)));
}
}
/**
* Creates the circuit
*
* @return the circuit
*/
public Circuit createCircuit() {
createInputBus();
return circuit; return circuit;
} }
public static void main(String[] args) { public static void main(String[] args) {
Variable a = new Variable("A"); Variable a = new Variable("A");
Variable b = new Variable("B"); Variable b = new Variable("B");
@ -86,9 +156,9 @@ public class Builder {
Builder builder = new Builder(new ShapeFactory(new ElementLibrary())); Builder builder = new Builder(new ShapeFactory(new ElementLibrary()));
Circuit circuit = builder Circuit circuit = builder
.addCircuit("L", l) .addExpression("L", l)
.addCircuit("Y", y) .addExpression("Y", y)
.getCircuit(); .createCircuit();
SwingUtilities.invokeLater(() -> new Main(null, circuit).setVisible(true)); SwingUtilities.invokeLater(() -> new Main(null, circuit).setVisible(true));
} }

View File

@ -38,18 +38,12 @@ public class FragmentExpression implements Fragment {
@Override @Override
public Box doLayout() { public Box doLayout() {
int centerHeight = 0;
int height = 0; int height = 0;
int width = 0; int width = 0;
int centerIndex = fragments.size() / 2; for (FragmentHolder fr : fragments) {
for (int i = 0; i < fragments.size(); i++) {
FragmentHolder fr = fragments.get(i);
fr.fragment.setPos(new Vector(0, height)); fr.fragment.setPos(new Vector(0, height));
fr.box = fr.fragment.doLayout(); fr.box = fr.fragment.doLayout();
if (i == centerIndex)
centerHeight = height;
height += fr.box.getHeight(); height += fr.box.getHeight();
int w = fr.box.getWidth(); int w = fr.box.getWidth();
if (w > width) if (w > width)
@ -74,6 +68,7 @@ public class FragmentExpression implements Fragment {
merger.setPos(new Vector(width, raster((height - mergerBox.getHeight()) / 2))); merger.setPos(new Vector(width, raster((height - mergerBox.getHeight()) / 2)));
} else { } else {
// odd number of inputs // odd number of inputs
int centerIndex = fragments.size() / 2;
int y = fragments.get(centerIndex).fragment.getOutputs().get(0).y - centerIndex * SIZE; int y = fragments.get(centerIndex).fragment.getOutputs().get(0).y - centerIndex * SIZE;
merger.setPos(new Vector(width, y)); merger.setPos(new Vector(width, y));
} }
@ -138,7 +133,7 @@ public class FragmentExpression implements Fragment {
return Vector.add(merger.getOutputs(), pos); return Vector.add(merger.getOutputs(), pos);
} }
public boolean isLong() { private boolean isLong() {
return fragments.size() > 1; return fragments.size() > 1;
} }

View File

@ -12,10 +12,13 @@ import java.util.List;
*/ */
public class FragmentVariable implements Fragment { public class FragmentVariable implements Fragment {
private final Variable variable; private final Variable variable;
private final boolean neg;
private Vector pos; private Vector pos;
private Vector circuitPos;
public FragmentVariable(Variable variable) { public FragmentVariable(Variable variable, boolean neg) {
this.variable = variable; this.variable = variable;
this.neg = neg;
} }
@Override @Override
@ -30,6 +33,15 @@ public class FragmentVariable implements Fragment {
@Override @Override
public void addToCircuit(Vector pos, Circuit circuit) { public void addToCircuit(Vector pos, Circuit circuit) {
circuitPos = pos.add(this.pos);
}
public Vector getCircuitPos() {
return circuitPos;
}
public boolean isNeg() {
return neg;
} }
@Override @Override
@ -43,4 +55,8 @@ public class FragmentVariable implements Fragment {
o.add(pos); o.add(pos);
return o; return o;
} }
public Variable getVariable() {
return variable;
}
} }