There are 2 constructors used in DLPlugin extensions. You should include one of the following constructors in your class:
public class MyPlugin extends DLPlugin {
public MyPlugin(java.util.Properties props) {
super(props);
...
}
public MyPlugin() {
super()
...
}
}
If you use java.util.Properties you must also include an "empty" constructor to initialize the properties you intend to use. For
example:
public MyPlugin() throws Exception {
super(prop1, value1, prop2, value2, ...);
...
}
The following 2 methods must be invoked by the constructor (or by a method called by the constructor):
Input/Output
The document reads input and writes output on binary channels called
"pins". Pins are numbered consecutively from 0, with input pins
having lower numbers than output pins. The document's principal
activitiy is to respond to changes on its input pins by writing new
values to its output pins (and possibly change some internal state
value).
The input/output pin size is established in the constructor with calls to setInputSize and setOutputSize. For example, here is a plug-in with 7 inputs and 7 outputs:
public class MyPlugin extends DLPlugIn {
public MyPlugin() {
setInputSize(7);
setOutputSize(7);
}
...
}
The plug-in it produces is shown below; note that the pin numbers are
clearly visible. Pin numbering assigns an index to the binary pins that interface the plug-in to the rest of the circuit. For convenience, pins may be grouped into larger bundles and treated as integer values. Bundles are declared with calls to setInMap and setOutMap. Let us assign a bundling pattern to our previous example that groups the 7 input pins into 3, 1, and 3, and the 7 output pins into 1, 4 and 2:
public class MyPlugin extends DLPlugIn {
public MyPlugin() {
setInputSize(7);
setOutputSize(7);
setInMap(3,1,3);
setOutMap(1,4,2);
}
}
Here is the resulting plug-in, showing also how it uses bus
connections to other components.
Once pin configurations have been determined, pins can be labeled using setLabel. The number of entries in setLabel must be the same as the number of actual physical pins. In our example, there are 6 physical pins.
public class MyPlugin extends DLPlugIn {
public MyPlugin() {
setInputSize(7);
setOutputSize(7);
setInMap(3,1,3);
setOutMap(1,4,2);
setLabels("i0(3)", "i1(1)", "i2(3)",
"o0(1)", "o1(4)", "o2(2)");
}
}
There are 2 indexing schemes used to reference pins. Pin numbering uses the original sequencing of the binary pins. Pos/Offset numbering refers to the bundling scheme. The Pos number is the physical pin number containing the pin, and the offset is its position within the physical pin. Conversion between the indexing schemes uses pinToPos and posToPin methods (see Document API: Pin ↔ Pos Conversion).
The following table shows the translation between pin indices and pos/offset indices for our example.
Pin Pos Offset 0 0 0 1 0 1 2 0 2 3 1 0 4 2 0 5 2 1 6 2 2
Pin Pos Offset 7 3 0 8 4 0 9 4 1 10 4 2 11 4 3 12 5 0 13 5 1
Individual binary values use getState and putState (with pin indexes) or getStatePos and putStatePos (with pos/offset numbers). See Document API: Binary Input/Output.
There are several convenience methods to input and output integer values derived from combining the binary values on pin bundles (or just sequences of individual pins).
Input
For input, the most important of these are:
protected long getBundle(int posNo)
protected long getBundle(int posNo, int offset, int length)
These return the value of the pins at pos number posNo as a little-endian long value. The bundle may be up to 64 bits wide. (For smaller bundles use casts to char and int types).
The first version returns the value of the entire bundle at the given position. The second version returns the value of the smaller bundle specified at the given position starting at the given offset and of the given length.
In our example:
getBundle(0) returns bits 0, 1 and 2.
getBundle(2, 1, 2) returns bits 5 and 6.
Output
The corresponding output methods are:
protected void putBundle(int posNo, int val)
protected void putBundle(int posNo, int val, int offset, int length)
protected void putBundleLong(int posNo, long val)
protected void putBundleLong(int posNo, long val, int offset, int length)
These output an int or long value as a binary number on the pins at the given pos index. The second version outputs only to the part of the bundle defined by offset and length.
In our example:
putBundle(4, 0xf} outputs 1111 on pins 8 - 11.
putBundle(4, 0xf, 1, 2) outputs 11 on pins 9 - 10.
There are 2 sets of pin number-based I/O methods, binToInt (binToLong) and intToBin (longToBin)
See Document API: Binary ↔ Integer Conversion.
Plug-in logic is based on the methods evalState and prime.
Plug-in components operate by responding to changes in their inputs. The call-back method public void evalState(int source, int val) is invoked whenever a change is detected on an input pin. The source and val parameters respectively contain the pin number and pin value of the pin triggering the call-back. The method may respond by reading its input, changing the internal state of the component (and, possibly, controls on the view) and/or writing to its output. The plug-in class must implement this method.
public void prime() is used when a circuit is activated to initialize the state and outputs of a component when that state depends on the value of some controls on its view. The default method does nothing. Generally, you need to override when your plug-in is not activated by an input.
DLPlugIn uses a property database to hold attributes that are retained in the cct and xml files storing the circuit containing the plug-in component. When used with the action menu (see below), it becomes possible to design generic plug-ins that can be specialized with specific property values.
When using propertys you must include a non-empty constructor accepting a java.util.Properties argument and calling super on that argument; e.g.,
public MyPlugin(java.util.Properties props) {
super(props);
...
}
If you use java.util.Properties you must also use the empty
constructor to initialize the properties you intend to use. For
example:
public MyPlugin() {
super(prop1, value1, prop2, value2, ...);
...
}
The remainder of the two constructors should otherwise be identical.The set of property getters and setters is described in API: Properties.
Each DLSim 3 component has an action menu accessible through a right-click on the component. Plug-in components may add items to this menu. Selection of any one of these items results in a call to a handler method.
New action menu items are specified using public void setAction(String... actions), where the strings in the argument are the new action items. The array of user-defined actions can be retrieved using public String[] getActions(). Actions are enabled/disabled using public void setActionEnabled(int idx, boolean enabled).
The handler method (empty in the base class) is public void performAction(int idx). The argument idx is the index of the selected action in the array returned by getActions().
Actions are often used to set properties, and so may change some of the intrinsic properties such as input/output size and pin configuration. If performAction calls any of the methods required (or optional) in the constructor, it must call reInit() .
See API: Action Menus.
The default view can display a row of "leds", each capable of showing a digit. (The default radix is hexidecimal, but can be changed). This row is displayed by invoking sedLedSize on a value > 0 during construction. An individual LED can be set to a specific digit (depending on the radix), or an entire range of columns can be used to display a multi-digit value.
See API: Led management.
Reflection refers to having access to the set plug-ins in the current circuit. The method protected Collection<DLPlugIn> getPluginSet() returns a collection of all plugin objects at the same level as the caller. It is particularly useful for engineering backchannel communication between plug-ins. This might be required, for example, to collect statistical data.
To create a brief description of the plug-in to be included in the DLSim 3 plug-in menu, include a declaration of the following form:
public static PluginInfo info = new PluginInfo(String... desc)Each of the Strings in the argument appears as a line in the menu documentation.