Tutorial 4: Properties; action menu

A Plug-in Tutorial
...     Tutorial 4: Properties; action menu

It is efficient to design generic plug-in types that are configured by properties at run-time. For example, a single ALU plugin may be used for various datapath widths, and a single MUX plugin may use various numbers of control bits and datapath widths.

This example illustrates a plug-in with a user-configurable property: the user may choose a bitwidth of either 3 or 5 input/output pins (again, merely copying its input to its output). The plug-in author can program any number of such properties. Property management is accomplished using the component's action menu and its property API.

Note that property values are on a per-instance basis. Thus one may include multiple instances of a given plug-in type in a given circuit with different property values.

package plugins.tutorial;

import java.io.IOException;
import java.util.Properties;

import dlsim.document.DLPlugIn;

/**
 * Plugin03: sample plugin using default view
 * 3 inputs, 3 outputs initially
 * Menu-option for 3 or 5 inputs/outputs
 * copies input to corresponding output
 * all inputs/outputs are bundled and labeled
 * Pins are number consecutively: 0, 1, 2 are input; 3, 4, 5 are output
 * 
 * @author rms
 *
 */
public class Plugin03 extends DLPlugIn {
    private static final String SIZEPROP = "Size";
    public static PluginInfo info =
            new PluginInfo("My Fourth PlugIn",
		           "Writes input to output", "3 or 5 bits");
	
    public Plugin03() throws IOException {
	super(SIZEPROP, "3");
	construct();
    }
	
    public Plugin03(Properties props) throws IOException {
	super(props);
	construct();
    }
	
    public void construct() {
	setActions("size = 3", "size = 5");
	int size = getIntegerProperty(SIZEPROP);
	pinConfig(size);
    }

    /*
     * Common setup routine for 3 or 5 bits
     */
    private void pinConfig(int size) {
	setInputSize(size);
	setOutputSize(size);
	setInMap(size);
	setOutMap(size);
	setLabels("in("+size+")", "out("+size+")");
	setActionEnabled((size == 5) ? 0 : 1, true);
	setActionEnabled((size == 5) ? 1 : 0, false);
    }

    /* 
     * Handler for menu selection
     * 
     */
    public void performAction(int n) {
	int size = (n == 0) ? 3 : 5;
	pinConfig(size);
	setProperty(SIZEPROP, size);
	reInit();
    }

    public void evalState(int source, int val) {
	putState(source+getInputSize(), val);
    }

}
To manage properties, note the following:
constructors
The null constructor should initialize properties used by the plug-in to their default values. It does this by calling super(String... proplist) with a sequence of Strings alternating property names and (String) property values.

When using persistent properties we must add a second constructor accepting a java.util.Properties argument that it passes to super.

The two constructors should proceed identically after the call to super. In this case the common object construction method construct is called.

plug-in properties API
The properties API uses the following methods:
To set properties:
public void setProperty(String property, String value)
public void setProperty(String property, Integer value)
public void setProperty(String property, Long value)
public void setProperty(String property, Float value)
public void setProperty(String property, Double value)

To get properties
public String getProperty(String property)
public Integer getIntegerProperty(String property)
public Long getLongProperty(String property)
public Float getFloatProperty(String property)
public Double getDoubleProperty(String property)

plug-in action menu API
public void setActions(String... actions)
Adds actions as menu selections to the component's action menu. The actions are indexed from 0.

public void setActionEnabled(int idx, boolean enabled)
Enables (or disables) the action indicated by idx. Alternatively, use, respectively, actionEnabled(int idx) or actionDisable(int idx).

public void performAction(int idx)
Call-back method invoked when a user-defined action is selected. idx is the index of the selected action.

public void reInit()
Must be called after any changes that affect the pin configuration.

Other highlights:

construct
Creates actions to set input/output size and calls pinConfig with the current size.

pinConfig
Sets input and output size; sets bit bundling to create single pin input and output; creates labels; and enables appropriate action menu items.

performAction
Calls pinConfig to reconfigure the pins to the new size; stores the new size as property SIZEPROP; calls reInit()

Run DLSim 3 (using "ant run") and build the circuit shown below using Plugin01.

The circuit shows the action menu. Note the user defined actions "size = 3" and "size = 5".

Exercise

  1. Save this circuit in XML and rebuild; change the pin size, save again, and rebuild again. Note the enabled/disabled items in the action menu.
  2. Add additional sizes and pin bundling options to the action menu. Be sure to create properties for additional options. Save your circuit in XML and reload to see if options are retained.