Connectors and wires
In this chapter you will learn about the connectors of units and wires
that make up a visual program.
Types of connectors
Most NST units possess connectors to receive input data and to return
output data. Connectors are indicated as little colored squares, with inputs
always sitting on the left, outputs always sitting on the right side of
an icon. Each connector consists of one or several "pins". There
are six predefined pin types, indicated by their color:
-
yellow: a single float
value ("scalar").
-
red:
one or several float values ("float vector")
-
green: one or
several int values ("int vector")
-
blue:
one or several byte values ("byte vector")
-
magenta: a null-terminated character string
-
brown: an instance
of a user-defined data type
A connector that is made up of pins of only one type is displayed in the
color of this type. A connector containing pins of more than one type ("composite
connector") is displayed as a white rectangle
(occasionally, you may also encounter a black connector. Such connectors
serve as an empty placeholder, they contain no data). The
example#1
illustrates
how suitable variable declarations in the prog_unit, prefixed by
the non-standard keyword "INP" or "OUT", can be used to make the declared
variables accessible in input or output connectors of an appropriate type.
The left prog_unit produces some outputs, the right one expects a corresponding
number of inputs.
Creating and editing wires
To pass the values from the outputs to the inputs requires to connect them
by wires. Wires are restricted to run between input-output pairs
of connectors of matching type. You can create a wire by the following
steps:
select the output connector (=source) with the mouse pointer,
hold the left mouse button down,
move the mouse pointer to the input connector (destination) while holding
the left mouse button down,
release the mouse button.
Try this for the current example to connect connectors of matching
color. Executing the circuit afterwards will then make the left prog_unit
print the values that it generates, and the right prog_unit the values
that it receives. When you create a wire (or later select it with the left
mouse button), the rightmost wire edit window will show the "fibers"
of the wire. A "fiber" is a part of a wire that always runs between
two individual pins. You can use the wire edit window to edit a wire a
the fiber level: clicking at a fiber in the wire edit window will delete
that fiber. Applying above steps in an analogous fashion to the pins in
the wire edit window will create a new fiber between the chosen pins.
The example#2
is similar to example#1, but now the same set of data is
offered via two composite connectors with corresponding pins. Connect
them and investigat which pin pairings can be made in the wire edit window
at the level of fibers!
NOTE: when you have cut all fibers in the wire edit window, the wire
will disappear at the moment when you leave the wire edit window with the
mouse pointer. You can then insert any fibers only after you have re-drawn
the wire in the circuit window. When you perform the above steps as indicated,
you will note that Neo tries automatically to insert as many fibers as
possible. If you don't want this, perform the steps in the reverse order,
i.e., draw the wire from the destination pin to the source pin.
You then have to insert all fibers from the wire edit window.
Fixed and dynamic
dimension connectors
In many cases it is desireable to make the dimension of a data vector dynamically
changeable during run-time. To this end, there are dynamic dimension
counterparts of the red, green and blue vector pin types. This dynamic
dimension type (or "dynamic pin" for short) is indicated by a little
surrounding square. The prog_unit creates dynamic pins for those
INP/OUT variables that are declared as pointers (see example#3).
A number of other units interpretes a dimension specification of 0 as a
request for a dynamic version of the associated pin(s).
Type compatibility
Connectors can only be connected, if they are type compatible. Two
connectors are type compatible, when they share at least a pair of type
compatible pins. Two pins are type compatible, when they are either both
of type string, or they are of the same type and their dimensions are either
equal, or at least the dimension of the destination is dynamic (and can
thus adapt to any dimension of the source pin). When you connect such pins
by a fiber, this will set up a fast by-reference access from the destination
to the source, using a pointer. Additionally, the float, byte
and
int
vector pins are mutually type compatible, if they are of the same fixed
dimension. When you connect such pins by a fiber, this will set up a by-copy
access from the destination to the source, with inclusion of an appropriate
data conversion call during the copy. Finally, you can connect a connector
with a single fixed dimension byte, float or int vector pin
with a scalar vector connector when dimension of the vector pin
matches the number of elements in the scalar connector (again, in this
case the access mechanism is by-copy+conversion, except when the source
is a float vector, in which case a fast by-reference is possible
and implemented).
Load example#1
and
example#2
to
try out these rules!
Conventions about connectors
The most frequent connectors in NST are of the yellow (representing vectors
of values individually accessible via Neo wires, cf. below) or red type
(usually with a single pin holding a float vector whose elements are not
individually accessible for Neo wires). When the number of elements in
one or several yellow connectors of a NST unit is given by some creation
parameter n>0, then many NST units follow the convention that specifying
the negative parameter value -n is the request to replace each of
the yellow connectors by a red one with a single float vector pin of n>0
elements. A dimension n=0 is reserved to indicate the request for
a dynamic pin (only honored when a unit implements this possibility).
How to display
information about a connector
Information about a connector can be displayed by visiting it with the
mouse pointer. Neo can be in one of the following three modes for displaying
connector information:
1. "lazy": in this mode, display of connector information
requires additionally to press the left mouse button down. When the connector
consists of a single vector or text string pin, or a number of scalar pins
("scalar vector"), this will make the first few and the last few data items
(numbers in the vector, or characters in the text string) appear in the
title bar of the circuit window. If the connector is of a more complex
type (several vector or text pins, or mixed data types), the title bar
will only display a "type signature" for the connector (with letters
s,c,i,f,t
indicating scalar float, char (=byte) vector, int vector, float vector
or text string types, following by the allocated
dimension. If something appears between angular brackets, this will
be a user-defined type, except for <C>,<I> or <F>, which
indicate dynamic char (=byte), int or float vector pins.
2. "data": in this mode, touching a connector with the
mouse pointer will pop-up a little window showing the types and the values
of the pins in the connector (if the connector holds to many values to
display, again only an initial and final portion will be shown). Leaving
the connector or pressing the left mouse button will make the window disappear
(e.g., if you wish to draw a wire etc.).
3. "info": this is like data, but now the window will
display some information about the purpose of the selected connector. For
compiled units, these information texts can be specified in the Neo wrapper
routine (which also specifies things such as the creation and parameter
dialog window) of the unit; prog_units make the contents of a C++-comment
line behind an INP or OUT declaration visible as connector info (look again
at example#1). Container
units allow to define information texts with an annotation that can be
defined interactively at the Neo level (for an explanation, see here).
The currently active mode can be either set in the Prefs menu
or it can be cyclically switched between its three possibilities by pressing
the left mouse button while visiting a connector.
To display more data elements than 1. or 2. can provide for, you can
try one of the following:
For scalar/float/int/byte vector connectors: connect a
print_vec
unit to the connector (specify a negative dimension, if you need to connect
to a non-scalar (red,green or blue) connector). To connect to a dynamic
float connector, specify a dimension of 0. If the data is a matrix, you
can use the print_mat unit in
a similar way (however, it does not offer a dynamic input connector). If
you wish a graphical display, you can try a plot_vec
unit.
For text pin (magenta) connectors: connect a print_str
or
a printf unit to the connector.
For pixel data connectors: connect a write_pix
unit to the connector.
As a final resort, you always can set up a prog_unit
to make a customized display for the situation at hand.