mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-27 06:51:37 -04:00
Improved and documented the file import strategy.
This commit is contained in:
parent
c7b550a010
commit
8281f4dc61
@ -7,6 +7,7 @@ planned as v0.10
|
||||
- With the right mouse button you can now select and move/delete wires.
|
||||
- Added a real bidirectional switch and a relay.
|
||||
- Added N and P channel FETs and some CMOS examples
|
||||
- Improved and documented the file import strategy.
|
||||
|
||||
v0.9, released on 03. Feb 2017
|
||||
- improved documentation
|
||||
|
@ -160,7 +160,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
||||
try {
|
||||
description = elementNotFoundNotification.elementNotFound(file);
|
||||
} catch (IOException e) {
|
||||
throw new ElementNotFoundException(Lang.get("msg_errorImportingModel", elementName));
|
||||
throw new ElementNotFoundException(Lang.get("msg_errorImportingModel", elementName), e);
|
||||
}
|
||||
|
||||
if (description != null)
|
||||
|
@ -7,11 +7,21 @@ package de.neemann.digital.draw.library;
|
||||
*/
|
||||
public class ElementNotFoundException extends Exception {
|
||||
/**
|
||||
* Creates a new Iistance
|
||||
* Creates a new Instance
|
||||
*
|
||||
* @param message the error message
|
||||
*/
|
||||
public ElementNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Instance
|
||||
*
|
||||
* @param message the error message
|
||||
* @param cause the errors cause
|
||||
*/
|
||||
public ElementNotFoundException(String message, Exception cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,14 @@ public class MissingShape implements Shape {
|
||||
*/
|
||||
public MissingShape(String elementName, Exception cause) {
|
||||
this.message = Lang.get("msg_missingShape_N", elementName);
|
||||
this.cause = cause.getMessage();
|
||||
this.cause = getMessage(cause);
|
||||
}
|
||||
|
||||
private String getMessage(Throwable e) {
|
||||
String message = e.getMessage();
|
||||
if (e.getCause() != null)
|
||||
message += "; " + getMessage(e.getCause());
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,6 +22,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* The LibrarySelector is responsible for building the menu used to select items for adding them to the circuit.
|
||||
@ -38,6 +39,7 @@ public class LibrarySelector implements ElementNotFoundNotification {
|
||||
private InsertHistory insertHistory;
|
||||
private CircuitComponent circuitComponent;
|
||||
private ArrayList<ImportedItem> importedElements;
|
||||
private HashMap<String, File> treeFileMap;
|
||||
|
||||
/**
|
||||
* Creates a new library selector.
|
||||
@ -138,6 +140,7 @@ public class LibrarySelector implements ElementNotFoundNotification {
|
||||
* @param filePath the file path
|
||||
*/
|
||||
public void setFilePath(File filePath) {
|
||||
treeFileMap = null;
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
@ -149,7 +152,47 @@ public class LibrarySelector implements ElementNotFoundNotification {
|
||||
if (primary.exists())
|
||||
file = primary;
|
||||
|
||||
return importElement(file).description;
|
||||
// check if there is a file with the given name below the current directory
|
||||
// if so, load this file!
|
||||
File f = getFileFromTree(file.getName());
|
||||
if (f != null)
|
||||
return importElement(f).description;
|
||||
|
||||
// than check if the exact given file exists
|
||||
if (file.exists())
|
||||
return importElement(file).description;
|
||||
|
||||
// could not find the given file
|
||||
throw new IOException(Lang.get("err_couldNotFindIncludedFile_N0", file));
|
||||
}
|
||||
|
||||
private File getFileFromTree(String name) throws IOException {
|
||||
if (treeFileMap == null) {
|
||||
treeFileMap = new HashMap<>();
|
||||
populateTreeFileMap(treeFileMap, filePath);
|
||||
} else {
|
||||
if (!treeFileMap.containsKey(name)) { // if file not in map rescan folder
|
||||
treeFileMap.clear();
|
||||
populateTreeFileMap(treeFileMap, filePath);
|
||||
}
|
||||
}
|
||||
return treeFileMap.get(name);
|
||||
}
|
||||
|
||||
private void populateTreeFileMap(HashMap<String, File> map, File path) throws IOException {
|
||||
File[] list = path.listFiles();
|
||||
if (list != null) {
|
||||
for (File f : list) {
|
||||
final String name = f.getName();
|
||||
if (f.isFile() && name.endsWith(".dig")) {
|
||||
if (map.containsKey(name))
|
||||
throw new IOException(Lang.get("err_file_N0_ExistsTwiceBelow_N1", name, filePath));
|
||||
map.put(name, f);
|
||||
}
|
||||
if (f.isDirectory())
|
||||
populateTreeFileMap(map, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getActionName(ElementTypeDescription typeDescription) {
|
||||
|
@ -420,6 +420,8 @@ Zur Analyse können Sie die Schaltung im Gatterschrittmodus ausführen.</string>
|
||||
<string name="err_splitterAllowsOnlyOneHighZInput">Ein Splitter der hochohmige Eingänge erlaubt, kann nur einen Eingang haben!</string>
|
||||
<string name="err_couldNotCreateFolder_N0">Konnte den Order '{0}' nicht erzeugen!</string>
|
||||
<string name="err_switchHasNoNet">Ein Schalter kann nicht nur mit Eingängen verbunden werden.</string>
|
||||
<string name="err_file_N0_ExistsTwiceBelow_N1">Die Datei {0} existiert mehrfach unter {1}</string>
|
||||
<string name="err_couldNotFindIncludedFile_N0">Die Datei {0} konnte nicht gefunden werden.</string>
|
||||
|
||||
<string name="key_AddrBits">Adress-Bits</string>
|
||||
<string name="key_AddrBits_tt">Anzahl der Adress-Bits die verwendet werden.</string>
|
||||
|
@ -406,6 +406,8 @@ To analyse you can run the circuit in single gate step mode.</string>
|
||||
<string name="err_splitterAllowsOnlyOneHighZInput">A splitter which allows high z inputs can only have one input!</string>
|
||||
<string name="err_couldNotCreateFolder_N0">Could not create folder '{0}'!</string>
|
||||
<string name="err_switchHasNoNet">It is not allowed to connect only inputs to a switch.</string>
|
||||
<string name="err_file_N0_ExistsTwiceBelow_N1">The file {0} exists multiple times below {1}.</string>
|
||||
<string name="err_couldNotFindIncludedFile_N0">Could not find the file {0}.</string>
|
||||
|
||||
<string name="key_AddrBits">Address Bits</string>
|
||||
<string name="key_AddrBits_tt">Number of address bits used.</string>
|
||||
|
@ -99,6 +99,37 @@
|
||||
erzeugt wird.
|
||||
</par>
|
||||
</chapter>
|
||||
<chapter name="Dateinamen">
|
||||
<par>
|
||||
Um eine Schaltung in mehrere Teile zu zerlegen, die auch unabhängig z.B. in einem VCS abgelegt und verfolgt
|
||||
werden können, wird jede eingebundenen Schaltung in einer eigenen Datei gespeichert. Das hat zu Folge, dass in einer
|
||||
Schaltung nur die Dateinamen der Teilschaltungen gespeichert sind, und diese Dateien zur Laufzeit im Dateisystem
|
||||
gefunden werden müssen. Um die verschiedenen Arbeitsweisen der Nutzer bestmöglich zu unterstützen und dennoch
|
||||
auf eine komplexe Verwaltung von Importpfaden usw. zu verzichten, ist eine etwas ungewöhnliche Import-Strategie
|
||||
implementiert.
|
||||
</par>
|
||||
<par>
|
||||
In einer Schaltung sind die absoluten Pfade der eingebetteten Schaltungen gespeichert. Wenn diese Datei eingelesen
|
||||
werden soll, wird jedoch zunächst geprüft, ob sich eine Datei des gleichen Namens im Ordner der einbindenden Datei befindet.
|
||||
Ist das der Fall, wird diese Datei verwendet.
|
||||
</par>
|
||||
<par>
|
||||
Ist das nicht der Fall, werden alle Unterordner nach einer Datei des entsprechenden Namens durchsucht. Wird
|
||||
eine passende Datei gefunden, wird diese importiert. Dabei kommt es nur auf den Dateinamen der einzulesenden
|
||||
Datei an, nicht auf dessen Pfad. Entsprechend wird eine Fehlermeldung erzeugt, wenn sich in verschiedenen
|
||||
Unterordneren mehrere Dateien gleichen Namens befinden, da dann Mehrdeutigkeiten entstehen.
|
||||
</par>
|
||||
<par>
|
||||
Erst wenn bisher keine Datei gefunden wurde, wird der komplette absolute Pfad verwendet und es wird versucht,
|
||||
diese Datei zu importieren. Gelingt auch das nicht, wird eine Fehlermeldung erzeugt.
|
||||
</par>
|
||||
<par>
|
||||
Eine geeignete Projektstruktur sieht daher wie folgt aus: In einem eigenen Ordner befindet sich die Wurzelschaltung.
|
||||
Alle importierten Schaltungen sollte sin im selben Ordner oder in Unterordnern befinden. Alle Schaltungen sollten
|
||||
unterschiedliche Namen haben, es sollte also nicht vorkommen, dass sich in verschiedenen Ordnern Schaltungen
|
||||
gleichen Namens befinden.
|
||||
</par>
|
||||
</chapter>
|
||||
<chapter name="Häufig gestellte Fragen">
|
||||
<faq>
|
||||
<question>Wie kann ich eine Leitung verschieben?</question>
|
||||
|
@ -42,7 +42,6 @@
|
||||
circuit behave in exact the same way as if all components had been inserted at the same circuit level.
|
||||
</par>
|
||||
</chapter>
|
||||
|
||||
<chapter name="Wires">
|
||||
<par>
|
||||
All components must be connected via wires. It is not possible to connect two components to each other by
|
||||
@ -97,7 +96,35 @@
|
||||
circuit is not analyzed correctly, which means that an incorrect state transition table is generated.
|
||||
</par>
|
||||
</chapter>
|
||||
|
||||
<chapter name="File Names">
|
||||
<par>
|
||||
In order to decompose a circuit into several parts which are independent, e.g. can be stored and tracked in
|
||||
a VCS, each embedded circuit is stored in its own file. The result is that in a circuit only the file names
|
||||
of the subcircuits are stored, and these files must be found in the file system at runtime.
|
||||
In order to support the various work methods of the users as best as possible and still to avoid a complex
|
||||
administration of import paths, etc., a somewhat unusual import strategy is implemented.
|
||||
</par>
|
||||
<par>
|
||||
The absolute paths of the embedded circuits are stored in a circuits file. If a file is to be imported,
|
||||
however, it is first checked whether a file with the same name is located in the folder of the including
|
||||
file. If this is the case, this file is used.
|
||||
</par>
|
||||
<par>
|
||||
If this is not the case, all subfolders are searched for a file of the corresponding name.
|
||||
If a suitable file is found, it is imported. This process only depends on the file name of the file to be
|
||||
read, not on its path. Correspondingly, an error message is generated if there are several files of the
|
||||
same name in different subfolders, since ambiguities then arise.
|
||||
</par>
|
||||
<par>
|
||||
Only if no file has been found yet, the complete absolute path is used and an attempt is made to import
|
||||
this file. If this is not successful, an error message is generated.
|
||||
</par>
|
||||
<par>
|
||||
A suitable project structure therefore looks as follows: The root circuit is located in a separate folder.
|
||||
All imported circuits should be in the same folder or subfolders. All circuits should have different names,
|
||||
so it should not happen that there are circuits of the same name in different folders.
|
||||
</par>
|
||||
</chapter>
|
||||
<chapter name="Frequently asked Questions">
|
||||
<faq>
|
||||
<question>How to move a wire?</question>
|
||||
|
Loading…
x
Reference in New Issue
Block a user