This chapter describes advanced functions that control the general organization of graphical data.
The conditional structure execution capabilities of the graPHIGS API allow your application to create conditional executes and returns in a structure. These facilities can be used to increase performance by eliminating unnecessary traversal and provide your application with a way to control traversal.
Conditional executes and returns are based on tests performed against a condition flag The condition flag is a 32-bit string where bits 0 to 15 are reserved for use by the graPHIGS API application, and bits 16 to 31 are reserved for use by the graPHIGS API The traversal default of the condition flag is all 0s.
In order to set the bits in the condition flag, three condition setting structure elements have been defined. First, the Test Extent 2 (GPTEX2) and the Test Extent 3 (GPTEX3) subroutines create structure elements which set bits 30 and 31 of the condition flag. Bit 30 is called the cull flag, and bit 31 is called the prune flag The parameters to GPTEX2 and GPTEX3 are defined as follows:
During structure traversal, the following actions are taken:
Through the Set Condition structure element, your application can directly set any condition flag. The element consists of two 32-bit bit strings: one on-flag and one off-flag. The bits of the current condition flag specified in the on-flag and off-flag are set to 1 and 0, respectively. More precisely, the resulting condition bits after this structure element is traversed becomes:(current-flag OR on-flag) AND (NOT off-flag)
Two conditional structure execution elements can be created using the Conditional Execute Structure (GPCEXS) and Conditional Return (GPCRET) subroutines. The element created by the GPCEXS subroutine provides the following construct:
|if the specified condition is satisfied|
then execute the specified structure
else do nothing
The GPCRET subroutine provides the following construct:
|if the specified condition is satisfied|
then terminate execution of this structure
else continue execution of this structure
For both elements, the conditions are specified as follows:
(1: all 1s, 2: all 0s, 3: not all 1s, 4: not all 0s)
When the bits specified by the flag mask satisfy the specified condition, the operation in the then clause is executed, otherwise the else clause is executed.
This section contains a discussion of structure manipulation in terms of editing modes, element pointer manipulation, element deletion, and structure inquiry.
Your application program can edit structures using one of two editing modes - the Insert edit mode or the Replace edit mode. Using the INSERT_MODE , structure elements are inserted to the current open structure immediately after the element pointed to by the current element pointer. Then the current element pointer is moved to the element that was inserted.
In REPLACE_MODE , structure elements are not inserted, but replace the current element. If the current element pointer points to element 0, then the new element is inserted immediately before element 1. In either case, the current element pointer is set to point to the new element.
You may select either of the two edit modes by using the Set Edit Mode (GPEDMO) subroutine. When you issue the Open graPHIGS (GPOPPH) subroutine, the editing mode defaults to INSERT_MODE
Using the REPLACE_MODE is equivalent to calling the Delete Element (GPDLE) subroutine, followed by a subroutine call to an element generation function in INSERT_MODE For example, to replace a Polyline in REPLACE_MODE is equivalent to the following calling sequence in the INSERT_MODE :
CALL DELETE ELEMENT (GPDLE) CALL POLYLINE (GPPL2)
As another example, if you want to replace elements 8 through 10 with polylines, then use the following calling sequence:
CALL SET EDIT MODE (INSERT_MODE) CALL DELETE ELEMENT RANGE (8,10) CALL POLYLINE (XXXX) CALL POLYLINE (XXXX) CALL POLYLINE (XXXX)or the calling sequence:
CALL SET EDIT MODE (REPLACE_MODE) CALL SET ELEMENT POINTER (8) CALL POLYLINE (XXXX) CALL OFFSET ELEMENT POINTER (1) CALL POLYLINE (XXXX) CALL OFFSET ELEMENT POINTER (1) CALL POLYLINE (XXXX)
The following element pointer manipulation subroutines are supported by the graPHIGS API:
Use the Generalized Set Element Pointer subroutines, (Generalized Set Element Pointer At Label (GPEPLG) and Generalized Set Element Pointer At Pick Identifier (GPEPPG)), to specify whether or not the search operation should wrap to the beginning of the structure if the label or pick identifier element is not found before the end of the structure is reached.
The following element deletion subroutines are supported by the graPHIGS API:
The Delete Element Group (GPDLEG) subroutine will delete all the elements between the two specified label identifier elements and, depending on the option set by the application, may also delete the first label element and/or the second label element. The option also specifies how the subroutine searches for the labels (i.e., whether the search starts at the current element or whether it starts at the element following the current element).
After the element deletions, the element pointer moves to the element immediately preceding the deleted elements. If the search reaches the end of the structure without finding both of the label identifier elements, an error is generated and the current element pointer is left unchanged.
Because structure contents are maintained by the graPHIGS API nucleus, each time the application issues a structure inquire subroutine call, communication between the shell and nucleus is required. When the nucleus is at another location (a remote nucleus), structure inquire subroutine calls may require a relatively large amount of I/O involving one round trip communication between the graPHIGS API shell and nucleus. Frequent use of these inquire functions is therefore not a good technique when using a remote nucleus.
The Inquire List of Element Headers (GPQEHD) subroutine, has been introduced as a way of minimizing I/O overhead. This subroutine has the following parameters:
----------------------- | length | code | -----------------------
The length field contains a 16-bit unsigned integer representing the length of the structure element including the header itself and the code field containing a 16-bit unsigned integer representing the structure element type.
The subroutine Inquire List Of Element Headers For Any Structure (GPQEHA) is a generalized form of GPQEHD. Using GPQEHA, your application can specify the structure identifier from which the data is obtained and a starting position in the structure from where to obtain the headers.
Note that the GPQEHD and GPQEHA subroutines return the element information in a different format and with different values than the Inquire Element Type And Size (GPQETS) subroutine. Although the latter subroutine is still supported, GPQEHD and GPQEHA are recommended for obtaining element headers from structures. Also, if your application is obtaining element headers in order to search for a particular element type, then you may be able to search more efficiently using the Element Search subroutine discussed in the Element Pointer Manipulation section on "Element Pointer Manipulation" Although the latter subroutine is still supported, GPQEHD is recommended when searching a structure for a particular element.
Another subroutine, Inquire List of Element Data (GPQED) subroutine, enables your application to inquire the content of one or more structure elements. The data returned by GPQED for each structure element is in the same order as the element headers returned by the Inquire List of Element Headers. GPQED requires the following parameters:
The elements are packed into the buffer provided by the application. The length in the header of each element will indicate the offset to the next structure element in the buffer.
The subroutine, Inquire List Of Element Data For Any Structure (GPQEDA), is a more generalized form of GPQED. Using GPQEDA, your application can specify the structure identifier from which the data is obtained, and a starting position in the structure from where to obtain the element data.
Your application can use two inquiry subroutines to determine the structure relations created using Execute Structure subroutine. These relationships are returned as paths, which are lists of ordered pairs of information. Each element of the pair consists of:
The identifier of a structure in the hierarchy related to the specified structure identifier
The element number of an EXECUTE STRUCTURE element in the structure
(101,10),(102,5),(103,0)then the path is interpreted as follows:
The Inquire Ancestors Of Structure (GPQPAS) subroutine returns the paths that lead to the specified structure. These paths are those created by other structures that reference the specified structure by use of Execute Structure elements. The Inquire Descendants Of Structure (GPQPDS) subroutine returns the paths that lead from the specified structure. The paths are those created by the Execute Structure elements in the specified structure.
In addition to the inquiry subroutines that return structure content, the Inquire Structure Status (GPQSTS) subroutine returns to your application an indicator as to whether or not the specified structure exists, and the number of elements in the structure if it does exist.
The Element Search (GPELS) subroutine is a generalized search facility that operates according to parameters supplied by your application. These included the identifier of the structure to be searched, the search direction (forward or backward), and a list of element types to satisfy the search. By using the element search facility, your application can efficiently locate structure elements for editing. For example, rather than performing a loop that sets the element point and continues to inquire each succeeding element type in search of a particular one, the element search subroutine could perform the search.
Two transfer functions allow your application to copy structures from a specified structure store to the currently selected structure store. The source and the target structure stores may reside on the same nucleus or on different nuclei.
To copy one or more structures from a specified structure store, use the Transfer Structures (GPTST) subroutine. If you wish to copy all structures from one structure store to the currently selected structure store, use the Transfer All Structures (GPTAST) subroutine.
At times, applications may find it convenient to give a structure a new identifier. Also, it may be convenient to change any execute structure-type elements (Execute Structure (GPEXST) or Conditional Execute Structure (GPCEXS)) that reference a structure so that they reference another structure instead. The following subroutines perform these tasks:
GPCSI changes the specified structure identifier to a new identifier but does not change any references to either the original or the new structure identifiers. The results of using this subroutine are:
Note that any execute structure-type elements that reference the original structure will remain unchanged. If changing a structure identifier results in a structure that references itself (it contains an execute structure-type element that specifies its own structure identifier), then an error occurs and the change is not performed.
GPCSRS changes reference to the original structure identifier so that they reference the new structure identifier, but it does not change any structure identifier. This has the same effect as if your application deleted all execute structure-type elements that refer to the original structure identifier and inserted new execute structure-type elements that refer to the new structure identifier. The results of using this subroutine are:
GPCSIR changes both the original structure identifier to a new structure identifier value and references to the original structure identifier to now reference the new structure identifier value. The result of using this subroutine is as if GPCSRS was called followed by a call to GPCSI results in a structure that now references itself (it contains an execute structure-type element that specifies its own structure identifier) then an error is issued and the change is not performed.
The Conditional Editing (GPCEDT) subroutine lets your application improve the efficiency of structure editing by defining a group of editing operations to perform until an error occurs. This eliminates the need to check for operational errors (such as a label not found error when using the Set Element Pointer at Label (GPEPLB) subroutine the graPHIGS API will check for the errors and only complete the structure operations if no error occurs.
When Conditional Editing is active, structure editing operations continue to be processed until:
Syntax errors do not affect conditional editing and only the operational errors from the following functions terminate conditional editing:
When such an error is found, all structure editing functions that require an open structure are ignored until a close structure operation or end conditional editing is encountered.
An error which may result in a fatal situation is nucleus storage overflow caused by structure editing. For example, if the storage overflow occurs while defining a sequence of output primitives, recovery from the overflow situation is very difficult because it is difficult for your application to find out how many output primitives have been lost. The Synchronize (GPSYNC) subroutine is not suitable for preventing an overflow situation because inserting the GPSYNC subroutine between each call to an output primitive routine results in very poor performance due to the many small I/O operations. To solve this problem, a structure store threshold concept is supported by the graPHIGS API Your application can set a threshold value for each structure store and when the structure contents exceeds this value, an event is reported to your application. By setting the threshold to a value smaller than the available storage, your application will be informed of a possible storage overflow situation.
To manage this threshold the graPHIGS API supports the following two subroutines:
The former returns an estimation of the current free storage on a nucleus and the latter sets the threshold value for each structure store. Note that the storage amount returned by GPQNCS is not necessarily exact but will be an estimation within an implementation dependent accuracy. According to the memory management scheme of the nucleus, the value may be greater or less than the exact size of free storage. You must also be aware that the nucleus storage value returned by GPQNCS represents the amount of storage available to all application processes connected to the nucleus and therefore does not mean that the entire amount can be used by the application. The amount of storage available to an application strongly depends on storage usage of other applications. Note that when the value of zero (0) is returned by the GPQNCS subroutine, the nucleus storage is unlimited (i.e.a virtual storage system), and no estimation is meaningful.
Also note that only one structure store threshold event is generated, even if your application continues to add or delete data to the structure store. If you want additional structure store threshold events, your application must reset the threshold, using the GPSSTH subroutine.