From 976e8491d8156eabdaa54165d3a474709cd5e471 Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Fri, 25 Jul 2014 00:29:44 +0200 Subject: [PATCH] w-i-p --- src/org/hwo/BitField.java | 61 ----- src/org/hwo/bitfields/BitField.java | 99 +++++++ src/org/hwo/bitfields/Field.java | 77 ++++++ src/org/hwo/intellivalues/IntelliInteger.java | 42 +++ src/org/hwo/intellivalues/IntelliValue.java | 16 ++ src/org/hwo/io/servicelink/ServiceLink.java | 33 +-- .../io/servicelink/ServiceRegisterCache.java | 133 ++++++++++ .../register/FloatServiceRegister.java | 28 ++ .../register/IntegerServiceRegister.java | 27 ++ .../servicelink/register/ServiceRegister.java | 246 +++++++----------- .../register/ServiceRegisterEditorDialog.java | 6 +- .../{ => bitfield}/BitFieldEditor.java | 4 +- 12 files changed, 523 insertions(+), 249 deletions(-) delete mode 100644 src/org/hwo/BitField.java create mode 100644 src/org/hwo/bitfields/BitField.java create mode 100644 src/org/hwo/bitfields/Field.java create mode 100644 src/org/hwo/intellivalues/IntelliInteger.java create mode 100644 src/org/hwo/intellivalues/IntelliValue.java create mode 100644 src/org/hwo/io/servicelink/ServiceRegisterCache.java create mode 100644 src/org/hwo/io/servicelink/register/FloatServiceRegister.java create mode 100644 src/org/hwo/io/servicelink/register/IntegerServiceRegister.java rename src/org/hwo/io/servicelink/register/{ => bitfield}/BitFieldEditor.java (96%) diff --git a/src/org/hwo/BitField.java b/src/org/hwo/BitField.java deleted file mode 100644 index c492a15..0000000 --- a/src/org/hwo/BitField.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.hwo; - -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -public class BitField { - - private String[] labels; - - public BitField() - { - labels = new String[32]; - initialize(); - } - - public String[] getLabels() - { - return labels; - } - - public BitField(Element element) - { - labels = new String[32]; - - initialize(); - - NodeList bits = element.getElementsByTagName("Bit"); - for (int i=0;i0) - sb.append(", "); - sb.append(labels[i]); - } - } - - return sb.toString(); - } - -} diff --git a/src/org/hwo/bitfields/BitField.java b/src/org/hwo/bitfields/BitField.java new file mode 100644 index 0000000..08d3b57 --- /dev/null +++ b/src/org/hwo/bitfields/BitField.java @@ -0,0 +1,99 @@ +package org.hwo.bitfields; + +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +public class BitField { + + private Integer value; + private List fields; + + public BitField() + { + this.fields = new ArrayList(); + + initialize(); + } + + public BitField(Element fieldsNode) + { + this.fields = new ArrayList(); + + NodeList fields = fieldsNode.getElementsByTagName("Field"); + for (int i=0;i 0) + sb.append(", "); + sb.append(st); + } + } + } + return sb.toString(); + } + + public synchronized Integer getValue() + { + return this.value; + } + + public synchronized void setValue(Integer value) + { + this.value = value; + } + + public synchronized int getValue(int start,int len) + { + if (value == null) + return 0; + return (value >> start) & (-1 >> (Integer.SIZE - len)); + } + + public synchronized void setValue(int value,int start,int len) + { + if (this.value == null) + this.value = 0; + + this.value &= ~((-1 >> (Integer.SIZE - len)) << start); + this.value |= (value & (-1 >> (Integer.SIZE - len))) << start; + } + + +} diff --git a/src/org/hwo/bitfields/Field.java b/src/org/hwo/bitfields/Field.java new file mode 100644 index 0000000..19c9bdb --- /dev/null +++ b/src/org/hwo/bitfields/Field.java @@ -0,0 +1,77 @@ +package org.hwo.bitfields; + +public class Field { + + private BitField bitField; + private int start, + len; + + private String label; + + public Field(BitField bitField,int start,int len) + { + this.initialize(bitField, start, len, null); + } + + public Field(BitField bitField,int start,int len,String label) + { + this.initialize(bitField, start, len, label); + } + + public void initialize(BitField bitField,int start,int len,String label) + { + this.bitField = bitField; + this.start = start; + this.len = len; + if (label != null) + this.label = label; + else + { + if (this.len == 1) + this.label = String.format("B%d",start); + else + this.label = String.format("B%d:%d",start,start+len-1); + } + } + public int getValue() + { + return this.bitField.getValue(start, len); + } + public void setValue(int value) + { + this.bitField.setValue(value, start, len); + } + + public int getStart() + { + return this.start; + } + public int getLength() + { + return this.len; + } + + public String getLabel() + { + return this.label; + } + + public BitField getBitField() { + return bitField; + } + + public String toText() + { + if (len == 1) + if (getValue() != 0) + return this.label; + else + return null; + else + { + return String.format("%s:%d", label, getValue()); + } + } + + +} diff --git a/src/org/hwo/intellivalues/IntelliInteger.java b/src/org/hwo/intellivalues/IntelliInteger.java new file mode 100644 index 0000000..14b3f7e --- /dev/null +++ b/src/org/hwo/intellivalues/IntelliInteger.java @@ -0,0 +1,42 @@ +package org.hwo.intellivalues; + +import javax.swing.JComponent; + +public class IntelliInteger implements IntelliValue { + + private IntelliValue sourceValue; + + public IntelliInteger(IntelliValue sourceValue) + { + + } + + @Override + public int getIntValue() { + return 0; + } + + @Override + public void setIntValue(int value) { + } + + @Override + public float getFloatValue() { + return 0; + } + + @Override + public void setFloatValue(int value) { + } + + @Override + public String getInformalText() { + return null; + } + + @Override + public JComponent getEditorComponent() { + return null; + } + +} diff --git a/src/org/hwo/intellivalues/IntelliValue.java b/src/org/hwo/intellivalues/IntelliValue.java new file mode 100644 index 0000000..e39521f --- /dev/null +++ b/src/org/hwo/intellivalues/IntelliValue.java @@ -0,0 +1,16 @@ +package org.hwo.intellivalues; + +import javax.swing.JComponent; + +public interface IntelliValue { + int getIntValue(); + void setIntValue(int value); + float getFloatValue(); + void setFloatValue(int value); + + String getInformalText(); + + JComponent + getEditorComponent(); + +} diff --git a/src/org/hwo/io/servicelink/ServiceLink.java b/src/org/hwo/io/servicelink/ServiceLink.java index a8aa2f0..bfa460e 100644 --- a/src/org/hwo/io/servicelink/ServiceLink.java +++ b/src/org/hwo/io/servicelink/ServiceLink.java @@ -8,8 +8,8 @@ import java.util.ArrayList; import java.util.Hashtable; import java.util.List; -import org.hwo.BitField; import org.hwo.ChkSum; +import org.hwo.bitfields.BitField; import org.hwo.interactiveobjects.InteractiveObject; import org.hwo.io.SerialPort; import org.hwo.io.servicelink.register.ServiceRegister; @@ -430,43 +430,24 @@ public class ServiceLink { } - - private SerialPort serialPort; int retries; - - private Hashtable serviceRegisters; + private ServiceRegisterCache + serviceRegisterCache; public ServiceLink(SerialPort serialPort) { this.retries = 3; this.serialPort = serialPort; this.serialPort.setTimeout(250); - this.serviceRegisters = new Hashtable(); + this.serviceRegisterCache = new ServiceRegisterCache(this); } - public ServiceRegister getServiceRegister(int ax,int node,int register,boolean readAsFloat) + public ServiceRegisterCache getServiceRegisterCache() { - int hash = ServiceRegister.calcHash(ax, node, register, readAsFloat); - - if (!serviceRegisters.containsKey(hash)) - { - ServiceRegister sr = new ServiceRegister(this); - sr.setAx(ax); - sr.setNode(node); - sr.setRegister(register); - sr.setReadAsFloat(readAsFloat); - serviceRegisters.put(sr.hashCode(), sr); - } - - if (serviceRegisters.get(hash) == null) - { - System.err.println("ARGH"); - } - - return serviceRegisters.get(hash); + return this.serviceRegisterCache; } - + public void open() throws ServiceLinkException { if (serialPort != null) diff --git a/src/org/hwo/io/servicelink/ServiceRegisterCache.java b/src/org/hwo/io/servicelink/ServiceRegisterCache.java new file mode 100644 index 0000000..88558dd --- /dev/null +++ b/src/org/hwo/io/servicelink/ServiceRegisterCache.java @@ -0,0 +1,133 @@ +package org.hwo.io.servicelink; + +import java.io.IOException; +import java.util.Hashtable; + +public class ServiceRegisterCache { + + public class BaseCacheItem + { + Integer ax, + node, + register; + + long lastReadTime; + + public BaseCacheItem(int ax,int node,int register) + { + this.ax = ax; + this.node = node; + this.register = register; + } + + long age() + { + return System.currentTimeMillis() - lastReadTime; + } + + boolean isOld() + { + return age() > 250; + } + } + + public class IntegerCacheItem extends BaseCacheItem + { + public IntegerCacheItem(int ax,int node,int register) + { + super(ax,node,register); + } + Integer intValue; + + Integer intValue() + { + if (isOld()) + { + try { + intValue = serviceLink.readInt(ax.byteValue(),node.byteValue(),register); + } catch (Exception e) { + e.printStackTrace(); + intValue = null; + } + lastReadTime = System.currentTimeMillis(); + } + return intValue; + } + } + + public class FloatCacheItem extends BaseCacheItem + { + public FloatCacheItem(int ax,int node,int register) + { + super(ax,node,register); + } + Float floatValue; + + Float floatValue() + { + if (isOld()) + { + try { + floatValue = serviceLink.readFloat(ax.byteValue(),node.byteValue(),register); + } catch (Exception e) { + e.printStackTrace(); + floatValue = null; + } + lastReadTime = System.currentTimeMillis(); + } + return floatValue; + } + + } + + int calcHash(int ax,int node,int register) + { + return (ax << 20)|(node << 16)|register; + } + + ServiceLink serviceLink; + + Hashtable + integerCache; + Hashtable + floatCache; + + ServiceRegisterCache(ServiceLink serviceLink) + { + this.serviceLink = serviceLink; + this.integerCache = new Hashtable(); + this.floatCache = new Hashtable(); + } + + public synchronized Integer getCachedInteger(int ax,int node,int register) + { + int hash = calcHash(ax, node, register); + IntegerCacheItem ici = integerCache.get(hash); + if (ici == null) + { + ici = new IntegerCacheItem(ax,node,register); + integerCache.put(hash, ici); + } + return ici.intValue(); + } + + public synchronized Float getCachedFloat(int ax,int node,int register) + { + int hash = calcHash(ax, node, register); + FloatCacheItem ici = floatCache.get(hash); + if (ici == null) + { + ici = new FloatCacheItem(ax,node,register); + floatCache.put(hash, ici); + } + return ici.floatValue(); + } + + public synchronized void invalidate(int ax,int node,int register) + { + int hash = calcHash(ax, node, register); + integerCache.remove(hash); + floatCache.remove(hash); + } + +} diff --git a/src/org/hwo/io/servicelink/register/FloatServiceRegister.java b/src/org/hwo/io/servicelink/register/FloatServiceRegister.java new file mode 100644 index 0000000..682d479 --- /dev/null +++ b/src/org/hwo/io/servicelink/register/FloatServiceRegister.java @@ -0,0 +1,28 @@ +package org.hwo.io.servicelink.register; + +import javax.swing.JComponent; + +import org.hwo.io.servicelink.ServiceLink; + +public class FloatServiceRegister extends ServiceRegister { + + public FloatServiceRegister(ServiceLink serviceLink) + { + super(serviceLink); + } + + @Override + public String getTextRepresentation() { + Float f = readFloatValue(); + if (f == null) + return ""; + return String.format("0x%08X %f",f,f); + } + + @Override + public JComponent getEditorComponent() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/org/hwo/io/servicelink/register/IntegerServiceRegister.java b/src/org/hwo/io/servicelink/register/IntegerServiceRegister.java new file mode 100644 index 0000000..f231300 --- /dev/null +++ b/src/org/hwo/io/servicelink/register/IntegerServiceRegister.java @@ -0,0 +1,27 @@ +package org.hwo.io.servicelink.register; + +import javax.swing.JComponent; + +import org.hwo.io.servicelink.ServiceLink; + +public class IntegerServiceRegister extends ServiceRegister { + + public IntegerServiceRegister(ServiceLink serviceLink) + { + super(serviceLink); + } + + @Override + public String getTextRepresentation() { + Integer i = readIntegerValue(); + if (i == null) + return ""; + return String.format("0x%08x %d", i, i); + } + + @Override + public JComponent getEditorComponent() { + return null; + } + +} diff --git a/src/org/hwo/io/servicelink/register/ServiceRegister.java b/src/org/hwo/io/servicelink/register/ServiceRegister.java index c8228ae..cbde0bf 100644 --- a/src/org/hwo/io/servicelink/register/ServiceRegister.java +++ b/src/org/hwo/io/servicelink/register/ServiceRegister.java @@ -1,44 +1,69 @@ package org.hwo.io.servicelink.register; import java.awt.Component; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import javax.swing.JComponent; + import org.hwo.interactiveobjects.InteractiveObject; import org.hwo.io.servicelink.ServiceLink; import org.hwo.io.servicelink.ServiceLink.ServiceTelegram; +import org.hwo.io.servicelink.register.bitfield.BitFieldEditor; import org.hwo.io.servicelink.ServiceLinkException; import org.hwo.models.TableMapper.TableColumn; +import org.w3c.dom.Element; +import org.w3c.dom.Node; @InteractiveObject(editor=ServiceRegisterEditorDialog.class) -public class ServiceRegister { - - static Long DEFAULT_CACHE_TIME = 250L; +public abstract class ServiceRegister { - static HashMap> controls; - public static void addServiceRegisterControl(String regType,Class clazz) + static HashMap> serviceRegisterTypes; + public static void addServiceRegisterType(String typename,Class clazz) { - controls.put(regType, clazz); + serviceRegisterTypes.put(typename, clazz); } - public static ServiceRegisterControl createControlForType(String registerType) + + public static ServiceRegister createServiceRegister(ServiceLink serviceLink,String typeName) { - Class clazz; - if (controls.containsKey(registerType)) - clazz = controls.get(registerType); - else - clazz = controls.get(null); - try + ServiceRegister sr = null; + + Class clazz = serviceRegisterTypes.get(typeName); + if (clazz != null) { - ServiceRegisterControl src = clazz.newInstance(); - - return src; - } catch (Exception e) - { - e.printStackTrace(); + try { + sr = clazz.getDeclaredConstructor(ServiceLink.class).newInstance(serviceLink); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } } - return null; + return sr; } + public static ServiceRegister createServiceRegister(ServiceLink serviceLink,Element registerNode) + { + ServiceRegister sr = null; + String registerType = registerNode.getAttribute("type"); + + if (registerType == null || registerType.equals("")) + registerType = "Integer"; + + sr = createServiceRegister(serviceLink, registerType); + if (sr != null) + { + sr.setRegisterNode(registerNode); + } + return sr; + } + + private Element registerNode; private ServiceLink serviceLink; private Integer ax, @@ -48,43 +73,54 @@ public class ServiceRegister { private String registerType; private String registerName; - private Long lastReadTime; - private Long maxCacheTime; - - private Boolean readAsFloat; - - private Integer intValue; - private Float floatValue; - private ServiceRegisterControl serviceRegisterControl; - - public static int calcHash(int ax,int node,int register,Boolean readAsFloat) - { - return (ax << 20)|(node << 16)|register|(readAsFloat ? 0x40000000 : 0); - } - - @Override - public int hashCode() { - return calcHash(ax, node, register, readAsFloat); - }; public ServiceRegister(ServiceLink serviceLink) { this.serviceLink = serviceLink; - this.maxCacheTime = DEFAULT_CACHE_TIME; - this.lastReadTime = 0l; } - public ServiceRegisterControl getServiceRegisterControl() - { - if (serviceRegisterControl == null) - { - serviceRegisterControl = createControlForType(getRegisterType()); - serviceRegisterControl.setServiceRegister(this); - } - return serviceRegisterControl; + @TableColumn(label="Bezeichnung",after="Register",width=400) + public String getRegisterName() { + return registerName; } + public void setRegisterName(String registerName) { + this.registerName = registerName; + } + + @TableColumn(label="Register",firstColumn=true,width=80) + public Integer getRegister() { + return register; + } + public void setRegister(Integer register) { + this.register = register; + } + + @TableColumn(label="Wert",after="Bezeichnung",width=250) + abstract public String getTextRepresentation(); + + abstract public JComponent getEditorComponent(); + + public Element getRegisterNode() + { + return registerNode; + }; + public void setRegisterNode(Element registerNode) + { + this.registerNode = registerNode; + + if (this.registerNode != null) + { + Element labelNode = (Element)this.registerNode.getElementsByTagName("Label").item(0); + Element addressNode = (Element)this.registerNode.getElementsByTagName("Address").item(0); + + register = Integer.decode(addressNode.getTextContent()); + registerName = labelNode.getTextContent(); + } + + } + public ServiceLink getServiceLink() { return serviceLink; @@ -108,68 +144,16 @@ public class ServiceRegister { public void setNode(Integer node) { this.node = node; } - - @TableColumn(label="Register",firstColumn=true,width=80) - public Integer getRegister() { - return register; - } - public void setRegister(Integer register) { - this.register = register; - } - - - public String getRegisterType() { - return registerType; - } - public void setRegisterType(String registerType) { - this.registerType = registerType; - } - - - @TableColumn(label="Bezeichnung",after="Register",width=400) - public String getRegisterName() { - return registerName; - } - public void setRegisterName(String registerName) { - this.registerName = registerName; - } - - @TableColumn(label="Wert",after="Bezeichnung",width=250) - public String getTextRepresentation() - { - return getServiceRegisterControl().getTextRepresentation(); - } public Float readFloatValue() { - try - { - if ((getAge() < maxCacheTime) && - ( - (intValue != null) || - (floatValue != null) - ) - ) - { - if (intValue != null) - return intValue.floatValue(); - return floatValue; - } - intValue = null; - floatValue = this.serviceLink.readFloat(ax.byteValue(), node.byteValue(), register); - lastReadTime = System.currentTimeMillis(); - } catch (Exception e) - { - e.printStackTrace(); - } - return floatValue; + return serviceLink.getServiceRegisterCache().getCachedFloat(ax, node, register); } public void writeFloatValue(Float value) { try { this.serviceLink.writeFloat(ax.byteValue(), node.byteValue(), register.shortValue(),value); - this.lastReadTime = 0l; } catch (Exception e) { e.printStackTrace(); @@ -178,76 +162,24 @@ public class ServiceRegister { public Integer readIntegerValue() { - try - { - if ((getAge() < maxCacheTime) && - ( - (intValue != null) || - (floatValue != null) - ) - ) - { - if (intValue != null) - return intValue; - return floatValue.intValue(); - } - floatValue = null; - intValue = this.serviceLink.readInt(ax.byteValue(), node.byteValue(), register); - lastReadTime = System.currentTimeMillis(); - } catch (Exception e) - { - System.err.println( "ServiceRegister: readIntegerValue(): " + e.toString()); - } - return intValue; + return serviceLink.getServiceRegisterCache().getCachedInteger(ax, node, register); } public void writeIntegerValue(Integer value) { try { this.serviceLink.writeInt(ax.byteValue(), node.byteValue(), register,value); - this.lastReadTime = 0l; } catch (Exception e) { e.printStackTrace(); } } - - public Long getAge() - { - return System.currentTimeMillis() - this.lastReadTime; - } - - - public Long getMaxCacheTime() { - return maxCacheTime; - } - public void setMaxCacheTime(Long maxCacheTime) { - this.maxCacheTime = maxCacheTime; - } - - - public Long getLastReadTime() { - return lastReadTime; - } - public void setLastReadTime(Long lastReadTime) { - this.lastReadTime = lastReadTime; - } - - - public Boolean getReadAsFloat() { - return readAsFloat; - } - public void setReadAsFloat(Boolean readAsFloat) { - this.readAsFloat = readAsFloat; - } - static { - controls = new HashMap>(); + serviceRegisterTypes = new HashMap>(); - addServiceRegisterControl(null, IntegerRegisterEditor.class); - addServiceRegisterControl("Float", FloatRegisterEditor.class); - addServiceRegisterControl("Bitfield", BitFieldEditor.class); + serviceRegisterTypes.put("Integer", IntegerServiceRegister.class); + serviceRegisterTypes.put("Float", FloatServiceRegister.class); } } diff --git a/src/org/hwo/io/servicelink/register/ServiceRegisterEditorDialog.java b/src/org/hwo/io/servicelink/register/ServiceRegisterEditorDialog.java index bacd956..1dec874 100644 --- a/src/org/hwo/io/servicelink/register/ServiceRegisterEditorDialog.java +++ b/src/org/hwo/io/servicelink/register/ServiceRegisterEditorDialog.java @@ -49,7 +49,7 @@ public class ServiceRegisterEditorDialog extends JDialog implements IInteractive @Override public void componentShown(ComponentEvent e) { if (serviceRegister != null) - serviceRegister.getServiceRegisterControl().requestFocusInWindow(); + serviceRegister.getEditorComponent().requestFocusInWindow(); } }); setBounds(100, 100, 327, 318); @@ -216,7 +216,6 @@ public class ServiceRegisterEditorDialog extends JDialog implements IInteractive private void accept() { - serviceRegister.getServiceRegisterControl().writeValue(); setVisible(false); } @@ -234,8 +233,7 @@ public class ServiceRegisterEditorDialog extends JDialog implements IInteractive tfNode.setText(serviceRegister.getNode().toString()); tfRegister.setText(serviceRegister.getRegister().toString()); tfRegname.setText(serviceRegister.getRegisterName()); - panelEditorControl.add( serviceRegister.getServiceRegisterControl().getComponent() ); - serviceRegister.getServiceRegisterControl().readValue(); + panelEditorControl.add( serviceRegister.getEditorComponent()); } doLayout(); } diff --git a/src/org/hwo/io/servicelink/register/BitFieldEditor.java b/src/org/hwo/io/servicelink/register/bitfield/BitFieldEditor.java similarity index 96% rename from src/org/hwo/io/servicelink/register/BitFieldEditor.java rename to src/org/hwo/io/servicelink/register/bitfield/BitFieldEditor.java index 4a75af2..a26414b 100644 --- a/src/org/hwo/io/servicelink/register/BitFieldEditor.java +++ b/src/org/hwo/io/servicelink/register/bitfield/BitFieldEditor.java @@ -1,4 +1,4 @@ -package org.hwo.io.servicelink.register; +package org.hwo.io.servicelink.register.bitfield; import java.awt.Component; import java.util.ArrayList; @@ -12,6 +12,8 @@ import javax.swing.JPanel; import org.hwo.io.servicelink.ServiceLink; import org.hwo.io.servicelink.ServiceLink.ServiceNode; import org.hwo.io.servicelink.ServiceLink.ServiceNode.ServiceNodeRegister; +import org.hwo.io.servicelink.register.ServiceRegister; +import org.hwo.io.servicelink.register.ServiceRegisterControl; import java.awt.FlowLayout;