mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
Datasheet functionality added
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import javax.swing.Icon;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
@@ -52,6 +53,8 @@ public class ComponentType implements Serializable {
|
||||
private KeywordPolicy keywordPolicy;
|
||||
private String keywordTag;
|
||||
private boolean enableCache;
|
||||
private List<String[]> datasheet;
|
||||
private int datasheetCreationStepCount;
|
||||
|
||||
public ComponentType() {
|
||||
}
|
||||
@@ -59,7 +62,8 @@ public class ComponentType implements Serializable {
|
||||
public ComponentType(String name, String description, CreationMethod creationMethod, String category,
|
||||
String namePrefix, String author, Icon icon, Class<? extends IDIYComponent<?>> instanceClass, double zOrder,
|
||||
boolean flexibleZOrder, BomPolicy bomPolicy, boolean autoEdit, IComponentTransformer transformer,
|
||||
KeywordPolicy keywordPolicy, String keywordTag, boolean enableCache) {
|
||||
KeywordPolicy keywordPolicy, String keywordTag, boolean enableCache, List<String[]> datasheet,
|
||||
int datasheetCreationStepCount) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
@@ -77,6 +81,8 @@ public class ComponentType implements Serializable {
|
||||
this.keywordPolicy = keywordPolicy;
|
||||
this.keywordTag = keywordTag;
|
||||
this.enableCache = enableCache;
|
||||
this.datasheet = datasheet;
|
||||
this.datasheetCreationStepCount = datasheetCreationStepCount;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -142,6 +148,14 @@ public class ComponentType implements Serializable {
|
||||
public boolean getEnableCache() {
|
||||
return enableCache;
|
||||
}
|
||||
|
||||
public List<String[]> getDatasheet() {
|
||||
return datasheet;
|
||||
}
|
||||
|
||||
public int getDatasheetCreationStepCount() {
|
||||
return datasheetCreationStepCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -308,10 +308,11 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
* component.
|
||||
*
|
||||
* @param componentType
|
||||
* @param template
|
||||
* @param template optional
|
||||
* @param parameters optional
|
||||
* @param forceInstatiate
|
||||
*/
|
||||
void setNewComponentTypeSlot(ComponentType componentType, Template template, boolean forceInstatiate);
|
||||
void setNewComponentTypeSlot(ComponentType componentType, Template template, String[] parameters, boolean forceInstatiate);
|
||||
|
||||
/**
|
||||
* Locks or unlocks the specified layer. All components within +- 0.5 range will be affected by
|
||||
|
||||
@@ -114,5 +114,17 @@ public @interface ComponentDescriptor {
|
||||
/**
|
||||
* @return true if the component drawing should be cached
|
||||
*/
|
||||
boolean enableCache() default false;
|
||||
boolean enableCache() default false;
|
||||
|
||||
/**
|
||||
* @return true if component datasheet should be loaded from the corresponding file
|
||||
*/
|
||||
boolean enableDatasheet() default false;
|
||||
|
||||
/**
|
||||
* If datasheet is enabled, this property determines how many columns define a component, e.g. in how many steps we can instantiate a component
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int datasheetCreationStepCount() default 0;
|
||||
}
|
||||
|
||||
@@ -49,5 +49,11 @@ public class Capacitance extends AbstractMeasure<CapacitanceUnit> {
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse capacitance: " + value);
|
||||
}
|
||||
|
||||
public Double getNormalizedValue() {
|
||||
if (value == null || unit == null)
|
||||
return null;
|
||||
return value * unit.getFactor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ package org.diylc.core.measures;
|
||||
|
||||
public enum CapacitanceUnit implements Unit {
|
||||
|
||||
pF(1, "pF"), nF(1e3, "nF"), uF(1e6, "uF"), mF(1e9, "mF"), F(1e12, "F");
|
||||
pF(1e-6, "pF"), nF(1e-3, "nF"), uF(1, "uF"), mF(1e3, "mF"), F(1e6, "F");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
@@ -49,5 +49,11 @@ public class Voltage extends AbstractMeasure<VoltageUnit> {
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse voltage: " + value);
|
||||
}
|
||||
|
||||
public Double getNormalizedValue() {
|
||||
if (value == null || unit == null)
|
||||
return null;
|
||||
return value * unit.getFactor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,10 @@ public class ComponentProcessor {
|
||||
boolean cacheDrawing;
|
||||
IComponentTransformer transformer;
|
||||
KeywordPolicy keywordPolicy;
|
||||
String keywordTag;
|
||||
String keywordTag;
|
||||
List<String[]> datasheet = null;
|
||||
int datasheetCreationStepCount = 0;
|
||||
|
||||
if (clazz.isAnnotationPresent(ComponentDescriptor.class)) {
|
||||
ComponentDescriptor annotation = clazz.getAnnotation(ComponentDescriptor.class);
|
||||
name = annotation.name();
|
||||
@@ -112,7 +115,11 @@ public class ComponentProcessor {
|
||||
transformer = getComponentTransformer(annotation.transformer());
|
||||
keywordPolicy = annotation.keywordPolicy();
|
||||
keywordTag = annotation.keywordTag();
|
||||
cacheDrawing = annotation.enableCache();
|
||||
cacheDrawing = annotation.enableCache();
|
||||
if (annotation.enableDatasheet()) {
|
||||
datasheet = DatasheetService.getInstance().loadDatasheet(clazz);
|
||||
datasheetCreationStepCount = annotation.datasheetCreationStepCount();
|
||||
}
|
||||
} else { // default
|
||||
return null;
|
||||
}
|
||||
@@ -134,7 +141,8 @@ public class ComponentProcessor {
|
||||
}
|
||||
ComponentType componentType =
|
||||
new ComponentType(name, description, creationMethod, category, namePrefix, author, icon, clazz, zOrder,
|
||||
flexibleZOrder, bomPolicy, autoEdit, transformer, keywordPolicy, keywordTag, cacheDrawing);
|
||||
flexibleZOrder, bomPolicy, autoEdit, transformer, keywordPolicy, keywordTag, cacheDrawing, datasheet,
|
||||
datasheetCreationStepCount);
|
||||
componentTypeMap.put(clazz.getName(), componentType);
|
||||
return componentType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
*
|
||||
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
|
||||
*
|
||||
* This file is part of DIYLC.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
||||
/***
|
||||
* Utility in charge of loading component datasheet from corresponding files.
|
||||
*
|
||||
* @author bancika
|
||||
*
|
||||
*/
|
||||
public class DatasheetService {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(DatasheetService.class);
|
||||
|
||||
private static DatasheetService instance;
|
||||
|
||||
private static Map<String, List<String[]>> datasheetCache = new HashMap<String, List<String[]>>();
|
||||
private static Map<String, Map<String, List<String[]>>> lookupCache =
|
||||
new HashMap<String, Map<String, List<String[]>>>();
|
||||
|
||||
public static DatasheetService getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DatasheetService();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private DatasheetService() {}
|
||||
|
||||
public List<String[]> loadDatasheet(Class<?> clazz) {
|
||||
return datasheetCache.computeIfAbsent(clazz.getCanonicalName(), key -> {
|
||||
String fileName = clazz.getSimpleName() + ".datasheet";
|
||||
LOG.info("Loading datasheet file for " + fileName);
|
||||
URL resource = clazz.getResource(fileName);
|
||||
if (resource == null) {
|
||||
LOG.warn("Datasheet file not found: " + fileName);
|
||||
return null;
|
||||
}
|
||||
try (BufferedInputStream in = new BufferedInputStream(resource.openStream())) {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
|
||||
|
||||
List<String[]> types =
|
||||
reader.lines().map(line -> line.split("\\s*,\\s*")).collect(Collectors.toList());
|
||||
|
||||
LOG.info(String.format("Loaded %d component sizes from the file", types.size()));
|
||||
return types;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error loading component sizes", e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String[] lookup(Class<?> clazz, double tolerance, String key,
|
||||
double... approximateValues) {
|
||||
int keySize = (int) (key.chars().filter(i -> i == '|').count() + 1);
|
||||
|
||||
Map<String, List<String[]>> classData =
|
||||
lookupCache.computeIfAbsent(clazz.getCanonicalName(), k -> {
|
||||
List<String[]> datasheet = loadDatasheet(clazz);
|
||||
if (datasheet == null)
|
||||
return null;
|
||||
|
||||
return datasheet.stream().collect(Collectors.groupingBy(line -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < keySize; i++) {
|
||||
if (i > 0) {
|
||||
sb.append("|");
|
||||
}
|
||||
sb.append(line[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}));
|
||||
});
|
||||
|
||||
List<String[]> list = classData.get(key);
|
||||
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
outerloop: for (String[] line : list) {
|
||||
for (int i = 0; i < approximateValues.length; i++) {
|
||||
String valueStr = line[keySize + i];
|
||||
double actualValue = Double.parseDouble(valueStr.split(" ")[0]);
|
||||
if (Math.abs(actualValue - approximateValues[i]) / actualValue * 100 > tolerance)
|
||||
continue outerloop;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -58,17 +59,18 @@ public class InstantiationManager {
|
||||
public static int MAX_RECENT_COMPONENTS = 16;
|
||||
|
||||
private ComponentType componentTypeSlot;
|
||||
private Template template;
|
||||
private Template template;
|
||||
private String[] parameters;
|
||||
private List<IDIYComponent<?>> componentSlot;
|
||||
private Point2D firstControlPoint;
|
||||
private Point2D potentialControlPoint;
|
||||
|
||||
public static final ComponentType clipboardType = new ComponentType("Clipboard contents",
|
||||
"Components from the clipboard", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, null,
|
||||
false, null, KeywordPolicy.NEVER_SHOW, null, false);
|
||||
false, null, KeywordPolicy.NEVER_SHOW, null, false, null, 0);
|
||||
public static final ComponentType blockType = new ComponentType("Building block",
|
||||
"Components from the building block", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, null,
|
||||
false, null, KeywordPolicy.NEVER_SHOW, null, false);
|
||||
false, null, KeywordPolicy.NEVER_SHOW, null, false, null, 0);
|
||||
|
||||
public InstantiationManager() {}
|
||||
|
||||
@@ -78,6 +80,10 @@ public class InstantiationManager {
|
||||
|
||||
public Template getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public String[] getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public List<IDIYComponent<?>> getComponentSlot() {
|
||||
@@ -96,19 +102,21 @@ public class InstantiationManager {
|
||||
this.potentialControlPoint = potentialControlPoint;
|
||||
}
|
||||
|
||||
public void setComponentTypeSlot(ComponentType componentTypeSlot, Template template, Project currentProject, boolean forceInstatiate)
|
||||
public void setComponentTypeSlot(ComponentType componentTypeSlot, Template template, String[] parameters,
|
||||
Project currentProject, boolean forceInstatiate)
|
||||
throws Exception {
|
||||
this.componentTypeSlot = componentTypeSlot;
|
||||
this.template = template;
|
||||
this.template = template;
|
||||
this.parameters = parameters;
|
||||
if (componentTypeSlot == null) {
|
||||
this.componentSlot = null;
|
||||
} else {
|
||||
switch (componentTypeSlot.getCreationMethod()) {
|
||||
case POINT_BY_POINT:
|
||||
this.componentSlot = forceInstatiate ? instantiateComponent(componentTypeSlot, template, new Point2D.Double(0, 0), currentProject) : null;
|
||||
this.componentSlot = forceInstatiate ? instantiateComponent(componentTypeSlot, new Point2D.Double(0, 0), currentProject) : null;
|
||||
break;
|
||||
case SINGLE_CLICK:
|
||||
this.componentSlot = instantiateComponent(componentTypeSlot, template, new Point2D.Double(0, 0), currentProject);
|
||||
this.componentSlot = instantiateComponent(componentTypeSlot, new Point2D.Double(0, 0), currentProject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -118,7 +126,7 @@ public class InstantiationManager {
|
||||
|
||||
public void instatiatePointByPoint(Point2D scaledPoint, Project currentProject) throws Exception {
|
||||
firstControlPoint = scaledPoint;
|
||||
componentSlot = instantiateComponent(componentTypeSlot, template, firstControlPoint, currentProject);
|
||||
componentSlot = instantiateComponent(componentTypeSlot, firstControlPoint, currentProject);
|
||||
|
||||
// Set the other control point to the same location, we'll
|
||||
// move it later when mouse moves.
|
||||
@@ -262,12 +270,19 @@ public class InstantiationManager {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<IDIYComponent<?>> instantiateComponent(ComponentType componentType, Template template, Point2D point,
|
||||
Project currentProject) throws InstantiationException, IllegalAccessException {
|
||||
private List<IDIYComponent<?>> instantiateComponent(ComponentType componentType, Point2D point,
|
||||
Project currentProject) throws InstantiationException, IllegalAccessException, NoSuchMethodException,
|
||||
SecurityException, IllegalArgumentException, InvocationTargetException {
|
||||
LOG.info("Instatiating component of type: " + componentType.getInstanceClass().getName());
|
||||
|
||||
// Instantiate the component.
|
||||
IDIYComponent<?> component = componentType.getInstanceClass().newInstance();
|
||||
IDIYComponent<?> component;
|
||||
if (parameters == null) {
|
||||
component = componentType.getInstanceClass().newInstance();
|
||||
} else {
|
||||
Constructor<? extends IDIYComponent<?>> constructor = componentType.getInstanceClass().getConstructor(String[].class);
|
||||
component = constructor.newInstance((Object)parameters);
|
||||
}
|
||||
component.createdIn(currentProject);
|
||||
|
||||
component.setName(createUniqueName(componentType, currentProject.getComponents()));
|
||||
|
||||
@@ -605,6 +605,7 @@ public class Presenter implements IPlugInPort {
|
||||
// Keep the reference to component type for later.
|
||||
ComponentType componentTypeSlot = instantiationManager.getComponentTypeSlot();
|
||||
Template template = instantiationManager.getTemplate();
|
||||
String[] parameters = instantiationManager.getParameters();
|
||||
Project oldProject = currentProject.clone();
|
||||
switch (componentTypeSlot.getCreationMethod()) {
|
||||
case SINGLE_CLICK:
|
||||
@@ -639,9 +640,9 @@ public class Presenter implements IPlugInPort {
|
||||
editSelection();
|
||||
}
|
||||
if (configManager.readBoolean(IPlugInPort.CONTINUOUS_CREATION_KEY, false)) {
|
||||
setNewComponentTypeSlot(componentTypeSlot, template, false);
|
||||
setNewComponentTypeSlot(componentTypeSlot, template, parameters, false);
|
||||
} else {
|
||||
setNewComponentTypeSlot(null, null, false);
|
||||
setNewComponentTypeSlot(null, null, null, false);
|
||||
}
|
||||
break;
|
||||
case POINT_BY_POINT:
|
||||
@@ -663,7 +664,7 @@ public class Presenter implements IPlugInPort {
|
||||
} else {
|
||||
// On the second click, add the component to the
|
||||
// project.
|
||||
addPendingComponentsToProject(scaledPoint, componentTypeSlot, template);
|
||||
addPendingComponentsToProject(scaledPoint, componentTypeSlot, template, parameters);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -718,7 +719,7 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
}
|
||||
|
||||
private void addPendingComponentsToProject(Point2D scaledPoint, ComponentType componentTypeSlot, Template template) {
|
||||
private void addPendingComponentsToProject(Point2D scaledPoint, ComponentType componentTypeSlot, Template template, String[] parameters) {
|
||||
List<IDIYComponent<?>> componentSlot = instantiationManager.getComponentSlot();
|
||||
Point2D firstPoint = componentSlot.get(0).getControlPoint(0);
|
||||
// don't allow to create component with the same points
|
||||
@@ -742,9 +743,9 @@ public class Presenter implements IPlugInPort {
|
||||
editSelection();
|
||||
}
|
||||
if (configManager.readBoolean(IPlugInPort.CONTINUOUS_CREATION_KEY, false)) {
|
||||
setNewComponentTypeSlot(componentTypeSlot, template, false);
|
||||
setNewComponentTypeSlot(componentTypeSlot, template, parameters, false);
|
||||
} else {
|
||||
setNewComponentTypeSlot(null, null, false);
|
||||
setNewComponentTypeSlot(null, null, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1664,7 +1665,7 @@ public class Presenter implements IPlugInPort {
|
||||
// calculateSelectionDimension());
|
||||
} else if (instantiationManager.getComponentSlot() != null) {
|
||||
preDragProject = currentProject.clone();
|
||||
addPendingComponentsToProject(scaledPoint, instantiationManager.getComponentTypeSlot(), null);
|
||||
addPendingComponentsToProject(scaledPoint, instantiationManager.getComponentTypeSlot(), null, null);
|
||||
} else {
|
||||
updateSelection(selectedComponents);
|
||||
}
|
||||
@@ -2415,7 +2416,7 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNewComponentTypeSlot(ComponentType componentType, Template template, boolean forceInstatiate) {
|
||||
public void setNewComponentTypeSlot(ComponentType componentType, Template template, String[] parameters, boolean forceInstatiate) {
|
||||
LOG.info(String.format("setNewComponentSlot(%s)", componentType == null ? null : componentType.getName()));
|
||||
|
||||
// record a test step if needed
|
||||
@@ -2429,7 +2430,7 @@ public class Presenter implements IPlugInPort {
|
||||
|
||||
if (componentType != null && componentType.getInstanceClass() == null) {
|
||||
LOG.info("Cannot set new component type slot for type " + componentType.getName());
|
||||
setNewComponentTypeSlot(null, null, false);
|
||||
setNewComponentTypeSlot(null, null, null, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2452,7 +2453,7 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
|
||||
try {
|
||||
instantiationManager.setComponentTypeSlot(componentType, template, currentProject, forceInstatiate);
|
||||
instantiationManager.setComponentTypeSlot(componentType, template, parameters, currentProject, forceInstatiate);
|
||||
|
||||
if (forceInstatiate)
|
||||
updateSelection(instantiationManager.getComponentSlot());
|
||||
|
||||
@@ -25,7 +25,7 @@ public class TestPlayer {
|
||||
try {
|
||||
switch(step.getAction()) {
|
||||
case DIYTest.SET_COMPONENT_SLOT:
|
||||
plugInPort.setNewComponentTypeSlot((ComponentType)step.getParams().get("componentType"), (Template)step.getParams().get("template"), (boolean)step.getParams().get("forceInstatiate"));
|
||||
plugInPort.setNewComponentTypeSlot((ComponentType)step.getParams().get("componentType"), (Template)step.getParams().get("template"),(String[])step.getParams().get("parameters"), (boolean)step.getParams().get("forceInstatiate"));
|
||||
res.add(new StepResult(i, step.getAction(), "OK", false));
|
||||
break;
|
||||
case DIYTest.MOUSE_MOVED:
|
||||
|
||||
Reference in New Issue
Block a user