allows simple generic circuits

This commit is contained in:
hneemann 2019-06-28 15:59:50 +02:00
parent 95865a1a05
commit 3bc8884b5c
6 changed files with 145 additions and 13 deletions

View File

@ -10,6 +10,7 @@ import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.library.CustomElement;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
@ -21,6 +22,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@ -31,18 +33,14 @@ import java.util.Map;
public class SubstituteLibrary implements LibraryInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(SubstituteLibrary.class);
private static final Map<String, SubstituteInterface> MAP = new HashMap<>();
private static final SubstituteInterface T_FF_WITH_ENABLE = new Substitute("T_FF_EN.dig");
private static final SubstituteInterface T_FF_WITHOUT_ENABLE = new Substitute("T_FF.dig");
static {
MAP.put("JK_FF", new Substitute("JK_FF.dig"));
MAP.put("T_FF", (attr, library) -> {
if (attr.get(Keys.WITH_ENABLE))
return T_FF_WITH_ENABLE.getElementType(attr, library);
else
return T_FF_WITHOUT_ENABLE.getElementType(attr, library);
});
MAP.put("Counter", new Substitute("Counter.dig"));
MAP.put("T_FF", new SubstituteMatching()
.add(attr -> attr.get(Keys.WITH_ENABLE), new Substitute("T_FF_EN.dig"))
.add(attr -> true, new Substitute("T_FF.dig"))
);
MAP.put("Counter", new SubstituteGenericBits("Counter.dig"));
}
private final ElementLibrary parent;
@ -75,6 +73,50 @@ public class SubstituteLibrary implements LibraryInterface {
ElementTypeDescription getElementType(ElementAttributes attr, ElementLibrary library) throws PinException, IOException;
}
private static final class SubstituteMatching implements SubstituteInterface {
private final ArrayList<Matcher> matcher;
private SubstituteMatching() {
matcher = new ArrayList<>();
}
private SubstituteMatching add(Accept accept, SubstituteInterface substituteInterface) {
matcher.add(new Matcher(accept, substituteInterface));
return this;
}
@Override
public ElementTypeDescription getElementType(ElementAttributes attr, ElementLibrary library) throws PinException, IOException {
for (Matcher m : matcher) {
ElementTypeDescription type = m.getElementType(attr, library);
if (type != null)
return type;
}
return null;
}
}
private static final class Matcher implements SubstituteInterface {
private final Accept accept;
private final SubstituteInterface substituteInterface;
private Matcher(Accept accept, SubstituteInterface substituteInterface) {
this.accept = accept;
this.substituteInterface = substituteInterface;
}
@Override
public ElementTypeDescription getElementType(ElementAttributes attr, ElementLibrary library) throws PinException, IOException {
if (accept.accept(attr))
return substituteInterface.getElementType(attr, library);
return null;
}
}
private interface Accept {
boolean accept(ElementAttributes attr);
}
private static final class Substitute implements SubstituteInterface {
private final String filename;
private ElementLibrary.ElementTypeDescriptionCustom typeDescriptionCustom;
@ -91,7 +133,7 @@ public class SubstituteLibrary implements LibraryInterface {
if (in == null)
throw new IOException("substituting failed: could not find file " + filename);
Circuit circuit = modify(Circuit.loadCircuit(in, library.getShapeFactory()));
Circuit circuit = Circuit.loadCircuit(in, library.getShapeFactory());
typeDescriptionCustom =
new ElementLibrary.ElementTypeDescriptionCustom(new File(filename),
@ -101,9 +143,56 @@ public class SubstituteLibrary implements LibraryInterface {
return typeDescriptionCustom;
}
private Circuit modify(Circuit circuit) {
return circuit;
}
}
private static abstract class SubstituteGeneric implements SubstituteInterface {
private final String filename;
private Circuit circuit;
private SubstituteGeneric(String filename) {
this.filename = filename;
}
@Override
public ElementTypeDescription getElementType(ElementAttributes attr, ElementLibrary library) throws PinException, IOException {
if (circuit == null) {
LOGGER.info("load substitute circuit " + filename);
InputStream in = getClass().getClassLoader().getResourceAsStream("analyser/" + filename);
if (in == null)
throw new IOException("substituting failed: could not find file " + filename);
circuit = Circuit.loadCircuit(in, library.getShapeFactory());
}
Circuit c = circuit.createDeepCopy();
generify(attr, c);
return new ElementLibrary.ElementTypeDescriptionCustom(new File(filename),
attributes -> new CustomElement(c, library),
c);
}
private void generify(ElementAttributes attr, Circuit circuit) {
for (VisualElement v : circuit.getElements()) {
String gen = v.getElementAttributes().get(Keys.GENERIC).trim();
if (!gen.isEmpty())
generify(attr, gen, v.getElementAttributes());
}
}
abstract void generify(ElementAttributes sourceAttributes, String gen, ElementAttributes nodeAttributes);
}
private static class SubstituteGenericBits extends SubstituteGeneric {
private SubstituteGenericBits(String filename) {
super(filename);
}
@Override
void generify(ElementAttributes sourceAttributes, String gen, ElementAttributes nodeAttributes) {
if (gen.equals("bits"))
nodeAttributes.setBits(sourceAttributes.getBits());
}
}
}

View File

@ -7,6 +7,7 @@ package de.neemann.digital.core.element;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.gui.Main;
import de.neemann.digital.lang.Lang;
import java.lang.reflect.Constructor;
@ -70,6 +71,8 @@ public class ElementTypeDescription {
if (p.getDirection() != PinDescription.Direction.input)
throw new RuntimeException("pin direction error");
attributeList = new ArrayList<>();
if (Main.isExperimentalMode())
attributeList.add(Keys.GENERIC);
}
/**

View File

@ -784,4 +784,10 @@ public final class Keys {
public static final Key<File> SETTINGS_TOOLCHAIN_CONFIG =
new Key.KeyFile("toolChainConfig", new File("")).setSecondary().setRequiresRestart();
/**
* Selects the midi channel
*/
public static final Key<String> GENERIC =
new Key<>("generic", "").allowGroupEdit();
}

View File

@ -44,6 +44,10 @@
<string>Bits</string>
<int>4</int>
</entry>
<entry>
<string>generic</string>
<string>bits</string>
</entry>
</elementAttributes>
<pos x="540" y="160"/>
</visualElement>
@ -68,6 +72,10 @@
<string>Bits</string>
<int>4</int>
</entry>
<entry>
<string>generic</string>
<string>bits</string>
</entry>
</elementAttributes>
<pos x="440" y="160"/>
</visualElement>
@ -78,6 +86,10 @@
<string>Bits</string>
<int>4</int>
</entry>
<entry>
<string>generic</string>
<string>bits</string>
</entry>
</elementAttributes>
<pos x="360" y="140"/>
</visualElement>
@ -88,6 +100,10 @@
<string>Bits</string>
<int>4</int>
</entry>
<entry>
<string>generic</string>
<string>bits</string>
</entry>
</elementAttributes>
<pos x="340" y="200"/>
</visualElement>
@ -98,6 +114,10 @@
<string>Bits</string>
<int>4</int>
</entry>
<entry>
<string>generic</string>
<string>bits</string>
</entry>
</elementAttributes>
<pos x="300" y="120"/>
</visualElement>
@ -108,6 +128,10 @@
<string>Bits</string>
<int>4</int>
</entry>
<entry>
<string>generic</string>
<string>bits</string>
</entry>
</elementAttributes>
<pos x="220" y="160"/>
</visualElement>
@ -123,6 +147,10 @@
<string>Bits</string>
<int>4</int>
</entry>
<entry>
<string>generic</string>
<string>bits</string>
</entry>
</elementAttributes>
<pos x="200" y="180"/>
</visualElement>

View File

@ -1341,6 +1341,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="key_toolChainConfig_tt">Kann für eine Integration einer externen Toolchain verwendet werden.
Erlaubt den Start externer Tools, um z.B. einen FPGA zu programmieren o.ä.</string>
<string name="key_generic">Generisch</string>
<string name="key_generic_tt">String für das Erzeugen generischer Schaltungen.</string>
<string name="mod_insertWire">Leitung eingefügt.</string>
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>
<string name="mod_setKey_N0_in_element_N1">Wert ''{0}'' in Element ''{1}'' verändert.</string>

View File

@ -1329,6 +1329,9 @@
<string name="key_toolChainConfig_tt">Used to configurate an integration of a toolchain.
Allows the start of external tools, e.g. to program an FPGA or similar.</string>
<string name="key_generic">Generic</string>
<string name="key_generic_tt">String used to create generic circuits.</string>
<string name="mod_insertWire">Inserted wire.</string>
<string name="mod_insertCopied">Insert from clipboard.</string>
<string name="mod_setKey_N0_in_element_N1">Value ''{0}'' in component ''{1}'' modified.</string>