added some documentation

This commit is contained in:
hneemann 2016-04-10 12:26:34 +02:00
parent 2108c69365
commit fc5ed14c77
6 changed files with 236 additions and 29 deletions

View File

@ -16,10 +16,23 @@ public class ObservableValue extends Value {
private final boolean supportsHighZ; private final boolean supportsHighZ;
private boolean bidirectional; private boolean bidirectional;
/**
* Creates a new instance
*
* @param name the name of this value
* @param bits the number of bits
*/
public ObservableValue(String name, int bits) { public ObservableValue(String name, int bits) {
this(name, bits, false); this(name, bits, false);
} }
/**
* Creates a new instance.
*
* @param name the name of this value
* @param bits the number of bits
* @param highZ if true this value can be a high impedance value
*/
public ObservableValue(String name, int bits, boolean highZ) { public ObservableValue(String name, int bits, boolean highZ) {
super(bits, highZ); super(bits, highZ);
mask = (1L << bits) - 1; mask = (1L << bits) - 1;
@ -28,16 +41,32 @@ public class ObservableValue extends Value {
supportsHighZ = highZ; supportsHighZ = highZ;
} }
/**
* Adds an observer to this value.
*
* @param observer the observer to add
* @return this for call chaining
*/
public ObservableValue addObserver(Observer observer) { public ObservableValue addObserver(Observer observer) {
if (observer != null) if (observer != null)
observers.add(observer); observers.add(observer);
return this; return this;
} }
/**
* Removes an observer from this value.
*
* @param observer the observer to use
*/
public void removeObserver(Observer observer) { public void removeObserver(Observer observer) {
observers.remove(observer); observers.remove(observer);
} }
/**
* Removes al observers from the given class
*
* @param observerClass the class of observers to remove
*/
public void removeObserver(Class<? extends Observer> observerClass) { public void removeObserver(Class<? extends Observer> observerClass) {
Iterator<Observer> it = observers.iterator(); Iterator<Observer> it = observers.iterator();
while (it.hasNext()) { while (it.hasNext()) {
@ -46,23 +75,38 @@ public class ObservableValue extends Value {
} }
} }
/**
* Fires a has changed event to all observers
*/
public void hasChanged() { public void hasChanged() {
for (Observer l : observers) { for (Observer l : observers) {
l.hasChanged(); l.hasChanged();
} }
} }
/**
* @return the number of bits of this value
*/
public int getBits() { public int getBits() {
return bits; return bits;
} }
/**
* returns the actual value
*
* @return the value
*/
public long getValue() { public long getValue() {
// if (highZ) // if (highZ)
// throw new HighZException(this); // throw new HighZException(this);
return value; return value;
} }
/**
* returns the actual value as a string
*
* @return the value as string
*/
public String getValueString() { public String getValueString() {
if (highZ) if (highZ)
return "?"; return "?";
@ -71,6 +115,12 @@ public class ObservableValue extends Value {
} }
} }
/**
* converts a value to a minimal hex string
*
* @param value the value
* @return the string representation
*/
public static String getHexString(long value) { public static String getHexString(long value) {
String s = Long.toHexString(value).toUpperCase(); String s = Long.toHexString(value).toUpperCase();
if (s.length() == 1) if (s.length() == 1)
@ -89,7 +139,11 @@ public class ObservableValue extends Value {
} }
} }
/**
* Sets the value and fires a event if value has changed.
*
* @param value the new value
*/
public void setValue(long value) { public void setValue(long value) {
value = getValueBits(value); value = getValueBits(value);
if (this.value != value) { if (this.value != value) {
@ -99,18 +153,43 @@ public class ObservableValue extends Value {
} }
} }
/**
* Returns the value as a bool.
*
* @return the boolean
*/
public boolean getBool() { public boolean getBool() {
return getValue() != 0; return getValue() != 0;
} }
/**
* Sets a bool value.
*
* @param bool the boolean to set
*/
public void setBool(boolean bool) { public void setBool(boolean bool) {
setValue(bool ? 1 : 0); setValue(bool ? 1 : 0);
} }
/**
* reduces a given value to the number of bits used by this value.
*
* @param value the value to reduce
* @return the reduced value
*/
public long getValueBits(long value) { public long getValueBits(long value) {
return value & mask; return value & mask;
} }
/**
* checks if the given number of bits is the same used by this value.
* It is a convenience method to make this check simpler to code.
*
* @param bits the number of bits
* @param node the node to add to the exception if one is thrown
* @return this for chained calls
* @throws BitsException thrown if bit numbers do not match
*/
public ObservableValue checkBits(int bits, Node node) throws BitsException { public ObservableValue checkBits(int bits, Node node) throws BitsException {
if (this.bits != bits) { if (this.bits != bits) {
throw new BitsException(Lang.get("err_needs_N0_bits_found_N2_bits", bits, this.bits), node, this); throw new BitsException(Lang.get("err_needs_N0_bits_found_N2_bits", bits, this.bits), node, this);
@ -118,10 +197,18 @@ public class ObservableValue extends Value {
return this; return this;
} }
/**
* @return true if this value is a high z value
*/
public boolean isHighZ() { public boolean isHighZ() {
return highZ; return highZ;
} }
/**
* Sets the highZ state of this value
*
* @param highZ the new highZ state
*/
public void setHighZ(boolean highZ) { public void setHighZ(boolean highZ) {
if (this.highZ != highZ) { if (this.highZ != highZ) {
this.highZ = highZ; this.highZ = highZ;
@ -138,37 +225,58 @@ public class ObservableValue extends Value {
@Override @Override
public String toString() { public String toString() {
return name + "{" + return name + "{"
"value=" + getValueString() + + "value=" + getValueString()
", setBits=" + bits + + ", setBits=" + bits
'}'; + '}';
} }
/**
* @return the name of this value
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* @return the numbers of observers
*/
public int observerCount() { public int observerCount() {
return observers.size(); return observers.size();
} }
/**
* @return teturns true if the value could become a highZ value
*/
public boolean supportsHighZ() { public boolean supportsHighZ() {
return supportsHighZ; return supportsHighZ;
} }
public boolean isHighZIgnoreBurn() { /**
return highZ; * Returns the value and does not throw a highZ exception.
} * Should be used if the value is needed to create a graphical representation to
* avoid the graphical representation is causing exceptions.
*
* @return the actual value.
*/
public long getValueIgnoreBurn() { public long getValueIgnoreBurn() {
return value; return value;
} }
/**
* Makes this value a bidirectional value.
*
* @param bidirectional true if value is bidirectional
* @return this for chained calls
*/
public ObservableValue setBidirectional(boolean bidirectional) { public ObservableValue setBidirectional(boolean bidirectional) {
this.bidirectional = bidirectional; this.bidirectional = bidirectional;
return this; return this;
} }
/**
* @return true if value is bidirectional
*/
public boolean isBidirectional() { public boolean isBidirectional() {
return bidirectional; return bidirectional;
} }

View File

@ -17,6 +17,9 @@ import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
/** /**
* This class is used to store the visual representation of an element.
* Instances of this class are also used to store a circuit to disk.
*
* @author hneemann * @author hneemann
*/ */
public class VisualElement implements Drawable, Moveable, AttributeListener { public class VisualElement implements Drawable, Moveable, AttributeListener {
@ -32,12 +35,23 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
private Vector pos; private Vector pos;
private int rotate; private int rotate;
/**
* creates a new instance
* The name of the element is the name which is given to the Library to get the {@link de.neemann.digital.core.element.ElementTypeDescription}
*
* @param elementName the name of the element
*/
public VisualElement(String elementName) { public VisualElement(String elementName) {
this.elementName = elementName; this.elementName = elementName;
elementAttributes = new ElementAttributes(); elementAttributes = new ElementAttributes();
pos = new Vector(0, 0); pos = new Vector(0, 0);
} }
/**
* Creates a copy of the given VisualElement
*
* @param proto the VisualElement to copy
*/
public VisualElement(VisualElement proto) { public VisualElement(VisualElement proto) {
this.elementName = proto.elementName; this.elementName = proto.elementName;
this.elementAttributes = new ElementAttributes(proto.elementAttributes); this.elementAttributes = new ElementAttributes(proto.elementAttributes);
@ -45,51 +59,95 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
this.rotate = proto.rotate; this.rotate = proto.rotate;
} }
/**
* Returns the name of the element.
* The name of the element is the name which is given to the Library to get the {@link de.neemann.digital.core.element.ElementTypeDescription}
*
* @return the name of the element
*/
public String getElementName() { public String getElementName() {
return elementName; return elementName;
} }
/**
* @return the elements attributes
*/
public ElementAttributes getElementAttributes() { public ElementAttributes getElementAttributes() {
elementAttributes.addListener(this); elementAttributes.addListener(this);
return elementAttributes; return elementAttributes;
} }
/**
* @return the position of this element
*/
public Vector getPos() { public Vector getPos() {
return pos; return pos;
} }
/**
* Sets the position of this element
*
* @param pos the position
* @return this for chained calls
*/
public VisualElement setPos(Vector pos) { public VisualElement setPos(Vector pos) {
this.pos = pos; this.pos = pos;
minMax = null; minMax = null;
return this; return this;
} }
/**
* Checks if the given point is within the bounding box of the shape of this element.
*
* @param p a position
* @return true if p is inside the bounding box of the shape of this element.
*/
public boolean matches(Vector p) { public boolean matches(Vector p) {
GraphicMinMax m = getMinMax(); GraphicMinMax m = getMinMax();
return (m.getMin().x <= p.x) && return (m.getMin().x <= p.x)
(m.getMin().y <= p.y) && && (m.getMin().y <= p.y)
(p.x <= m.getMax().x) && && (p.x <= m.getMax().x)
(p.y <= m.getMax().y); && (p.y <= m.getMax().y);
} }
/**
* Checks if the given bounding box contains the bounding box of the shape of this element.
*
* @param min upper left corner of the bounding box
* @param max lower right corner of the bounding box
* @return true if the given box completely contains this element
*/
public boolean matches(Vector min, Vector max) { public boolean matches(Vector min, Vector max) {
GraphicMinMax m = getMinMax(); GraphicMinMax m = getMinMax();
return (min.x <= m.getMin().x) && return (min.x <= m.getMin().x)
(m.getMax().x <= max.x) && && (m.getMax().x <= max.x)
(min.y <= m.getMin().y) && && (min.y <= m.getMin().y)
(m.getMax().y <= max.y); && (m.getMax().y <= max.y);
} }
/**
* @return the rotation of this element
*/
public int getRotate() { public int getRotate() {
return rotate; return rotate;
} }
/**
* sets the rotation of this element
*
* @param rotate the new value in the range 0-3
*/
public void setRotate(int rotate) { public void setRotate(int rotate) {
this.rotate = rotate; this.rotate = rotate;
minMax = null; minMax = null;
} }
/**
* Returns the shape of this element.
* The there is no shape the {@link ShapeFactory} is requested for the shape.
*
* @return the shape
*/
public Shape getShape() { public Shape getShape() {
if (shape == null) if (shape == null)
shape = shapeFactory.getShape(elementName, elementAttributes); shape = shapeFactory.getShape(elementName, elementAttributes);
@ -103,8 +161,8 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
shape.drawTo(gr, highLight); shape.drawTo(gr, highLight);
for (Pin p : shape.getPins()) for (Pin p : shape.getPins())
gr.drawCircle(p.getPos().add(-PIN, -PIN), p.getPos().add(PIN, PIN) gr.drawCircle(p.getPos().add(-PIN, -PIN), p.getPos().add(PIN, PIN),
, p.getDirection() == Pin.Direction.input ? Style.WIRE : Style.WIRE_OUT); p.getDirection() == Pin.Direction.input ? Style.WIRE : Style.WIRE_OUT);
if (highLight && minMax == null && !(graphic instanceof GraphicMinMax)) getMinMax(); if (highLight && minMax == null && !(graphic instanceof GraphicMinMax)) getMinMax();
@ -124,6 +182,9 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
return new TransformRotate(pos, rotate); return new TransformRotate(pos, rotate);
} }
/**
* @return the bounding box of the shape of this element
*/
public GraphicMinMax getMinMax() { public GraphicMinMax getMinMax() {
if (minMax == null) { if (minMax == null) {
GraphicMinMax mm = new GraphicMinMax(); GraphicMinMax mm = new GraphicMinMax();
@ -139,6 +200,13 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
minMax = null; minMax = null;
} }
/**
* Create an icon from this element.
* Is used to create the icons in the element menu
*
* @param maxHeight the maximum hight
* @return the icon ore null if the maximum height is exceeded.
*/
public ImageIcon createIcon(int maxHeight) { public ImageIcon createIcon(int maxHeight) {
GraphicMinMax mm = getMinMax(); GraphicMinMax mm = getMinMax();
@ -161,6 +229,9 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
return new ImageIcon(bi); return new ImageIcon(bi);
} }
/**
* @return the pins of this element
*/
public Pins getPins() { public Pins getPins() {
Shape shape = getShape(); Shape shape = getShape();
Transform tr = createTransform(); Transform tr = createTransform();
@ -186,6 +257,13 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
interactor = getShape().applyStateMonitor(ioState, guiObserver); interactor = getShape().applyStateMonitor(ioState, guiObserver);
} }
/**
* Is called if this element is clicked by the mouse.
* the call is delegated to the {@link Interactor} of the {@link Shape}
*
* @param cc the calling {@link CircuitComponent}
* @param pos the position
*/
public void clicked(CircuitComponent cc, Point pos) { public void clicked(CircuitComponent cc, Point pos) {
if (interactor != null) if (interactor != null)
interactor.clicked(cc, pos, ioState, element); interactor.clicked(cc, pos, ioState, element);
@ -207,14 +285,22 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
return elementName; return elementName;
} }
/**
* Sets the concrete element created.
* The value is given to the {@link Interactor} if the shape is clicked.
*
* @param element the element
*/
public void setElement(Element element) { public void setElement(Element element) {
this.element = element; this.element = element;
} }
public Element getElement() { /**
return element; * Sets the shape factory of this element.
} *
* @param shapeFactory the {@link ShapeFactory}
* @return this for chained calls
*/
public VisualElement setShapeFactory(ShapeFactory shapeFactory) { public VisualElement setShapeFactory(ShapeFactory shapeFactory) {
this.shapeFactory = shapeFactory; this.shapeFactory = shapeFactory;
return this; return this;

View File

@ -77,7 +77,7 @@ public class Style {
public static Style getWireStyle(ObservableValue value) { public static Style getWireStyle(ObservableValue value) {
if (value == null || value.getBits() > 1) return WIRE; if (value == null || value.getBits() > 1) return WIRE;
if (value.isHighZIgnoreBurn()) return WIRE_HIGHZ; if (value.isHighZ()) return WIRE_HIGHZ;
if (value.getValueIgnoreBurn() == 1) return WIRE_HIGH; if (value.getValueIgnoreBurn() == 1) return WIRE_HIGH;
else return WIRE_LOW; else return WIRE_LOW;

View File

@ -47,7 +47,7 @@ public class LEDShape implements Shape {
if (ioState != null) { if (ioState != null) {
fill = false; fill = false;
ObservableValue value = ioState.getInput(0); ObservableValue value = ioState.getInput(0);
if (!value.isHighZIgnoreBurn() && (value.getValue() != 0)) if (!value.isHighZ() && (value.getValue() != 0))
fill = true; fill = true;
} }

View File

@ -8,12 +8,19 @@ import java.util.ResourceBundle;
/** /**
* @author hneemann * @author hneemann
*/ */
public class Lang { public final class Lang {
private static class InstanceHolder { private static class InstanceHolder {
static final Lang INSTANCE = new Lang(); static final Lang INSTANCE = new Lang();
} }
/**
* gets an internationalized string
*
* @param key the key
* @param params optional parameters
* @return the internationalized string
*/
public static String get(String key, Object... params) { public static String get(String key, Object... params) {
return InstanceHolder.INSTANCE.getKey(key, params); return InstanceHolder.INSTANCE.getKey(key, params);
} }

View File

@ -0,0 +1,6 @@
/**
* simple internationalization class
*
* @author hneemann
*/
package de.neemann.digital.lang;