![]() |
![]() |
![]() |
![]() |
7 V and the V Command Processor
This chapter describes the V Command Processor (VCP) and the V language. It includes the following sections:
Like the Network Editor, the V Command Processor (VCP) is an Object Manager interface with which you develop and debug AVS/Express applications. Unlike the Network Editor, the VCP is not a graphical interface, but rather a textual interface. Its medium is a language called the V command language (also called V code or V), a schema definition language with which AVS/Express defines objects and applications.
You write V code to perform tasks such as the following:
- Create objects and assign values to them
- Cause objects to persist
- Create networks by connecting objects
- Save networks
The VCP processes your V code, instructing AVS/Express to perform the specified tasks. Note that the VCP is not a compiler; V is an interpreted language rather than a compiled one.
The V command language consists of comments, statements, commands, and functions.
- Comments are nonoperational code that documents a V file. AVS/Express ignores them.
- V statements are the lowest level of V usage. You use them to do anything that you can do in the Network Editor; for example create objects, set properties and attributes, redefine data, create connections, export ports, and so on.
- V commands perform special applications, typically those that obtain information on objects, files, your application, or processes.
- V functions are programming-style functions such as mathematical and logical operations.
AVS/Express stores the definitions of objects (whether created in the Network Editor or the VCP) in V code in files called V files. Typically, these objects are stored in text V files, whose names, by convention, have the extension .v; for example, my_object.v. However, you can also store object definitions in binary V files, which load into AVS/Express faster. By convention, binary V files have the extension .vo; for example, my_object.vo.
The following section explains how to access the VCP and, through it, navigate your application's AVS/Express object hierarchy. Subsequent sections describe the V language itself: comments, statements, commands, and functions.
There are several ways to use V in AVS/Express:
- Enter V code at the prompt in the VCP window. In this window, you can use all features of V except comments.
- Write V code in a V file and load the file into AVS/Express. You can use V statements, functions, and comments in a V file, but you cannot use V commands.
- Write V code in a parse_V module object.
- Note: Advanced Visual Systems does not recommend using parse_V module objects, as they are difficult to debug.
This section focuses on the most simple and direct usage of V: the VCP window.
The VCP window is the window from which you launch AVS/Express. It looks like the following:
When you launch AVS/Express, the current object in the VCP window is Root, the top-level object in the current application. To indicate this, the VCP displays the following prompt:
Before you can use the VCP to create or modify an object, you must navigate to the appropriate location in the AVS/Express object hierarchy: either the object to be modified or the parent of the object to be created. Note that the VCP prompt changes as you navigate through the object hierarchy, and always indicates your current location.
A routine exists OMcreate_stream_parser, has been added that allows you to create the VCP window outside of the OMmain_loop. The declaration for this routine is shown below:
To manually create the V parser, make the following call:
The statement above creates a new VCP that takes its input from stdin that is editing the root object (OMroot_obj).
The AVS/Express object hierarchy in an application exists in levels, with Root as the top-most level, as noted previously. From Root, you can move only down the object hierarchy; from the bottom level of the application (whatever that may be), you can move only up; from all other levels, you can move either up or down.
To move down a single level in the object hierarchy, enter the name of a subobject of the current object followed by the left brace character ({). For example, you might enter the following commands to navigate from the top-most Root object to the Read_Geom object in the applications workspace area one level at a time:
OM(Root) -> Applications{
OM(Applications) -> SingleWindowApp{
OM(SingleWindowApp)-> Read_Geom{
OM(Read_Geom) ->
To move several levels down the object hierarchy in a single step, specify a compound target name consisting of the subobjects to be traversed separated by periods, followed by the left brace character. For example, you can use the following command to move directly from Root to Read_Geom:
Observe that the VCP indents the starting position of the commands you enter, to further indicate your current level in the object hierarchy.
To move up the object hierarchy, type the move-up command: a right brace character following by a semicolon ({). This command returns you to your previous location in the object hierarchy. For example, if you moved from the Root object down to the Read_Geom object one level at a time as illustrated in the first example in the previous section, you move back up to Root as follows:
Note that if you moved from Root down to Read_Geom in a single single step, as illustrated in the second example, entering the move-up command (};) moves you immediately up to Root, because this was your previous location:
Many AVS/Express objects, for example the Applications object, have their global attribute set to indicate that they are available to all AVS/Express applications. You can simplify navigating the AVS/Express object hierarchy by bypassing global objects when moving to objects beneath them. When you do this, AVS/Express prints a warning message to inform you that it is skipping levels.
For example, because Applications is a global object, you can navigate directly from the Root object to the SingleWindowApp object as follows:
OM(Root) -> SingleWindowApp{
warning: jumping from: Root to Root.Applications.SingleWindowApp
OM(SingleWindowApp)->
Starting again at Root, you can navigate directly from Root to Read_Geom in a single step by skipping the Applications portion of the compound target name as follows:
OM(Root) -> SingleWindowApp.Read_Geom{
warning: jumping from: Root to Root.Applications.SingleWindowApp.
Read_Geom
OM(SingleWindowApp)->
You can determine whether an object is global by examining its base type in the Object Info dialog window and observing whether its global attribute is set. To open this dialog window, right-mouse-click on the object in the Network Editor, then select the Info... command from the pop-up menu that appears.
For example, here is the Object Info window for the Applications object:
Many AVS/Express libraries of template objects are also global, in order to allow you to instantiate an object in the VCP without specifying its full path. Because you can bypass these libraries, you must be sure to assign unique names to the objects that you create: if you do not, and you bypass a global library object, you may inadvertently use the wrong template object without receiving a warning from AVS/Express.
For more information on global libraries, see Global Libraries on page 5-13.
A nonprimitive array object has elements that can consist of multiple values. In the VCP, you specify the name of an array element using the following syntax:
- The exclamation point (!) is the read-write modification operator (also called the read-write negation operator).
- The array_obj component is the name of the array containing the element.
- The index component is the index number of a single, specific array element. Recall that in AVS/Express, index numbering in arrays begins at 0.
Suppose, for example, that you create an array object named grp_array that contains three elements, each of which consists of two objects.
- Note: Nonprimitive arrays are limited to one dimension, so this array object is defined as a three-element, one-dimensional array.
In the Network Editor, the definition of this array object in the Object Editor is as follows:
The following sequence of V code, issued in the VCP window, accesses and sets various of the array elements as noted in the comment text (that is, text between a pair of forward slash characters (//) and the end of a line):
OM(SingleWindowApp)-> !grp_array[1]{ //Access element 2 of grp_array
OM(grp_array[1]) -> int = 11; //Set int subobject
OM(grp_array[1]) -> float = 11.1; //Set float subobject
OM(grp_array[1]) -> }; //Move from element 2 to SingleWindowApp
OM(SingleWindowApp)-> !grp_array[2]{ //Access element 3 of grp_array
OM(grp_array[2]) -> int = 22; //Set one subobject
OM(grp_array[2]) -> float = 22.2; //Set other subobject
OM(grp_array[2]) -> }; //Move from element 3 to SingleWindowApp
You include V comments in a V file to document the contents of the file. There are three types of comments, each with its own syntax:
A C-style comment has this format:
The /* and */ delimiters define the beginning and end of the comment; the comment text includes all characters between the delimiters. A C-style comment can appear anywhere in your V code and can span multiple lines.
AVS/Express ignores C-style comments.
A C++-style comment has this format:
The // delimiter defines the beginning of the comment; the comment text includes all characters from the right of the delimiter to the end of the current line. A C++-style comment can appear anywhere in your V code but it cannot span multiple lines.
AVS/Express ignores C++-style comments.
A special comment is a comment that AVS/Express tracks, rather than ignoring it as it does C-style and C++-style comments. AVS/Express defines this type of comment as an object (specifically, the child of the current object) and keeps track of it, displaying it in the Network Editor and saving and restoring it along with the current object.
The simplest version of a special comment has this format:
The /*= and */ delimiters define the beginning and end of the comment; the comment text includes all characters between the delimiters. For example:
You can specify a size and offset for a special comment by using the following more detailed format:
The parameters specify the width and height of the comment and its x and y offsets. The units for all four parameters are in the same coordinate system as the NEx, NEy, NEwidth, and NEheight properties (pixels on most systems). For example:
In this example, the parameters specify a comment that is 100x50 units in size and is offset 30 units in both the X and Y directions.
AVS/Express assigns unique names to the special comments that it creates. To list your special comments, use the $list command; for example:
To delete a comment, use the delete (-) operator; for example:
For more information on the $list command and the delete operator, see V Statements on page 7-11.
You use V statements to create, modify, and delete objects, first navigating to the appropriate location. A V statement consists of one or more clauses, separated by separator characters and terminated by a semicolon.
When using V statements, observe the following general rules:
- A V statement can start anywhere on a line.
- A V statement can start on a line on which a previous V statement ends.
- A V statement is not restricted to a single line; it can continue across multiple lines. You can continue a character string literal to another line, but the newline character is considered a part of the string.
- The clauses in a V statement must appear in the order shown.
- Separate clauses with spaces, tabs, or newlines. You can insert any number of them between clauses. Certain clauses require special characters that also act as separators; for example, the properties clause is enclosed in angle brackets (<>). (For details, see the clause descriptions later in this section.)
- AVS/Express is case sensitive; therefore, you must be careful how you specify clauses. For example, you cannot specify a type of int as Int.
Except for attributes, properties, and reference mode, the syntax of V statements is very similar to C-language syntax. The syntax varies depending on whether you are using the statement to create, modify, or delete an object.
- Note: The syntax of V statements also varies slightly depending on whether you use them in the VCP or in a V file.
The V create statement creates a new object. It has the following syntax:
type+type...+attribute+attribute...
[ref_mode ]
object_name
[properties]
[array_decl]
[subobject_decls]
[value_expr]
For descriptions of create statement clauses, see Clauses on page 7-12.
When you use a V statement to create an object, you create an object that is an immediate subobject of the current object. For example, the following V statement creates x as an immediate subobject of grp1:
You must assign at least one type to an object. The object inherits the characteristics of its type, including attributes, mode, properties, array declaration, subobjects, and value expression. Any characteristics that you specify in a create statement override any inherited characteristics.
You can create multiple objects of the same type at the same time using a single V statement. To do this, separate the object definitions with commas and place the terminating semicolon at the end of the last object's definition. For example, the following V statement creates the three integer objects x, y, and z:
You can create an object that inherits from multiple object types, by specifying all of the types, preceding all but the first with the merge + (merge-plus) operator. In this example, the two_groups object contains copies of the grp1 and grp2 subobjects.
You can use the V create statement to replace an existing object with a new object. Simply navigate to the parent object of the object to be replaced, then specify its name in the V create statement. AVS/Express replaces the existing object with the new object. If you want only to modify the object's definition, use the V modify statement instead (see The V Modify Statement on page 7-15.)
The following table describes clauses in the V create statement syntax.
Table G-1
The object's properties. Place the specified properties in angle brackets (<>) and separate multiple properties with commas. The properties clause begins and ends with opening and closing angle brackets (<>) and contains one entry for each property, with entries separated by commas. You can use either of the following formats for an entry:
The object's subobjects. Macro, group, and library objects can have subobjects, but primitive objects cannot. The subobject clause, following, begins and ends with opening and closing braces and contains one declaration for each subobject, with declarations separated by semicolons:
An expression that assigns a value or creates a connection. For details and examples, see Value Expressions on page 7-20.
Creating a primitive object. This example illustrates a series of V commands and statements, issued in a VCP window, that perform the following tasks:
Here are the required V commands and statements:
OM(Root) -> Applications{
OM(Applications) -> SingleWindowApp{
OM(SingleWindowApp)-> int &my_obj [2]; // creates my_obj
OM(SingleWindowApp)-> my_obj = {10,20}; // sets its values
Creating a group object. This example illustrates a V-code definition of a group, stored in a V file. The definition creates a group object named grp1, which contains three float objects and an int object.
Creating an object that inherits subobjects. This example illustrates a V-code definition of a group, stored in a V file. The definition creates a group object named grp2 whose type is grp1 (defined in the previous example). The grp2 group object inherits grp1's subobjects (x, y, z, and a). In addition, the definition creates an additional subobject named w and modifies the inherited subobjects x and y:
grp1 grp2{
float w; // create w
x<NEportLevels=2> = 1; // modify NEportLevels property of x
y => varx; // create a reference from y to varx
};
- Note: In the example above, varx need not exist yet. When you create varx and set it to a value, y is set to the same value automatically because of the connection.
The V modify statement modifies an existing object. It has the following syntax:
[ref_mode ]
object_name
[type+type...+attribute+attribute...]
[delete_atts]
[properties]
[array_decl]
[subobjec_decls]
[value_expr]
For descriptions of modify statement clauses, see Clauses on page 7-16.
When you use a V statement to modify an object, you change the definition of the object. Only those clauses that you specify in the statement are modified; all others are unchanged. You can use a V modify statement on any of the following objects:
- The current object
- An immediate subobject of the current object
- Using a compound path name, any lower-level subject
Suppose, for example, that you create the object c1, then change its (inherited) subobject x as follows:
Now suppose that you are in the VCP window and want to modify subobject x. You can do this in either of two ways:
Note that you cannot use a V modify statement to change the name of an object. Instead, you must use the V command $set_obj_name; for example:
You cannot use the V modify statement to replace an existing object with a new object. If this is what you want do do, use the V create statement instead (see The V Create Statement on page 7-11.)
The following table describes clauses in the V modify statement syntax.
Table G-2
Previously assigned attributes to be removed from the object. Precede each attribute with the attribute - (attribute-minus) operator. This example removes the notify attribute from x:
Additional properties to be set or modified for the object. Place the specified properties in angle brackets (<>) and separate multiple properties with commas. The properties clause begins and ends with opening and closing angle brackets (<>) and contains one entry for each property, with entries separated by commas. You can use either of the following formats for an entry:
Subobjects to be added to, modified for, or deleted from the object. Macro, group, and library objects can have subobjects, but primitive objects cannot. The subobject clause, following, begins and ends with opening and closing braces and contains one declaration for each subobject, with declarations separated by semicolons:
A new value expression for the module. It replaces the value expression previously assigned to the module. For details and examples, see Value Expressions on page 7-20.
The V create statement deletes an existing object. It has the following syntax:
The object_name argument specifies the name of the object to be deleted. You can delete either the current object, one of its immediate subobjects, or (using a compound path name) any lower-level subobject. Note that object names are case sensitive.
Creating an object and deleting its subobject. Suppose that you create the macro mymacro, which contains three subobjects, as follows:
The following V code deletes the geom_1 subobject:
Navigating to and deleting an object. This example illustrates a series of V commands and statements, issued in a VCP window, that perform the following tasks:
Here are the required V commands and statements:
OM(Root) -> Applications{
OM(Applications) -> SingleWindowApp{
OM(SingleWindowApp)-> -my_obj; //deletes my_obj
A value expression is a C-style expression that assigns a value or creates a connection. Each value expression begins with an assignment operator (=) or a connection operator (=>), to specify the type of operation. Value expressions are categorized as either scalar value expressions or array value expressions.
A value expression always begins with either an assignment operator (=) or a connection operator (=>).
- An assignment operator assigns a value to an object. The syntax of a value expression that uses an assignment operator is as follows:
- Using the assignment operator, assigns the object's value.
- A connection operator (also called a reference operator) creates a connection. The syntax of a value expression that uses a connection operator is as follows:
- Using the connection operator, references the object.
Both assignment and connection operators can accept either constant values (for example, the integer value 32) or multioperand values (for example, the expression 3 * val1).
The following simple example illustrates the assignment and connection operators. Suppose that you enter the following V statements in the VCP window:
The first statement uses the assignment operator; the second statement uses the connection operator. Because e int1 and int2 are primitive objects, you can assign values to them directly. After the VCP processes these statements, these results appear in the Network Editor:
Suppose that you now change the value of int2 using the following statement:
After the VCP processes this statement, these results appear in the Network Editor:
Observe that changing the value of int1 also changed the value of int1 (the connection is a read-write connection).
Scalar value expressions (also called scalar expressions) return a scalar value, either constant (for example, the integer value 32) or multioperand (for example, 3 * int1). Here are some simple examples of scalar value expressions:
Scalar value expressions can include any of the tokens described in this table.
Table G-3
Note that scalar value expressions can appear in contexts other than V statements; for example, in the declaration of an array's dimension or the definition of a connection for a group with reference mode set to by-reference or by-pointer. The following V statement specifies that camera_in references (connects to) the view.picked_camera object:
Array value expressions (also called array expressions) return an array value of a particular dimensionality, either constant (for example, {32, 34, 34}) or multioperand (for example, 3*array_1). Here are some simple examples of array value expressions:
int z => 4*max(a,b,c); // Connects to a multioperand expression
int w[] => {x,y,z}; // Connects to an array of objects
An array value is a sequence of scalar values, each corresponding to an element in an array object. (This section assumes that array objects are arrays of scalar values and not arrays of groups.) For example, the following are equivalent:
- int array_obj[2][3] = {0,1,2,3,4,5};
- int first_array[2] = {0,1};
int second_array[2] = {2,3};
int third_array[2] = {4,5};
int array_obj[2][3] = {first_array, second_array, third_array};The following commands have a somwhat surprising effect; the second command redimensions array_obj to be a 1 by 2 array and sets all the array elements to 5.
-> int array_obj[2][3];
-> array_obj[1][2] = 5;
-> $get_array array_obj
{{5,5}}To set array elements one by one, a different method must be used.
-> int array_obj[2][3] = 0; // Initialize all elements to zero.
-> $get_array array_obj
{{0,0,0},{0,0,0}}
-> int tmp => array_obj[0][0];
-> tmp = 1;
-> $get_array array_obj
{{1,0,0},{0,0,0}}An array expression can be in the form of a mathematical expression that uses array names, if the specified arrays have the same number of elements. The following example uses array multiplication in an array expression:
OM(DefaultApplication)-> int a1[2][3] = {1,2,3,4,5,6};
OM(DefaultApplication)-> int a2[3][2] = {10,20,30,40,50,60};
OM(DefaultApplication)-> int a3[2][3] = {a1*a2*2};
OM(DefaultApplication)-> $get_array a3
{{20,80,180},{320,500,720}}
OM(DefaultApplication)-> $array_dims a3
ndim=2 [2][3]
The third command contains the array multiplication: {a1*a2*a3}. Note the use of the $get_array V command to print array values and the $array_dims V command to print dimensions and size.
Array value expressions can include any of the tokens described in this table.
Table G-4
When you create an array expression, you assign or connect values to an array object. Values can take the form of either a sequence of values (for example, {0, 25, 99, 33*my_int}) or a compatible array object. A set of rules define whether two array objects are compatible. If array_obj_A is compatible with array_obj_B according to these rules, you can make the following assignment or connection:
- Note: This section addresses primitive array objects only. Nonprimitive array objects can have only one dimension.
Following are the array compatibility rules. They assume that array_obj_A and array_obj_B have the same number of elements.
OM(SingleWindowApp)-> int array_obj_A[6] = {0,1,2,3,4,5};
OM(SingleWindowApp)-> int array_obj_B[2][3];
OM(SingleWindowApp)-> array_obj_B = array_obj_A; // allowed
OM(SingleWindowApp)-> int array_obj_A[2][3] = {{0,1,2},{3,4,5}};
OM(SingleWindowApp)-> int array_obj_B[6];
OM(SingleWindowApp)-> array_obj_B = array_obj_A; //allowed
- If array_obj_B and array_obj_A are multidimensional arrays, they must have the same number of dimensions and their sizes in each dimension must be the same.
OM(SingleWindowApp)-> int array_obj_A[2][3] = {0,1,2,3,4,5};
OM(SingleWindowApp)-> int array_obj_B[3][2];
OM(SingleWindowApp)-> array_obj_B = array_obj_A; // not allowed
--- Error detected in: module: OMmatch_dims ---
unable to match: 2D array with 2D array, [3] doesn't match [6]
--------------------------------------------------
--- Error detected in: module: OMprim ---
object: `array_obj_A' has invalid value or type for assignment to:
Root.Applications.SingleWindowApp.array_obj_B
- If array_obj_B and array_obj_A are multidimensional arrays with have the same number of dimensions and you do not specify the size in one or more dimensions of array_obj_B, then AVS/Express converts the dimension and/or size of array_obj_B accordingly.
OM(SingleWindowApp)-> int array_obj_A [2][3][2] =
{1,2,3,4,5,6,7,8,9,10,11,12}; // define 3-dim array with 12 elems
OM(SingleWindowApp)-> int array_obj_B [][][2]; // define
// 3-dim array
OM(SingleWindowApp)-> array_obj_B = array_obj_A; //make assignment
OM(SingleWindowApp)-> $get_array array_obj_B // get array elems
{
1,2,3,4,5,6,7,8,9,10,11,12
}
OM(SingleWindowApp)-> $array_dims array_obj_B // get array dims
ndim=1 [12] // converted to 1-dim array with 12 elements
- If array_obj_B is an array (one-dimensional or multidimensional), array_obj_A can be a scalar value. In this case, AVS/Express creates an array value out of the scalar value.
OM(SingleWindowApp)-> int scalar_obj_A = 8;
OM(SingleWindowApp)-> int array_obj_B[6];
OM(SingleWindowApp)-> array_obj_B = scalar_obj_A; // allowed
OM(SingleWindowApp)-> $print array_obj_B // check value of
// array_obj_B
int array_obj_B[6] = {8,8,8,8,8,8}; // AVS/Express promotes
scalar to array
- If you do not specify the size of array_obj_B, array_obj_A can be a scalar value, an array value, or a combination of both.
OM(SingleWindowApp)-> int array_obj_A[2][3] = {0,1,2,3,4,5};
OM(SingleWindowApp)-> int scalar_obj = 77;
OM(SingleWindowApp)-> int array_obj_B[][];
OM(SingleWindowApp)-> array_obj_B = scalar_obj * array_obj_A;
OM(SingleWindowApp)-> $print array_obj_B
int array_obj_B[][] = {0,77,154,231,308,385};
AVS/Express supports the use of the following types of operators in V code:
- Arithmetic operators
- Bitwise operators
- Logical operators
- Comparison operators
- Miscellaneous operators
- Read-write operators
The following table describes the AVS/Express operators, grouped by type. Note that all operators follow the C language order of precedence; use parentheses to override the default order.
The AVS/Express read-write operators-<+>, <*>, and !-perform read-write operations. All other operators perform read-only operations. For example, if you use a read-only operator in a connection value expression and then change the one of the operands' values, the other operands do not change their values to maintain the connection. Instead, the operator breaks the connection to maintain the operands' values.
Suppose that you create two objects and connect them using a read-only operator:
int b = 2; // create b and assign it a value
int a => b + 3; // create and connect a
// using a read-only operator
The results appear in the Network Editor as follows:
Now, suppose that you reassign the value of a (the $print statement displays the value of b):
The results appear in the Network Editor as follows:
Observe that b retains its value of 2, but its connection with a is broken. The read-only operator does not allow b to be overwritten.
By comparison, read-write operators change the values of operands in order to maintain a connection. For example, suppose that you create the same two objects but connect them using a read-write operator:
int b = 2; // create b and assign it a value
int a => b <+> 3; // create and connect a
// using a read-write operator
The results appear in the Network Editor as follows:
Now, suppose that you reassign the value of a (again, the $print statement displays the value of b):
The results appear in the Network Editor as follows:
Observe that in this case, b changes its value to 5 and maintains its connection with a.
If you use more than one read-write operator in a connection, the operators change the value of the leftmost operand to maintain the connection. Suppose, for example, that you use the following statements to create two objects and connect them using multiple read-write operators:
int b = 2; c = 3; d = 4; // create b, c, and d and
// and assign values to them
int a => b <*> c <*> d; // create and connect a using
// two read-write operators
The results appear in the Network Editor as follows:
Now, suppose that you reassign the value of a (the $print statement displays the values of b, c, and d):
a = 37; // reassign a the value 37
$print b // check the value of b
$print c // check the value of c
$print d // check the value of d
The results appear in the Network Editor as follows:
Observe that only b changes its value to maintain the connection.
The ! operator is the read-write modification operator, which always represents a read-write operation. It is so named because it maintains a connection by modifying its operands.
- Attempting to set the value of the ! operator to a non-zero value results in setting the operand to 0.
- Attempting to set the ! operator to 0 sets the operand to 1.
The read-only operators take precedence over the rdonly property of a referenced object. For example, suppose that you create two objects and connect them using a read-only operator:
int int1 = 35; // create int1 and assign it a value
int int2 => int1 +5; // create and connect int2
// using a read-only operator
The results appear in the Network Editor as follows:
Now, suppose that you reassign the value of int2:
The results appear in the Network Editor as follows:
Observe that the read-only operator breaks the connection in order to maintain the value of int1. However, a different result occurs when you create the same two objects and connect them using a read-write operator, but then set the rdonly property:
int int1 = 35; // create int1 and assign it a value
int int2 => int1 <+> 5; // create and connect int2
// using a read-write operator
int1<rdonly=1>; // set the rdonly property of int1
$print int1 // check the value of int1 and
// verify that rdonly is set to 1
The output of the $print command, following, confirms that the rdonly property is set.
The results appear in the Network Editor as follows:
Now, suppose that you reassign the value of int2:
The output of the $print command, following, shows that the value of int2 has been changed to 39.
The results in the Network Editor confirm the change in value and show that the connection has been maintained:
You typically create a read-only connection to a mathematical expression so that the connection breaks when you attempt to change the value of the object. This is appropriate because most mathematical expressions are not generally defined in the reverse direction. For example, if you set c to the value of the expression a + b, you cannot then change c because you do not know whether you must change a, b, or both to maintain the expression.
Alternatively, you can construct a dummy mathematical expression such as a + 0. This technique is sometimes useful for making transient one-way connections.
You use V commands to perform special operations such as obtaining information on objects (including V files), setting various types of values, saving and loading projects, testing and debugging, and defining conditional code.
A V command has the following syntax:
In this syntax, command_name_string identifies a particular command and arg1 ... specifies one or more command arguments. Not all V commands require arguments: a few take none, most take one, and some take more than one (for details, see Command Summary on page 7-36). Note that unlike a V statement, a V command is not terminated by a semicolon.
When using V commands, observe the following general rules:
- A V command can start anywhere on a line.
- A V command is restricted to a single line; it cannot continue across multiple lines.
- V commands are case sensitive. For example, you cannot specify $print as $Print.
The following sections discuss two special topics relevant to V command usage.
Most V commands take at least one argument, and those that do typically take an object name as one of their arguments. An object-name argument is usually optional and defaults to the current object. In the command descriptions later in this section (see Command Summary on page 7-36), optional arguments are enclosed in brackets; for example:
If you specify a simple object name, the specified object must be a subobject of the current object. However, you can specify a lower-level subobject in one of the following ways:
OM(Root) -> Applications{
OM(Applications) -> SingleWindowApp{
OM(SingleWindowApp)-> higher_group{
OM(higher_group) -> $print my_group
group my_group<NEdisplayMode="open",NEx=319.,NEy=55.> {
int int<NEportLevels=1> = 22;
float float<NEportLevels=1> = 98.2;
};
- In this example, you navigate from the SingleWindowApp object to its higher_group subobject (the parent of my_group), then specify the $print my_group command.
- Invoke the command from the current location in the object hierarchy, but specify a compound path name to the subobject. For example:
OM(Root) -> Applications{
OM(Applications) -> SingleWindowApp{
OM(SingleWindowApp)-> $print higher_group.my_group
group my_group<NEdisplayMode="open",NEx=319.,NEy=55.> {
int int<NEportLevels=1> = 22;
float float<NEportLevels=1> = 98.2;
};
- In this example, you remain at the SingleWindowApp object, but specify the command as $print higher_group.my_group.
You can redirect the output of any command to a file by specifying UNIX-style redirection at the end of the command. The default directory is the directory in which AVS/Express started; however, you specify a different directory using a more explicit path name. For example, the following V command redirects the output of the $save command to the specified file:
The $save command prints an object's V definition; therefore, using $save with redirection saves an object's V definition to a file. This technique is equivalent to selecting Object->Save Objects... in the Network Editor.
- Note: This technique works on both UNIX and Windows systems.
This section summarizes V commands. Each of the following sections contains a specific group of commands, as follows:
- Printing object definitions
- Printing object values
- Printing and setting other object characteristics
- Printing and setting object references
- Saving and loading projects
- Testing and debugging
- Controlling execution
- Making code conditional
- Miscellaneous V commands
For reference descriptions of these commands, see the AVS/Express online help.
Command arguments appear in italic type and, if optional, are enclosed in brackets.
Table G-2
Prints the values of a subarray of elements of the specified array object. The array cannot be an array of group objects.
Table G-5
Saves the current project to the specified (or default) project directory. This command is equivalent to the Project->Save command in the Network Editor.
Note: Avoid using this method to save your template objects. Instead, save the libraries that contain them. For more information, see Templates and Library Objects on page 5-11.
Saves a compiled project to a particular project directory, using the specified object(s) and one or more of the following options:
Table G-6
Table G-7
Table G-8
Table G-9
This section describes V functions (also called built-in functions). Each of the following sections contains a specific group of commands, as follows:
Each V function takes one or more arguments (shown in italics) and returns a value. You can use V functions in either the VCP window or a V file.
- Note: In the examples that appear in some function descriptions, the OM prompt is shown as -> and intevening spaces between the prompt and V code have been removed, in order to improve readability. However, relative levels of indentation have been maintained.
Mathematical functions operate on any numeric data type. They return the appropriate data type, performing any necessary data-type conversion. When using a mathematical function in a value expression, note the following:
- In a scalar value expression, each argument must itself be a scalar value expression.
- In an array expression, each argument can be either a scalar-value expression or an array value expression.
AVS/Express supports the following mathematical functions in V code:
Table G-1
AVS/Express supports these logical functions in V code:
When using an array function, note the following:
- Functions that return a single value can be used in a scalar value expression or an array value expression. Functions that return an array can be used only in an array value expression.
- Array function arguments are typically array expressions such as array literals or references to array objects. However, they can be scalar expressions, in which case they are treated as one-element arrays.
- You can use a set of scalar expressions in an array function such as max_array by using an array literal to present them as a single array.
AVS/Express supports the following array functions in V code:
Table G-3
Combines the specified array objects into a single array and returns that array. For details and examples, see The combine_array Function on page 7-52.
Returns a one-dimensional array of the maximum value in each column in the specified array object. You specify the optional flag and null_val arguments only if the array contains null values. In this case:
Returns a one-dimensional array of the minimum value in each column in the specified array object. You specify the optional flag and null_val arguments only if the array contains null values. In this case:
The combine_array(arr1,arr2,...) function performs a complex operation that requires some special discussion and examples. It combines the elements of the specified array objects into a single array object. In order to accomplish this:
- The source arrays must all have the same number of dimensions (n, in this discussion).
- The source arrays must all have the same number of elements in their first n-1 dimensions.
This function returns an n-dimensional array, where the size of the first n-1 dimensions is the same as the source arrays and the size of the nth dimension is the sum of the sizes of the source arrays' nth dimensions.
For example, suppose that you have two arrays defined as follows:
Invoking combine_array(arr1,arr2) returns an array having the following size:
The following more specific example uses V code in a VCP window to create two arrays, combine them, and then display the result (note that the OM command prompt is shown only as -> for readability):
-> int arr1[1][2][3] = {1,2,3,4,5,6};
-> int arr2[1][2][4] = {11,22,33,44,55,66,77,88};
-> int combined[1][2][7] = combine_array(arr1,arr2);
-> $get_array combined
{
{{1,2,3,11,22,33,44},{4,5,6,55,66,77,88}}
}
AVS/Express supports the following miscellaneous functions in V code.
Table G-4
![]() |
![]() |
![]() |
![]() |