Entity Event Example

Purpose

The most common use of entity events is to control cursor movement for character-based host applications. These examples illustrate several different ways to do this.

In each case the problem is the same: there is no way to directly control the movement of the cursor on a character-based terminal. The host application will move the cursor to any one of a number of pre-defined locations in response to keystrokes entered by the user. The issue is: how can Verastream best tell the host application how to move between positions on the terminal screen?

Model Design

Each example is based upon the Pine e-mail program model which is supplied with the Verastream development kit. Each example uses a different method to move the cursor while using tabbing and tab stops to write attribute values to the AddressEdit entity.

Testing the Event Handlers in the Design Tool

All of these examples can be tested in a similar way. You will need to have a machine running the Pine e-mail program. (Pine is freely available from the University of Washington.) You will need an account on the machine running Pine which you don't mind playing with. Pine does not actually need to be attached to a real mail server for these tests.

Use the Design Tool's Session Setup dialog to point to the machine running Pine. You will probably also want to modify the login and logout command lists to login and logoff from the test machine, and to start and quit Pine. The command lists supplied with the example work with an unmodified Bash shell running under Linux.

Once you can successfully connect to the machine running Pine, make sure that there is at least one e-mail address in Pine's address book. (The Address_add entity can be used to do this.) Then navigate to the Address_edit entity and use the Write Attributes Test dialog to:

The test data you enter in the Write Attributes Test dialog can be reused if (after writing the attributes) you type CTRL-C (in the Design Tool's terminal window) to tell Pine to discard the changes, and then re-display the Address_edit entity.

Move Cursor

Purpose

The Move Cursor example uses an entity event handler which handles the Move Cursor event. The event handler is given two pieces of information: where the cursor is and where it needs to go. It is up to the event handler to figure out the best to get from here to there.

Using a Move Cursor event handler bypasses the normal Verastream tabstop logic.

Implementation

The event handler itself is simple. If the target location is in a row above the current row, move the cursor up; otherwise move it down.

Model Design

The Pine model has an entity event handler attached to the Address_edit entity. The Address_edit.LineDown and Address_edit.LineUp operations have an event handler attached which simply logs the name of the operation executed.

Scripted Tabbing

Purpose

The Scripted Tabbing example uses the standard Verastream tabstop logic, but overrides the operations used to move the cursor.

Using this kind of implementation is useful when the standard tabstop logic works well enough to decide where to move the cursor. In this case, trying to move the cursor beyond the last entity will cause a timeout error. The operation event handler suppresses this timeout so that Verastream's tabstop logic can work normally.

Implementation

The Scripted Tabbing example attaches an event handler to the Address_edit.LineUp and Address_edit.LineDown operations. The event handler first executes the default operation (to move in one direction or the other). If moving the cursor results in a timeout, the timeout error is suppressed, Verastream notices that the cursor hasn't moved, and reverses the tab direction.

Model Design

The Pine model uses the same operation event handler for both the Address_edit.LineDown and Address_edit.LineUp.

If tabstops are defined, the event handler executes the default operation (line up or line down), and then waits until the cursor reaches any of the defined tabstops.

If no tabstops are defined, the event handler waits for the cursor to move and returns, figuring that wherever the cursor ended up must be okay.

If the cursor does not move after issuing a cursor movement command, a timeout will be reported. In this case, the event handler assumes that the cursor can't move any more in that direction, so the timeout error is not reported. The Verastream tabstop logic will notice that the cursor hasn't moved, so the cursor movement is reversed.

Testing in the Design Tool

To force a timeout to reverse the cursor movement:

  1. Move to the Address_edit entity.
  2. Move the cursor below the Nickname attribute.
  3. Open the Write Attributes Test dialog.
  4. Set up the test to write the Nickname attribute, and to not write the Addresses attribute.

Executing the test will move the cursor forward (down), causing a timeout at the Addresses entity. The cursor movement then reverses to reach the Nickname.

Write Attributes

Purpose

The Write Attributes example is significantly more complex than the others. In this case, the event handler is handed a set of attributes (names and new values) which needs to be written. The event handler is responsible for figuring out the order in which to update all of the attributes.

Moving the cursor on the Address_edit entity is simple: send a cursor-up command to move up; send a cursor-down command to move down. The optimal strategy to handle attribute writes is write the attribute values while moving the cursor in only one direction, starting with either the first (topmost) or last (bottommost) attribute, whichever is closer to the starting cursor position.

Implementation

The implementation strategy is to first gather information about the attributes to be written, to decide where to begin and which way to move the cursor, and then to move and write to each attribute value in turn. This is done as follows:

  1. Sort the attributes to be written in tab order.
  2. Determine which "end" of the sorted attribute sequence (priority queue) is closer to the current cursor position.
  3. Move the cursor to the closer end of the attribute sequence, and write that attribute's value.
  4. Move toward the other end of the sequence, writing each attribute value required as the attribute position is reached.

The event handler contains several subsidiary classes which simplify the actual event handler code (that is, the writeAttributes() method itself). A priority queue manages sorting the attributes, an attribute-region object keeps the attribute name and location together, and an iterator for the queue returns the queue contents (the attributes and locations) in the desired order.

Model Design

The model is the standard Pine model with an entity event handler attached to the Address_edit entity.

Entity Arrival

Purpose

The Entity Arrival example demonstrates how to use an entity arrival event to automatically bypass an entity. This prevents the need to add the entity as an intermediate entity to each operation that might encounter it.

Implementation

The implementation of the event handler is fairly straight forward. The entityArrival() method is called when VHI recognizes the entity. In the method an operation is executed to bypass the entity.

Model Design

The pine model is used to demonstrate this ability. The CancelChanges entity is configured to be automatically bypassed. The event handler is attached to this entity and the "Immediate arrival processing" option is checked in the Advanced Entity Properties. This is important, otherwise the entity will not be recognized during execution of operation commands.