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