 |
» |
|
|
 |
As alluded to in Chapter 1 “Introduction to Display List ”, a segment network is a set of two or
more display list segments, arranged such that one segment "calls"
another. This capability is essential for conveniently and accurately
representing hierarchical structures. This chapter enumerates and
describes the Display List routines that are involved in the process
of having one segment call others. - call_segment
Transfers control to the specified Display List
segment, which executes and then returns control to the calling
segment. This routine does not save the Starbase
state before transferring control, nor does it restore the Starbase
state after control is returned. - execute_segment
Transfers control to the specified Display List
segment, which executes and then returns control to the calling
segment. This routine does save a subset of
the Starbase state before transferring control, and it restores
the Starbase state after control is returned. Other than the implicit
save and restore of the Starbase state, this routine is identical
in function to call_segment. - cond_call_segment
Does a call_segment
if the specified condition is met. - cond_execute_segment
Does an execute_segment
if the specified condition is met. - cond_return
Returns control to the calling segment if the specified
condition is met. - push_state
Explicitly saves a subset of the Starbase state
for subsequent restoration by pop_state.
The effect of a trio of calls to push_state,
call_segment,
and pop_state,
in that order, is identical to a call to execute_segment. - pop_state
Explicitly restore Starbase to the state it was
at the most recent call to push_state. - set_disp_traversal_control
Set display-traversal-control mechanism to continue,
return, or abort. - set_pick_traversal_control
Set pick-traversal-control mechanism to continue,
return, or abort.
"call_segment" |  |
The call_segment
routine causes a "call segment" element to be inserted into the
currently open segment. When the segment is traversed and the "call
segment" element is encountered, the following events take place: Control is passed to the segment referenced by the "call segment"
element. The child segment is traversed. Control returns to the parent segment, where execution
continues with the element following the "call segment" element.
The syntax is: call_segment(〈fildes〉,
〈segno〉);
where: 〈fildes〉
is the file descriptor of the display list, returned by gopen. The display list can
be either device-dependent or device-independent. 〈segno〉
is a 32-bit integer value specifying the number of the segment to
be traversed.
When refreshing or displaying a segment that contains a "call
segment" element, the call_segment
routine does nothing to save or restore the Starbase state after
control returns from the called segment; that is, if the specified
segment contains any Starbase calls that change the attribute settings,
etc., those settings will still be in effect after control is returned
to the segment containing the call_segment
call. For example, consider the following piece of pseudo-code: . . . open_segment(fildes, 1, ...); line_color_index(fildes, 12); polyline2d(fildes, Line1, ...); call_segment(fildes, 2); polyline2d(fildes, Line3, ...); close_segment(fildes); . . . open_segment(fildes, 2, ...); line_color_index(fildes, 15); polyline2d(fildes, Line2, ...); close_segment(fildes); . . . refresh_segment(fildes, 1); . . . |
Both segments 1 and 2 set the line color index (to different
values). The question is: What color is Line3? Answer: Line3 is drawn with line
color index 15. The reason is that call_segment
neither saves the Starbase state before the call_segment, nor restores
the Starbase state after the call_segment.
Since the call_segment
routine is used, when segment 2 exits and control is returned to
segment 1, Display List does not restore the
Starbase state to what it was before segment 2 was called. Therefore,
Line3 is drawn
in the line color most recently specified, regardless of the segment
in which it was specified. If you want the Starbase state to be saved and restored, use
the routine execute_segment
(discussed next). "execute_segment" |  |
The execute_segment
routine causes an "execute segment" element to be inserted into
the currently open segment. When the segment is traversed and the
"execute segment" element is encountered, the following events take
place: A subset of the Starbase state is stored. Control is passed to the segment referenced by the
"execute segment" element. The child segment is traversed. The stored subset of the Starbase state is restored
to what it was prior to the execute_segment
call. Execution continues in the parent segment with the
element following the "call segment" element.
The syntax is: execute_segment(〈fildes〉,
〈segno〉);
where: 〈fildes〉
is the file descriptor of the display list, returned by gopen. The display list can
be either device-dependent or device-independent. 〈segno〉
is a 32-bit integer value specifying the number of the segment to
be traversed.
When refreshing or displaying a segment that contains an "execute
segment" element, a subset of the the Starbase state is saved before
passing control to execute_segment,
and it is restored after control returns. That is, if the specified
segment contains any Starbase calls that change attribute settings,
those settings will remain in effect only until control is returned
to the segment containing the call to execute_segment.
This "subset of the Starbase state" consists of Starbase attributes
only — not the matrix stack or the
current position. If you wish to save and restore the matrix stack,
use the pop_matrix
and push_matrix
routines. It is not possible to save and restore the current position. Since execute_segment
is identical to call_segment
except for the implicit restoration of the state of Starbase after
a segment is called, the above pseudo-code example can be modified
accordingly: . . . open_segment(fildes, 1, ...); line_color_index(fildes, 12); polyline2d(fildes, Line1, ...); execute_segment(fildes, 2); (different
routine)polyline2d(fildes, Line3, ...); close_segment(fildes); . . . open_segment(fildes, 2, ...); line_color_index(fildes, 15); polyline2d(fildes, Line2, ...); close_segment(fildes); . . . refresh_segment(fildes, 1); . . . |
In this case, Line3
is drawn in line color index 12. The reason is apparent in the following
description of the actions of execute_segment: The current set of Starbase attributes is implicitly saved
by execute_segment. The named segment (#2 in this case) is traversed.
Notice that segment #2 changes a Starbase attribute: line color. When control returns from segment #2, the Starbase
state (including its attribute settings), is implicitly restored
(by execute_segment)
to the state it was before segment #2 was traversed. Here, the line
color index is restored to its previous value of 12. Segment #1 processing continues with the element
following the "execute segment" element.
"push_state" and "pop_state" |  |
The routines push_state
and pop_state
respectively save and restore the state of the Starbase attributes.
The discussion above shows why you might want such functionality,
and the above discussion talks about how execute_segment implicitly
does a push_state
and pop_state.
The syntax of these routines is simple: The words "push" and "pop" imply that the Starbase states
are stored on a stack, and, indeed, this is the case. Because of
this, push_state/pop_state pairs can be nested
to any depth, limited only by available memory. Harking back to the pseudo-code example above and modifying
it accordingly, we can see that explicitly saving and restoring
the Starbase state yourself (using push_state
and pop_state),
and then executing call_segment,
has the same effect as using execute_segment: . . . open_segment(fildes, 1, ...); line_color_index(fildes, 12); polyline2d(fildes, Line1, ...); push_state(fildes); (save
Starbase state) call_segment(fildes, 2); pop_state(fildes); (restore
Starbase state) polyline2d(fildes, Line3, ...); close_segment(fildes); . . . open_segment(fildes, 2, ...); line_color_index(fildes, 15); polyline2d(fildes, Line2, ...); close_segment(fildes); . . . refresh_segment(fildes, 1); . . . |
As before, Line3
is drawn in line color index 12. The reasoning is functionally identical
to that in the case of execute_segment,
but the way we went about it was different: The current set of Starbase attributes is explicitly saved
by push_state. The named segment (#2 in this case) is traversed.
Segment #2 changes the line-color attribute. After control returns from segment #2, the Starbase
state is explicitly restored by pop_state
to the state it was at the most recent call to push_state. Here, the line
color index is restored to its previous value of 12. Segment #1 processing continues with the element
following the "pop state" element.
|