PROTOTYPE:
void_unit(i0...,uHost)
ARGUMENTS:
- int i0...ik
- parameters specifying interface (field
types and dimensions) of created unit
(see below)
- unitptr uHost
- unit to contain newly created instance
as a new subunit.
RETURN VALUE:
- unitptr u
- pointer to newly created instance of
a void unit with the specified input and
output fields.
DESCRIPTION:
This routine creates an instance of a void unit (i.e.
containing no subunits) which has a specified interface. The
interface is specified with the integer parameters i0...ik.
There are two different ways how the interface can be
defined:
Old Style Definition:
The old style definition is chosen, if the first parameter
i0 is a nonnegative integer. In this case, the created unit
will have i0 input fields, and their dimensions must be
specified with i0 further parameters that follow the first
parameter i0. Then, a similar sequence (i.e., a nonnegative
nr of fields, followed by their dimensions) is expected for
the definition of the output fields. The last argument
parameter is the host unit of the created unit. With this
type of definition only scalar (specify a positive dimen-
sion) and float vector fields ("packed fields", specify a
negative dimension) can be specified.
Example: void_unit(2,10,-4000,0,uHost)
will create a void unit with two input fields and zero out-
put fields. The first input field has 10 single float
pins, the second input field appears as a single pin holding
a vector of 4000 float elements.
New Style Definition:
The new style definition is more general and allows to over-
come the restriction of having fields with only pins of the
same type float. It allows to create units with input or
output fields that are composed of arbitrary combinations of
pins of the five types scalar float, float vector, byte
vector, int vector and (null terminated) text string.
Thus, as a data structure, such fields resemble C-structs,
restricted to elements of the basic data types
float, float[], unsigned char[], int[] and char*.
To use a new-style definition, the parameter sequence must
be of the form
<InputFieldDef>,<OutputFieldDef>,NST_HOST,uHost
I.e. it has to start with a (possibly zero) number
of <InputFieldDef>s, followed by a (possibly zero) number of
<OutputFieldDef>s and must be terminated by a mandatory pair
NST_HOST,uHost. Each <InputFieldDef> defines a single field
and starts with the reserved constant NST_INP. Then, for
each desired pin of the field, there must follow a pair
<Type>, <Number> that specifies the type of the pin and the
number of allocated elements.
<Type> can be any of NST_SCALAR (makes <number> single float
pins), NST_FLOAT (makes a vector pin of <number> float
elements, NST_INT (the same for int elements), NST_BYTE
(the same for unsigned char elements) or NST_STRING (makes a
pin to hold a null-terminated character string; here
<number> specifies the initially allocated number of bytes for
storing the string). For backward compatibility,
NST_SCALAR,-n is equivalent to NST_FLOAT,n, if n>0. Note
also, that the space that is allocated for strings is dynam-
ically adjusted as long as any changes to the string are
made via the NST functions
NstInpCpy(u,f,i,pcText), NstOutCpy(u,f,i,pcText),
NstInpCat(u,f,i,pcText), NstOutCat(u,f,i,pcText),
NstInpSprintf(u,f,i,iOffset,pcFmt,Args...) or
NstOutSprintf(u,f,i,iOffset,pcFmt,Args...),
that are obvious analogs of the familiar C-functions.
An <OutputFieldDef> starts with NST_OUT and is otherwise
entirely analogously defined.
Example:
u1 = void_unit(NST_OUT,NST_SCALAR 5,NST_HOST,uHost);
u2 = void_unit(
NST_INP,
NST_BYTE, 100, NST_STRING, 10, NST_INT, 3,
NST_INP,
NST_FLOAT, 5,
NST_OUT,
NST_SCALAR, 7,
NST_FLOAT, 7,
NST_HOST, uHost
);
The first definition creates a void_unit u1 with a
single output field of 5 scalar pins and would be equivalent to
the old style-call void_unit(0,1,5,uHost). The second
definition creates a void_unit u2 with two input fields and
one output field. The first input field has a vector pin of 100
bytes, a text string pin for initially 10 chars and an int
vector pin of 3 elements. The second input field has a single
float vector pin of 5 elements (and is, therefore, equivalent
to a packed field of 5 elements in earlier NST-Versions).
The output field has 7 scalar float pins (the only pin type
available in earlier NST versions) plus an additional
float vector pin, again of 7 elements.
ACCESS OF VALUES IN NEW PINs:
To access pin i of field f of a unit u, choose the
required function according to the type of the
pin from the following table:
pin type: for input pin: for output pin:
---------------------------------------------
float : fNstInp (u,f,i) fNstOut(u,f,i)
float[]: pfNstInp(u,f,i) pfNstOut(u,f,i)
int [] : piNstInp(u,f,i) piNstOut(u,f,i)
byte[] : pcNstInp(u,f,i) pcNstOut(u,f,i)
string : ptNstInp(u,f,i) ptNstOut(u,f,i)
void * : pvNstInp(u,f,i) pvNstOut(u,f,i)
pin * : pNstInp (u,f,i) pNstOut(u,f,i)
Note that those macros that begin with a letter p return a
pointer to the first data element, i.e, to access the
first element of an input float array, use
pfNstInp(u,f,i)[0] etc.
Since the former packed fields are now represented as
fields with a single float vector pin, XP(u,f,i) and
pfNstInp(u,f,0)[i] are equivalent. Likewise, Y(u,f,i)
and fNstOut(u,f,i) are the same (avoid the use of the
old style X,Y macros).
SPECIAL REMARKS:
Specifiying a pin dimension of zero creates an
undimensioned, "expandable" pin. Such a pin can be connected to
another pin of the same type, even if the dimensions differ,
provided the other pin belongs to a subunit. In that case,
the expandable pin adjusts its dimension to the dimension of
the pin to which it is connected. When this occurs, it loses
its property of being "expandable" and becomes a normal pin.
Specifying a field of zero pins creates an undimensioned,
"expandable field". If such a field is connected to another
field, any required pins are created dynamically and the
field loses its "expandable" property and becomes normal.
Again, this requires that the connected field must belong to
a subunit.
[Both features were introduced to facilitate the writing of
Neo's code generator].
A number of NST-units use the type NST_VAR in the parameter
list of void and primitive_units. This is a globally defined
type parameter that by default has the value NST_FLOAT.
Units that use NST_VAR instead of NST_FLOAT in their
parameter list thereby signal the option to make additional
versions, in which the pins that were declared with NST_VAR
have a different type. This type can be specified by simply
resetting the value of NST_VAR before the creation call of
such units [DON'T FORGET TO RESET!]. This allows to share
the same code for different interface variants of many basic
units and is used by the BYTEVERSION -macro in nst_math8
and nst_pixl8. (But note that the exec -routine usually has
to be rewritten for the new version!)
EXAMPLES:
The program somdemo.c provides an example of the use of the
void_unit-routine.
FILE:
nst
SEE ALSO:
void_unit1, void_unit2, primitive_unit,
primitive_unit1, primitive_unit2, nst_typedef
FILE
/amnt/loge/users/nistaff02/nistaff/rhaschke/nst7/man/../o.linux//../nstsrc/nst3.c