[PREVIOUS] [NEXT] [UP]

Variables

In this chapter you will learn how to make your visual programs more flexible with the use of variables.

When to use global variables

Consider example#1. The rnd_gen unit generates a random vector of 6400 (=80*80) elements. The write_pix unit displays these as pixel gray values in a 80x80 window. Imagine that we now want to display a random vector of different length, e.g. half the original dimension, using a window that is half as wide. This would require to make changes in two places: in the dimension entry of the rnd_gen unit and in the width entry of the write_pix unit.

Clearly, such manual editing would remain manageable only for very small circuits (even in our small example, we would have to temporarily disconnect the two units, since we could not make the dimension change at both ends of the wire simultaneously). To solve tasks like this, Neo allows to use variables in the entry slots of each unit. In this way, circuits can be parametrized so as to allow their simple and consistent reconfiguration.

How to define global variables

To parametrize the present example circuit, we introduce two global variables, one for the width and one for the height of the circuit (we don't need a variable for the rnd vector dimension, since it follows when we know the width and the height). Select the "Define" command in the command menu to define the required global variables for our circuit. A dialog window pops up. You are now expected to enter the layout of an input window to query and assign values for the desired variables.

The necessary widget specification follows the rules explained for the input_window unit (in fact, the window is made by such a unit). In the present case, enter something like

 width  : %80i %n
 height : %80i %n

The text is just to aid the user making the right entries. The important parts are the two widget directives %80i, each of which provides an input entry for an integer value, initially set to 80 (remember that the %n are just directives to obtain linefeeds). Press the test button to see the layout of your newly specified input window. If you are satisfied, accept with OK, otherwise select CANCEL to make changes.

You have now defined two global variables for your circuit. The first variable will be named $0 and its value is set by the widget created for the first %80i widget directive. The second variable will be named $1 and will be set through to the second widget. The current values of $0 and $1 are 80, since we have specified the widgets to have these initial values.

How to use global variables

You can now replace the width and height entries in the write_pix unit by the newly defined variables $0 and $1 (note that we have initialized the variables with precisely those values that they are going to replace; this allows to make the substitution without running into any dimension conflicts with attached wires).

Next, we replace the dimension entry in the rnd_gen unit (open its creation dialog window). The correct dimension is the product $0*$1 and Neo will correctly evaluate arithmetic expressions of variables. However, the initial dimension was specified negative, in order to obtain a float vector connector (instead of a yellow scalar vector connector), thus change the entry to "-$0*$1" (without the apostrophes).

You have now parametrized your circuit. Note that the little squares at the bottom of both units are now filled red to indicates that these units depend on global variables. You can now reconfigure your circuit by just assigning new values to the two variables. This requires you to bring up the input window that you have just defined previously. This window is always accessible with the right mouse button when you are at the topmost level of your circuit (if you are inside a container, the right mouse button just leads one level up). Press the right mouse button. Your newly defined input window should come up. Specify new values for width and height and press return. The window will disappear and your circuit be reconfigured according to the newly entered values.

How to change global variables

Imagine that you now want to change the set of existing global variables, e.g., add a new variable, say, for the title of the write_pix window. Again, use the "Define" command to bring up the definition window for the global variable window. You will see that the window now contains the text

width  : @0 %n
height : @1 %n

which is what you entered, but each widget token has been replaced by @i, where i is the index of the associated global $-variable (Neo makes this replacement to be able to distinguish any already existing widgets from newly inserted ones).

To introduce a new variable for the window title, which now is not numeric, but a string, edit the above text to contain an additional text widget directive, i.e., to something like (newly inserted text emphasized)

 title : %40t %n
 width : @0 %n
 height: @1 %n

(assuming that you wish to make the title the new first variable, and that a length of 40 characters is sufficient). Test and/or accept your new layout.

You now have three variables $0, $1 and $2. Since Neo always identifies variables by the serial position of their widget in the variable input window (the window that you just have defined), $0 is the newly introduced text variable (which currently contains the empty string) and $1, $2 are the new width and height variables (that before were named $0, $1).

Finally, open the write_pix window to insert the newly defined $0 into the title field. You will also note that Neo has automatically updated the former $0,$1 to $1,$2, as required by their position shift due to the introduction of a new variable in the first position. (a similar update has taken place in the rnd_gen dialog window, you may wish to check). You can now also specify the write_pix window title from the global variable window. You can compare your circuit with example#2, which contains what you should have obtained from the previous steps.

How to display ariables

Each occurrence of a variable $i in the annotation title will be replaced by its current value. This allows you to write annotations that display the values of particular variables in the circuit window (to escape the substitution mechanism, prefix the $i by a backslash).

How to set variables from the command line

When a circuit is started together with neo from the command line, you can change the default values of the circuit's global variables (if it has any) by adding a suitable number of command line arguments, each of which must have the form "@i=something" (no spaces allowed!), for example:

neo -i mycircuit @2=-34.1 @0="a string"

Note that here variable names are given by @i (and not by $i, as might be expected; the reason is, of course, that '$' already is a special shell character). Also, currently i is limited to the 10 values 0..9. Neo will check types and legal ranges of each variable assignment and will ignore all assignments that fail the check.

Where variables should be avoided

One exception where you should avoid to use variables are the entry slots in containers. These are treated in a special way: to simplify things, the dimensions of container connectors always try to follow the dimensions of their attached wires suitably (making the use of variables to specify a dimension superfluous), and whenever this occurs, the previous value in the corresponding entry slot is overwritten by the new value (and any inserted variable will be lost). A similar thing happens to the number-of-operands field of some operator units, such as the for_op. Here, the overwriting occurs when you manually change the scope of the operator. However, there are probably only rare cases where you will miss the possibility to parametrize the number of operands that an operator has.


[PREVIOUS] [NEXT] [UP]