![]() |
![]() |
![]() |
![]() |
This chapter describes AVS/Express projects and processes. It includes the following sections:
- Overview
- Processes
- AVS/Express Code Generation
- Projects
- Integrating with a Microsoft Visual C++ Application
An AVS/Express project defines your development and execution environment. Whenever you work with AVS/Express, you are working in a project. A project, which serves as the framework for your working environment, includes three major components:
- Libraries are collections of template objects that are available to you for building applications.
- User code includes any user code needed by objects in the process.
- Processes include the main (express) executable process, any external processes (notably the user process), and an internal bootstrap process called base. You can create additional processes as necessary (see the next section, Creating and Compiling Processes, for details).
When you first use AVS/Express, you work in the install area's project, with its full complement of AVS/Express template objects (see Install Area Project on page 3-7). The install area project is read only and cannot be modified; you create your own projects as summarized in Creating and Compiling/Saving Projects on page 10-2.
As noted in the previous section, a project comes with the set of predefined processes, some of which are created as needed for objects. You can also create additional processes by inserting them into the the root-level ProcTemplates object in which processes are defined.
For details, see Defining Processes for Objects on page 10-12, Creating New Processes on page 10-14, and The proc.v File on page 10-26.
When working with AVS/Express, you will often need to compile processes, for example to include new or revised definitions of objects. You can compile a process either from within AVS/Express or from the command line. When you do the former, AVS/Express uses information that you provide-for example, source filenames, library dependencies, and process name-to construct a makefile and, if possible, use it to build a new executable. During the compile process, AVS/Express can also generate template source files in cases where an object's source file does not exist.
For details, see Compiling Processes on page 10-14.
You create your own projects as children of your current project. You can create a new project from any existing project (install or other), as long as it is your current (parent) project. A new project can be either a distinct project (the default) or a derived project.
- A distinct project is a copy of the parent project that defines itself as being like the parent project at the time of its (the new project's) creation. A distinct project inherits from any projects from which the parent project inherits, but inherits from the parent project only at the time of creation.
- A derived project is a copy of the parent project and therefore inherits from the parent project. A derived project is like the parent project in its current state, but changes in the new project override files inherited from the parent.
By creating derived projects, you can build a project hierarchy that is a chain of projects; for example, Project A is a derivative of Project B, which in turn is a derivative of Project C, and so forth.
AVS/Express sets up and manages projects for you, so you generally do not need to know the underlying architecture of a project to use it.
Only Developer Edition users can compile projects. As a Developer Edition user, once you understand project architecture, you can use AVS/Express to create more sophisticated projects. To do this, you will compile and save a selected set of objects into a separate project area. This mechanism allows you to build runtime versions of your AVS/Express applications that are smaller, start up faster, and depend upon fewer files, and are therefore ideal for distribution.
For details, see Saving Compiled Projects on page 10-27.
Processes contain definitions for the objects in an AVS/Express project, enable the objects' interactions, and perform operations required by the project. Any number of processes can attach to a single AVS/Express session. Each AVS/Express object in a project lives in exactly one process, but all processes see the same object hierarchy and any process can operate on any other object regardless of which process contains it. AVS/Express processes can either exist on the local host or run on a remote host.
A project comes with an express process and a base internal bootstrap process, and user processes are created as needed for objects (see Defining Processes for Objects on page 10-12). You can also create additional processes as needed (see Creating New Processes on page 10-14). The processes for a given project are defined in its root-level ProcTemplates object (see The proc.v File on page 10-26).
You must compile an AVS/Express process to use the objects it defines.
For details, see Compiling Processes on page 10-14.
The main process, named express, synchronizes all other processes. It must, therefore, start up before any other process attaches to AVS/Express and exit after all other processes detach from AVS/Express. The main process serves as a hub for the exchange of addresses among processes: when one process attempts to access an object in another process, it forms a direct socket connection to that process via the main process. If the processes are on different hosts and the hosts have different data formats, AVS/Express performs the required data conversions automatically.
The main process starts some processes automatically when you create objects that live in them. Other processes are started externally and attach to an existing session.
The following figure illustrates the process organization of the AVS/Express object hierarchy:
Any AVS/Express process can initiate an operation, but the main process controls the execution of operations through an AVS/Express object called the Scheduler. The Scheduler synchronizes operations by calling push_ctx and pop_ctx routines to push and pop contexts for them on a stack (see Contexts on page 8-11 for details). Only a single push_ctx call can be active at one time: if the Scheduler has an outstanding push_ctx call and receives another, it queues the additional push_ctx call. The process that initiated the queued push_ctx call waits on the current push_ctx call until it completes with a pop_ctx call.
AVS/Express provides a definition of a default C main in the library -lmnc and a definition of a default C++ main in the library -lmncxx. By default, these libraries are included on the link line of any process that is constructed through an AVS/Express compilation. Whether AVS/Express uses the C or C++ version depends on which compiler it uses to compile a process; this is system dependent. You can also define your own main; for details, see Defining Your Own Main Process on page 10-9.
You use the following three environment variables to specify whether a process is the main process or an external process; that is, a process that attaches to the main process:
- To specify that the process attaches to a main process, define these environment variables before the process is initialized (see Initializing AVS/Express on page 10-8) with the appropriate values.
- To specify that the process is the main process, leave them unset. On initialization, the process becomes the main process and then defines the environment variables for itself.
You can define these environment variables in several ways:
- For the main process, use the following command-line option, which writes the environment variable definitions to the specified file:
For a client process, use the following option, which loads the definitions from the specified file:
This option loads the definitions.
- Use the getenv function from anywhere within the main process to retrieve the values of these variables, then set the definitions manually in the environment of the client process.
Each AVS/Express process has the following components:
- Definitions of the modules that it contains, if any
- Its process name
- An initialization call
- An event handler
When AVS/Express compiles a process, it generates code for two functions, PREinit and BASEinit, that AVS/Express' initialization routine calls (see Initializing AVS/Express on page 10-8 for details). At initialization, PREinit and BASEinit do the following:
- Perform any process-specific initialization required by the objects in this process; for example, initializing the widget toolkit for the UI objects
- Set the name of the process
- Build a table that maps method names to the method pointers using the OMadd_named_func routine
The PREinit function is called before object definitions in the Templates hierarchy are defined and the BASEinit function after the Templates objects are defined but before any template objects are instanced.
You can add your own code to the PREinit and BASEinit functions by setting the properties pre_init_code (for PREinit) and init_code (for BASEinit). Each of these properties specifies C code that is added directly to PREinit or BASEinit functions (the string value for each must define a complete C statement). These functions are generated in the order in which objects appear in the Templates library, thus a particular library is defined after all of the libraries upon which it depends are defined.
Although PREinit and BASEinit are defined with C-scoped names, AVS/Express may compile them with a C++ compiler. Therefore, you must be sure that any functions called in the init_code and pre_init_code property values are declared before they are used. You can do this as follows:
- Set the the c_hdr_files or cxx_hdr_files property to specify a header file that declares these functions.
- Set the hdr_code property to declare the functions. This property specifies a C statement that is inserted into the value of the current out_hdr_file property (by default, process_name.h).
For example, using V code, if the library MYLIB is included in the current process, you can call the function MYLIB_init in the BASEinit function as follows:
Each process has a name, so that AVS/Express can determine which processes are running and create the right objects in the right process. The name should correspond to the name of the object defined in the root-level ProcTemplates object (see The proc.v File on page 10-26). When AVS/Express generates a process, it sets the process name automatically by code inserted into the PREinit function; for example:
You need to set the name of a process explicitly only if you are generating your own PREinit and BASEinit functions for a process that will define local objects. In this case, you must set the name of the process to the process property value set for the objects that you will define locally.
You call the OMmain_init routine (or equivalent) to initialize AVS/Express. You must make this call before you attempt to access any AVS/Express objects. Once it returns, you can create and destroy AVS/Express objects.
How OMmain_init is called varies depending on your platform. For UNIX platforms, it is called as follows:
For Windows platforms, it is called as follows:
These routines parse the command-line arguments that AVS/Express parses (you can disable them by passing in empty command line strings). If you have command-line arguments that your program recognizes, you should remove them from arguments that you pass to OMmain_init since the routine displays error messages about arguments that it does not recognize.
This routine returns a flag that indicates whether the -vcp or -novcp options were specified in the command-line arguments. The flag should be passed to the OMmain_loop routine to enable the functionality of these command-line arguments.
The following call processes events for AVS/Express processes:
The vcp_flag argument can have one of the following three values:
As noted previously, AVS/Express provides definitions of default C and C++ main processes in the libraries -lmnc and -lmncxx, respectively, and includes these libraries on the link line of any process that it compiles. If you define your own main for a particular process, you must disable the use of the default main processes as follows:
- Instruct AVS/Express to omit these libraries from the link line by setting no_main=1 on an object in your process.
- Specify the file that defines your main process using the c_src_files, cxx_src_files, or link_files properties.
See Providing Code Management Information on page 8-28.
Be sure to supply your definition in the correct language for your process. On UNIX systems, AVS/Express links your process with the C++ compiler if any objects in the process need C++, otherwise it links with the C compiler. If you are not certain which compiler your system uses, supply your definition of the main process in a C++ source file to force the use of C++ for the link.
The rest of this section discusses topics relevant to defining your own main process.
On UNIX systems, you can configure your main process to use the standard Xt event dispatch facilities (for example, XtAppMainLoop, XtAppNextEvent, or XtAppProcessEvent) instead of the routine OMmain_loop. Doing this makes it easer to integrate AVS/Express objects into existing Motif/Xt based applications. See your platform documentation for information on the XT event dispatch facilities.
In order to take advantage of this facility, you must do the following:
1. Place a call to the function EVXinit_display_xt() for each Display used in your program. This function is declared as follows:
To include a definition of this function in your main, include the header file avs/event_x.h in your program as follows:
You must place this call after you open the display but before you enter the event dispatch loop of your program; that is, before you call XtAppMainLoop, XtAppNextEvent or XtAppProcessEvent.
2. Define your own main loop, bypassing the AVS/Express main loop. Doing this prevents you from using the V Command Processor (VCP) from within this process. However, you can start up the VCP in another process that manipulates objects in the current process as follows:
The VCP available in the shell started by the base command can manipulate objects in your express process.
If you intend to use UI Kit objects in your application, you must ensure that your code and the UI Kit code share only a single XtAppContext. Currently, the only way to do this is to obtain the Widget pointer from the handle.widget subobject of a UI object used in your application. From this Widget pointer, you can use the XtWidgetToApplicationContext and XtDisplay functions to access the XtAppContext and the Display:
This example illustrates how to create a dummy shell object outside of the express project mechanism, obtain a Widget pointer from that object, and perform an EVXinit_display_xt call. It uses the example source code that follows the set of instructions.
1. Save the example source code at the end of this section (see Example Source Code) into your project directory in a file called xtmain.cxx.
3. Select the Workspace_1 object (or any library that defines objects for the express process) for dummy.v.
The resulting express process uses the xtmain.cxx file as its main program.
---- xtmain.cxx:
#include <stdlib.h>
#include <avs/om.h>
#include <avs/event_x.h>
#include <X11/Intrinsic.h>
void
main (int argc, char **argv)
{
int vcp;
OMobj_id shell_id, widget_id, macro;
Widget widget;
vcp = OMmain_init(argc, argv);
OMpush_ctx(OMroot_obj,0,0,0);
macro = OMcreate_obj_from_path("macro", "my_macro", OMinst_obj);
shell_id = OMcreate_obj_from_path("UIshell", "xt_shell", macro);
OMset_name_int_val(shell_id, OMstr_to_name("visible"), 0);
OMpop_ctx(OMroot_obj);
widget_id= OMfind_str_subobj(shell_id,"handle.widget",OM_OBJ_RD);
if (OMget_ptr_val(widget_id, (void **)&widget, 0) != 1)
widget = NULL;
if (widget == NULL) {
fprintf(stderr,"can't get widget\n");
exit(-1);
}
EVXinit_display_xt(XtDisplay(widget));
XtAppMainLoop(XtWidgetToApplicationContext(widget));
OMexit(0);
}
When defining your own main process, you can define functions that AVS/Express will call in response to system events such as a time-out interval, an idle event, or an event on a file descriptor. You do this using the Object Manager API routine EVadd_select.
For details, see the reference description of EVadd_select in the AVS/Express online help.
There are two ways to make a process exit.
The process that issues this call exits using the exit system call with the status code provided as the first argument.
- To make a specific process exit, call the C API routine OMprocess_exit (or C++ equivalent), as follows:
The process specified by the proc_id argument exits with the status specified by the status argument. This call is most useful when you want an external process to make the main process exit. Note that the process ID of the main process is always 0.
For details, see C and C++ API Routines on page 9-5 and the reference descriptions of these routines in the AVS/Express online help.
Each template object in AVS/Express belongs to exactly one process. The process for an object is set using the process property, which specifies the string name of an object defined in the root-level ProcTemplates object (see The proc.v File on page 10-26). This property is inherited as you move down the object hierarchy: if it is set on a library, each module in the library is placed in the specified process unless you override this value by setting the process property on the module itself to another process). If process property is unset for both an object and its parent, the object is placed in the default process, which is the first process in the ProcTemplates list (by default, the express process).
The following rules specify in more detail how the process for a particular object is set. Note that the order of these rules is significant: the first rule that applies to the object is used to set its process.
1. If the process property is set on the object itself or the template object from which it was created, the object is placed in the specified process.
2. If the process property is set on an ancestor of the object, the object is placed in the specified process.
3. If the process is set on an ancestor of a template object from which the object was created, the object is placed in the specified process.
The following diagrams illustrate these rules. In each figure, the circles represent objects in the Templates hierarchy, belonging to processes as noted in the key.
If the library that contains C and D is given an explicit process setting, C no longer inherits the process from its superclass B and is instead assigned to the process of its parent.
Note that when you change the process on an object, you must recompile the affected processes:
- The process that previously contained the object has a stale copy of the code for that object, which should be removed.
- More importantly, the process that now contains the object needs its definition.
See the next section, Compiling Processes, for details.
As noted previously, a project comes with an express process and a base internal bootstrap process, and user processes are created as needed for objects (see Defining Processes for Objects on page 10-12). Using the VCP, you can also create additional processes as needed while running AVS/Express, by inserting them into the root-level ProcTemplates object in which processes are defined (see The proc.v File on page 10-26).
To create a new process, enter the VCP window and navigate to the ProcTemplates object, then define your new process as in the following example:
When you save the project that contains this new process, your new proc.v file looks like the following:
When you compile this process, AVS/Express generates filenames with your process name as the identifier. Advanced Visual Systems recommends that you assign process names that have fewer than seven characters, in order to avoid problems on machines that limit filenames to eight or fewer characters.
You must compile an AVS/Express process to use the objects it defines. The simplest way to compile a single, specific process other than the express process is from within AVS/Express. Using information that you supply-source filenames, library dependencies, process name-AVS/Express compiles the process by constructing a makefile and, if possible, executes it. (If necessary, AVS/Express also generates source files that contain prototype source code for methods.) On most platforms, AVS/Express compiles a process dynamically, to make use of shared AVS/Express libraries. The next subsections describe compiling with shared libraries and compiling a single, nonexpress process.
Note that you cannot compile either of the following from within AVS/Express:
You must perform these compilations from outside AVS/Express, as described later in this section; however, both use AVS/Express-supplied compile functionality to simplify the task.
You can choose to compile a process manually without using AVS/Express compile functionality of any kind; however, this is a complicated task because you must perform independently each of the tasks that an AVS/Express compilation performs for you.
Shared libraries offers several notable benefits, including smaller executable size and drastically reduced link times when relinking your processes. AVS/Express uses shared libraries on all platforms except AIX, Digital UNIX, Windows NT, and Windows 95. You use shared libraries by dynamically linking to them (the default) at compile time.
Advanced Visual Systems recommends that if your platform supports shared libraries, you use dynamic linking. However, you can use static linking (as described later in this section), in which case your application is no longer dependent on AVS/Express external libraries.
Dynamic linking is the default behavior. If a dynamically linked application references the libmods.s, libmods.o, or libmods.o shared library, AVS/Express dynamically loads the image file reader and writer libraries, contained in the libmods.a library archive.
Static linking, which you must set explicitly, enables you to avoid using shared libraries at compile and/or link time. To do this, you set the NO_DLLIBS environment variable to a nonzero value for the make process (the recommended values are t or l). When you do this, the AVS/Express shared libraries are neither generated when compiling nor included on the link line when linking, and your process is linked with static libraries instead.
You can set NO_DLLIBS in any of the following ways:
- In your project's templ.v file in the build_cmd property
- In the environment of the shell under which AVS/Express is running
Note: Setting NO_DLLIBS does not create a completely statically linked executable. It just prevents linking with the AVS/Express shared libraries. System libraries, X libraries, and so on are still linked dynamically when available.
Compiling a single process other than express from within AVS/Express is a straightforward procedure that consists of the following steps:
AVS/Express executes the compilation by performing the following tasks:
AVS/Express creates the makefile by navigating all branches of the object hierarchy under Templates, except where it finds the compile_subs=0 property, looking for objects that are part of the process being compiled. The makefile is called process_name.mk. If a file by this name already exists in your project directory, AVS/Express removes it and creates a new one.
While creating the makefile, AVS/Express sends informational and error messages, if any, to the startup window (in which the V Command Processor appears).
2. Generate the files process_name.c, xprocessname.cxx and process_name.h and place them in your project directory.
3. If a method's source file does not exist and the method specifies the src_file property, generate template source files.
See Writing Target Functions on page 8-15 for details.
See Introduction on page 9-2 for details.
When AVS/Express runs make on the makefile, it pops up a window in which to display any compile-time messages.
6. If the make is successful, place the resulting executable in a machine-specific subdirectory of your project's bin directory.
For a description of error messages that may appear during this procedure, see Common Error Messages on page 10-17.
Because you cannot compile a process while it is executing, you cannot compile the express process from within AVS/Express. Instead, you compile it as follows:
1. Run Project->Compile. As for a single nonexpress process, AVS/Express prepares a makefile named express.mk for the express process and places it in your project directory. However, because the express process is running, it does not run a make on the makefile.
Note: Once the express process compiles, be sure to run the express process that you just compiled rather than the express process in the AVS/Express install directory.
With one exception, you can compile at one time all processes in your project (as defined in the root-level ProcTemplates object; see The proc.v File on page 10-26). The exception is that you cannot include the base internal bootstrap process, because you use it to perform the multiprocess compilation, as follows:
Note that you can also use the base process to build a specific process from outside of AVS/Express as follows:
Your XP_PATH environment variable must be set properly (for example, through the avsenv file) for this to work.
For details see The avsenv File on page 10-23.
This section describes common error messages that AVS/Express may return when you use it to compile a process.
The following error message may appear in the startup window when you compile a process:
This message means that AVS/Express has created the makefile for this process, but cannot run a make on it because the specified process is currently executing. AVS/Express typically returns this message in the following circumstances:
The following types of error messages may appear in a popup window while the makefile is being processed. (The actual message text depends on the operating system.)
This message, from the linker, indicates that a required function is missing.
- If the undefined function belongs to an object that you added, this message may mean that you did not set a c_src_files (or similar) property.
- If the undefined function belongs to an object in one of AVS/Express' kits, your objects may have a dependency that you did not account for by setting the libdeps property.
See Providing Code Management Information on page 8-28.
You are compiling a function that receives pointers to a C structure that you have defined and to a bitmask structure generated by AVS/Express. The generated file includes the header file where your C structure is defined, so you do not have to include it again in the function's source file.
This section provides detailed information about certain aspects of AVS/Express process compilation. You do not need this information for relatively straightforward compilations, but it may be helpful when you implement and debug more complex projects.
The AVS/Express compilation process contains two main stages: code generation and process build.
- During the code generation stage, AVS/Express generates the code and makefile needed to build the process. To do this, AVS/Express makes two passes through the Templates hierarchy:
- During the process build state, AVS/Express simply invokes your system's make command for the generated makefile.
This section provides detailed information about the code generation process. For information about the process build, see the make command documentation available with your system.
In Pass 1, AVS/Express determines what objects belong in what processes, using the rules discussed in Defining Processes for Objects on page 10-12, and marks the objects needed by the process to be compiled. When AVS/Express marks an object as needed, it also marks the containing library. For example, if the process needs the UIbutton object, AVS/Express marks both this object and the UI library that contains it. Note that other objects in a marked library (for example, UIshell in the UI library) are marked only if the project specifically needs them. To continue the previous example, AVS/Express marks UIshell, another object in the UI library, only if it is needed.
Note that if you compile using Project->Save Compiled Project instead of Project->Compile, this pass is modified so that only the objects that select are marked as needed. As a result, the process contains only a subset of the objects defined for this process in templ.v, and templ.v is not explicitly modified.
Two properties affect the way in which objects are marked as needed:
- The libdeps property affects how AVS/Express handles library dependencies.
- The need_objs property affects how AVS/Express handles dynamic object dependencies.
The libdeps property takes a list of names of AVS/Express template objects. In its object-marking pass, AVS/Express marks these objects but not their subobjects as needed by the process. This property is useful for guaranteeing that AVS/Express marks the link files specified by one library whenever another library is needed by a process. This is necessary only when those AVS/Express objects do not express this dependency directly.
For example, if you define a library that calls the FLD library but does not contain any FLD objects, AVS/Express may report that the FLD routines are undefined when you link. To fix this problem, set the libdeps property as follows to indicate this dependency:
The need_objs property also takes a list of AVS/Express objects. In its object-marking pass, AVS/Express marks these objects and their subobjects as needed by the process. You set this property on a module that creates objects dynamically to ensure that AVS/Express places them in any compiled project that contains the module.
For example, if you write a module that dynamically creates a UIbutton object and include the module in a compiled project, AVS/Express may report that the UIbutton object was not included in your project. To fix this problem, set the need_objs property as follows to indicate this dependency:
During the code generation stage, AVS/Express generates initialization code, header definitions, source definitions, and the process makefile.
- AVS/Express inserts initialization code, which is executed when the process is started, into the function BASEinit. This function is put into the file process_name.c if the file contains only C definitions, or the file process_name.cxx if it contains any C++ definitions.
- By default, AVS/Express also places all source definitions into the file process_name.c or process_name.cxx, as appropriate. You can modify this default by setting the out_src_file property.
- By default, AVS/Express puts all header definitions into the file process_name.h. You can modify this default by setting the out_hdr_file property.
- AVS/Express puts generated code for the process makefile into the file process_name.mk.
In Pass 2, AVS/Express generates code for objects marked as needed during Pass 1; specifically:
- Methods marked as needed. This code includes:
- Code Management Properties set on any objects that are marked as needed. The following properties affect what code is generated:
The build_dir property specifies the build directory for an object and its subobjects. If this property is specified with a relative pathname, it is taken to be relative to the project directory. If the build_dir property is unset for an object or its ancestor, AVS/Express uses the project directory as the build directory.
All build files processed for an object and its subobjects are taken to be relative to the current build directory. T his includes values taken from the c_hdr_files, cxx_hdr_files, c_src_files, cxx_src_files, src_files, and link_files properties.
The c_src_files and cxx_src_files properties specify one or more source files required for processes that need this object. AVS/Express addes rules for constructing object files from the source files to the process makefile and adds the resulting object files to the link line for the process. (Recall that these files are specified relative to the current build directory.) If a process needs an object for which the cxx_src_files property is set, AVS/Express uses the C++ linker to link that process.
The src_file property also specifies one or more source files. It implements similar logic on its arguments except that it determines the language of the files from the filename suffixes. The omethod and cxxmethod base types also use current value of the src_file property to determine whether to generate target-function prototypes (see Target Functions on page 8-15 for details). You can turn off prototype generation by setting the use_src_file property to 0 on an object for which the src_file property is set.
The c_hdr_files and cxx_hdr_files properties specify one or more header files that contain the definitions needed to compile this object or its subobjects. Setting these properties puts an #include statement in the file that contains generated header definitions for this object, either the file specified by the out_hdr_file property, or the default file process_name.h if out_hdr_file is unset.
If AVS/Express can find an absolute path to each header file (recall that it looks relative to the current build directory), it adds the files to a list used to generate makefile dependencies for object files in this process. If it cannot find the header files, it includes them using a pathname specified specified from the property definition. AVS/Express does not treat this behavior as an error, nonetheless this does not generate proper dependencies.
AVS/Express project architecture is accessible to all users, and all users will find the discussion of project architecture in this section useful. However, because only Developer Edition users can save projects, it is especially pertinent to them. A Developer Edition user who thoroughly understands project architecture can use AVS/Express to create more sophisticated projects; for example:
- A project that completely replaces the install area project
- A project that includes only a small subset of the install area project's libraries
- A project with a completely different appearance in the Network Editor
This section describes AVS/Express project architecture, then (for Developer Edition users) explains how to use Save Compiled Project to save a custom project.
A project is based in a project directory. The project directory hierarchy contains all of the files and directories required by the project. At absolute minimum, it contains a directory called v, which contains the v files needed for the project. However, it typically contains much more than a v directory, including files and directories such as the following:
- an avsenv file
- makefiles
- project-level source files
- project-level header files
- data directories
- source-code directories
- object-file directories
AVS/Express may generate some of these files and directories as needed, and you may supply others. The following sections do not describe all of a project's possible files and directories, but do discuss typical components.
The avsenv file contains environment-variable definitions. AVS/Express generates an avsenv file in your project directory whenever you create or save a project; for example:
# WARNING: this file is program generated.
# Remove these two lines to protect the file from overwrites.
XP_PATH=/home/users/me/proj1 /home/express
- The first two lines identify the file as an AVS/Express-generated avsenv file rather than a user-supplied file. Whenever the associated project is saved, AVS/Express regenerates this file if it finds these two lines.
- The next line assigns a value to the XP_PATH environment variable.
You can modify an avsenv file by adding environment variable definitions as required; they take effect for AVS/Express only. If you do modify this file, be sure to remove the first two lines so that AVS/Express does not regenerate the file, thus removing your modifications, the next time you save the project.
Whenever AVS/Express starts up, it looks for an avsenv file in the following places in the order listed, and uses the first file it finds:
- The directory specified by the -project command-line option, if any.
- The current directory.
- (UNIX systems only) Your home directory.
- The directory two levels above the directory that contains the AVS/Express executable. For example, if the executable is in the directory /home/express/bin/hp, AVS/Express looks in the directory /home/express.
If you are working with the makefiles that are generated when building an AVS/Express project on a Windows platform, you should note that the automatically generated macros $(XP_C_COMPILE_CMD) and $(XP_CXX_COMPILE_CMD) were changed in AVS/Express 3.1. This should have no effect on projects built in AVS/Express 3.1 or higher.
In particular, the $(XP_C_COMPILE_CMD) macro has been replaced with:
A particularly important environment variable-one required by AVS/Express whenever it starts up-is XP_PATH. The value of this environment variable is a list of project directories, specified as absolute pathnames; for example (from the previous avsenv file):
Your project's directory (if any) should be specified first, followed by the install area project's directory.
Whenever AVS/Express starts up, it looks for an definition of XP_PATH in the following places in the order listed, and uses the first definition it finds:
If AVS/Express does not find a definition, it sets XP_PATH to the directory two levels above the executable's directory. For example, if the executable is in the directory /home/express/bin/hp, AVS/Express sets XP_PATH to /home/express.
Note that when you refer to the XP_PATH environment variable in V code, you can supply an index value to indicate a particular project directory in its list. This usage has the following format:
Indexes for project directories in the XP_PATH list begin with 0 for the rightmost directory and increase by 1 as you move to the left. Recall the previous example:
In this definition, $XP_PATH<0> refers to /home/express and $XP_PATH<1> refers to /home/users/me/proj1.
The templ.v file, a V file located in the v directory, defines the contents of the Templates library which, in turn, defines all of the templates from which you can create new objects. For example:
"$XP_PATH<0>/v/templ.v" Templates {
flibrary MYLIB {
module my_module {
int p1;
omethod+notify+read update = "my_module_update";
};
};
};
The first line in this file (following) creates your project's Templates library:
Observe that the type of Templates is a filename. The $XP_PATH<0> component of the name refers to the rightmost path in XP_PATH, typically the install directory. Therefore, the entire name, $XP_PATH<0>/v/templ.v, refers to the install area project's templ.v file. As a result, the Templates library for your project begins with all of the objects in the install area project.
The subsequent lines define additions and modifications for your project. In this example, the project contains an additional library named MYLIB and and a simple module named named my_module that is defined in that library.
The proc.v file, a V file located in the v directory, creates a root-level object called ProcTemplates that defines a project's processes. The relevant (noncomment) portion of the install area project's proc.v file is as follows :
The project consists of three processes named as express, user, and base. The executable is given the same name as the name of the process object.
Here is a version of proc.v as it might appear in your project directory:
Observe that the type of ProcTemplates is a filename. The $XP_PATH<0> component of the name refers to the rightmost path in XP_PATH, typically the install directory. Therefore, the entire name, $XP_PATH<0>/v/proc.v, refers to the install area project's proc.v file. As a result, the ProcTemplates object for your project starts off with all of the processes of the install area project. You can manually insert additional lines to create additional processes; for example:
Two V files in the V directory contain information that defines the Network Editor libraries.
- The libs.v file includes files that define the libraries as they appear in the Network Editor.
- The lib_xp.v file describes the AVS/Express Network Editor layout. It is simply a set of NElink objects and libraries of NElink objects, one for each major library collection.
For more information on libraries, see Understanding Libraries on page 5-11
Note: The information in this section is relevant only to Developer Edition users. Visualization Edition users cannot use the Save Compiled Project command.
The default AVS/Express environment provides access to a large number of objects in the application development process. The Developer Edition of AVS/Express provides a feature, implemented as the Save Compiled Project command, that you can use to generate a project containing a subset of the objects used in the base project. There are two main advantages to using this feature:
- The compiled project is streamlined by the elimination of code associated with objects that it does not use.
- All of the V state information for the compiled project is stored in a single binary V file, reducing application startup time and the number of files required to support the project.
You should consider streamlining a project with Save Compiled Project in the following circumstances:
- When you deploy an application built entirely from AVS/Express components
- When you deploy an application built from code that creates AVS/Express components dynamically
Whenever you use the compiled project capability of this command, AVS/Express creates a separate project directory that contains local versions of the make files and configuration files that it generates for the project. This project directory also contains a local version of each AVS/Express executable needed by the objects contained in the compiled project.
The Save Compiled Project command is available on the Network Editor's Project menu. Selecting Project->Save Compiled opens the following dialog box:
As illustrated in this figure, there are three sets of controls in the Save Compiled Project dialog box:
- Project directory selection controls: a text box and Browse button combination
- Object selection controls: a set of radio buttons
- Option controls: a set of check boxes
You use the project directory controls to specify the directory for the compiled project. You can specify either a new directory or an existing directory. In the latter case, if the directory already contains a project, the new project replaces the previous project. You specify the directory either by typing its name into the text box or selecting the Browser button and navigating to it in the file-browser dialog box that opens.
There is directory, called runtime, under the "compiled project directory". The dictionary files for different languages are copied into this directory. Any files necessary for executing the runtime will be copied automatically into this sub-directory.
This used to be a manual process in Release 3.0; it is now automated in Release 4.0
You use the object selection controls to specify the core set of objects that the compiled project will contain. You can choose either of two objection-selection modes:
- Save selected objects. In this mode, the core set of objects to be included in the compiled project consists of all currently selected objects.
- Save current application. In this mode, the core set of objects includes only the current application object.
In addition to the core set of objects specified by your choice of mode, AVS/Express automatically includes any objects that the core set of objects need. For example:
- If you include a macro object, AVS/Express also includes all objects that the macro uses.
- If you include a library object, AVS/Express also includes all objects in that library.
The operation selection controls specify a number of operations that the command can perform when it executes. These operations are as follows:
This option controls whether or not AVS/Express automatically instances the objects selected for the compiled project operation when it starts up the main (express) process.
- Check it if you are using AVS/Express to generate a compiled project from a single object that contains the entire definition of the object.
- Uncheck it if your program dynamically creates the AVS/Express objects itself, or the objects you selected are libraries (it does not make sense to instance a library of objects).
This option controls whether the Network Editor is a part of the compiled project.
If you include the Network Editor, it is instanced when the main (express) process of your project is executed, just as in a normal AVS/Express session. As usual, the default creation of the Network Editor can be disabled with the -none command line option.
Since your project will contain only a compilation of system objects, the organization of the Libraries object in the Network Editor must also display a subset of the objects in the system. The current version of AVS/Express does not perform a subset operation on the existing Libraries organization for you. Instead, it creates a default v/libs.v file that displays the contents of the Templates object only. This display lists all of the libraries that are included in AVS/Express but in a very raw form. In order to get a better libraries organization, you must create your own customized v/libs.v file.
As noted previously, the Save Compiled Project command generates a single binary V file that contains the definitions of all objects needed to implement the selected set of objects. This option controls whether the V definitions are stored in a separate binary V file that is loaded when the main (express) process is started or the binary V file is directly linked into the executable of the main process.
If you select this option (that is, link the binary V file into the executable), you can produce a single standalone executable file with which to deploy the application. Note, however, that any runtime files needed by any objects that the compiled project uses are still required; for example, the runtime files that are required to use the Network Editor in an application.
There are some drawbacks to selecting this option:
- Linking the binary V file into the executable takes longer than storing it in a separate file.
- You must always relink the executable if you change the project. With a separate binary V file, you can make changes to the project that require only updating the binary V file rather than relinking and rebuilding the project.
This option controls the building of the project's exexcutable. This is on as a default.
This option automaticaly generates wrapper code for the project. This is on as a default.
IMPORTANT: The Include OLE automation support and the Compile project in ActiveX options are specilaized functions and not fully supported in AVS/Express 4.0. You should NOT use them. We cannot promise you will have reliable results and they are not supported.
- If you attempt to overwrite an existing project, you are informed of this fact and given the option to cancel.
- If you attempt to overwrite a project that is currently in use by this session, you are prevented from doing so (since the compiled project references these projects and thus will not work).
Diagnostics are available when you select Project->Compile.
You may see a warning message in this release that did not appear in the AVS/Express 3.0 release if you copied methods from the "Standard Objects" page but did not provide a new function value to replace the default method value (OMomethod_unset, OMmethod_unset, OMcmethod_unset).
This warning message can be ignored, but it provides the name of the methods that are not functional in your system.
You can eliminate the extra warning message by setting the method value to a valid function name or deleting the method from your Templates library. If you want to "deactivate" the object that this method belongs to, you can set the "compile_subs" property to 0.
When AVS/Express compiles a project, it chains it off the project directories of the original project; that is, the project that was active at compilation time. You can determine which project directories were used to create the new project by reviewing the avsenv file in the new project directory. The compiled project uses libraries and object files from these other project directories when its executable is being linked; therefore, you must also compile these other projects if they define any new code that the compiled project uses.
The following figure illustrates the files generated when you execute Save Compiled Project command with the Generate source option checked.
These directories and files are as follows:
A machine-specific subdirectory of this directory contains the object files compiled for this project. None of the files in this subdirectory tree are necessary to run an application built with this project. On UNIX machines, you can obtain the value of the $MACHINE variable for a particular platform by running the xp_mach shell script. On Windows machines, this value is always pc.
This file, generated if you compiled the project with the Build V into executable option turned off, contains the V definitions for the compiled project. It is required for running applications built from the project, and must be located in the v subdirectory of XP_PATH when you run the project.
See Build V definition into executable on page 10-30.
This file is generated if you compiled the project with the Include network editor in project option turned on. The file is a simple prototype that you can replace by a custom version.
See Include network editor in project on page 10-29.
A machine-specific subdirectory of this directory contains contains all of the process executables necessary to run this project. On UNIX machines, you can obtain the value of the $MACHINE variable for a particular platform by running the xp_mach shell script. On Windows machines, this value is always pc.
These files are generated for each process used by the compiled project. They are necessary only for compiling the project, not for running applications built with it.
This file stores the value of the XP_PATH variable used to construct the project. It is necessary for compiling the project and is necessary to run the project if any of the components it uses rely on any files stored relative to XP_PATH.
This source file, generated if you compiled the project with the Build V into executable option turned on, contains a hexadecimal description of the binary V description for the objects used by the project. It is necessary for compiling the project but not for running it.
There is a subdirectory of the Compiled Project Directory called runtime. The dictionary files for different languages are copied into this directory , and any files necessary for executing the runtime will be copied automatically into this subdirectory.
This used to be a manual process which has been automated since AVS/Express Release 3.1.
The examples in this section illustrate uses of the Save Compiled Project command.
In this example, imagine that you have produced an application that is entirely represented using an AVS/Express network, and it is running as the current application. You now want to produce a version of this application that runs more efficiently and is easier to hand over to another user. To do this:
3. Select the Save current application option: the current application is the only object you need in the compiled project.
4. Deselect the Include network editor in project option: the user of this application will not be editing it.
In this example, imagine that you have constructed an application that dynamically creates and modifies AVS/Express networks: specifically, it dynamically creates objects from the Data Visualization and the Graphics Display kits. You now want to deploy a more efficient version of this application to a set of users. To do this:
6. Select the Save selected objects option: you want to save the objects you have selected in the compiled project.
7. Deselect the Include network editor in project option: the user of this application will not be editing it.
The following procedure explains how use AVS/Express and Microsoft Visual C++ to create a simple multiple-document interface (MDI) application that allows you to read AVS/Express geometry files and display them. The application that you will be creating is called Geomview. The file that you will access while creating this application is:
where <install_dir> is the directory in which AVS/Express is installed.
All of the steps that you perform in this procedure are specific to building the Geomview application, however, the steps can be adjusted and the concepts can be applied to developing similar types of applications.
The application is created as follows:
Notice that the border around the various sublibraries is highlighted.
a. When the dialog box is displayed, disable the Annotation and Graphing Kit, the Print Renderer, the VRML Renderer, and the VPS Renderer.
6. Drag the scrollbar at the bottom of the Libraries.Templates object all the way to the right, so the GEOMVIEW object becomes visible.
Instance objects automatically on restore
Build project's executable9. After the compiled project has been generated, exit from AVS/Express and start Microsoft Developer Studio.
The following steps are performed using Microsoft Developer Studio.
2. The New Project Workspace dialog box appears. Select the Projects tab if it is not already selected.
Note: This tutorial assumes that the project is called "geomview". If you choose a different name, you will need to make the necessary adjustments as you complete the steps.
6. Click Next on pages 1, 2, and 3 of the MFC AppWizard, since you will be using the default settings for these steps.
After you are done with the MFC AppWizard, the project directory will be created.
11. Copy the following files to the MFC AppWizard-created geomview project directory from the compiled project directory that you generated using AVS/Express:
Note that the appl.vo file should be placed directly into your geomview project directory; there is no need to create a v subdirectory.
12. Optionally, use a text editor to examine the file express.dsp from the compiled project directory.
Examine the file looking for lines that start with:
The libraries and files listed on these lines should match the list of files you will be specifying later when you change your project settings.
13. In your geomview project directory, create a file called avsenv, and enter the information for setting the XP_PATH variable so that it indicates the name of your project directory.
For example, if your project directory is c:\projects\geomview, your avsenv file should contain the following line:
Note: The instructions below assume that AVS/Express is installed in C:\express. Be sure to substitute the appropriate installation directory when assigning your project settings.
1. Select Project->Settings to display the Project Settings dialog box. In the "Settings for:" list box on the left side of the dialog, make sure "All Configurations" is selected.
a. In the "General" category, add the preprocessor definition MSDOS to the end of the list of existing definitions.
c. In the "Preprocessor" category, add the following entries to the "Additional include directories:" text field:
libacvt.a libgeom.a libutil.a libgdogl.a libgdsw.a libgd.a libmutil.a libvxbx.a libui.a libcxxut.a libpal.a libdmap.a libdbxx.a libgmod.a libwtobj.a express.lib wsock32.lib
Note: This needs to be entered as one long line in the typein window.
a. In the "Settings for:" list box on the left side of the dialog box, change the selection so that only the Debug version of the project is selected.
You are now finished with the Project Settings dialog box.
2. Add the following line immediately before the final return statement in the code for CGeomviewApp::InitInstance in geomview.cpp:
5. Using the ClassWizard (View->ClassWizard), add the OnOpenDocument and OnCloseDocument messages to the CGeomviewDoc class.
m_reader = new CGeomFileReader;
m_reader->push_ctx();
m_reader->filename = lpszPathName;
m_reader->pop_ctx();
10. Using ClassWizard, add the OnInitialUpdate, PostNcDestroy, WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP, and WM_SIZE messages to the CGeomviewView class.
CGeomviewDoc *pDoc = GetDocument();
CGeomFileReader *reader = pDoc->GetReader();
if (!reader) return;
m_viewer = new C3DViewer;
if (OMadd_obj_ref((OMobj_id) m_viewer->objs,
(OMobj_id) reader->obj, 0) != OM_STAT_SUCCESS) {
return;
}
m_viewer->push_ctx();
m_viewer->window = (int) GetSafeHwnd();
m_viewer->widget = (int) GetSafeHwnd();
m_viewer->hdc = 0;
m_viewer->event = 1;
m_viewer->pop_ctx();
The program starts up with an initial empty view window.
2. To display some data, select File->Open and input an AVS geometry file (e.g. c:\express\data\geom\teapot.geo).
You can rotate, scale, or XY-translate the geometry using the left mouse button. To scale, hold the Shift key down while dragging. To translate, press the Control key while dragging.
If you select Window->New Window, a new view window appears, and it displays the currently selected geometry using the default transform.
If you select File->Close, the geometry for the currently selected view is deleted, and all of the geometry's view windows are closed.
![]() |
![]() |
![]() |
![]() |
![]() |
Copyright © 2001 Advanced Visual Systems
Inc.
All rights reserved.