28.4 The Generic Command Loop

The default application command loop provided by CLIM performs the following steps: [annotate]

  1. Prompts the user for input. [annotate]
  2. Reads a command. Each application frame has a command table that contains those commands that the author of the application wishes to allow the user to invoke at a given time. Since commands may be read in any number of ways, the generic command loop enforces no particular interface style. [annotate]
  3. Executes the command. The definition of each command may refer to (and update) the state variables of the frame, to which *application-frame* will be bound. [annotate]
  4. Runs the display function for each pane in the frame as necessary. The display function may refer to the frame's state variables. Display functions are usually written by the application writer, although certain display functions are supplied by CLIM itself. Note that an application frame is free to have no panes. [annotate]

Major issue: RWK has a reasonable proposal for breaking down command loops into their component pieces. It should be integrated here. --- SWM [annotate]

All classes that inherit from application-frame must inherit or implement methods for all of the following functions. [annotate]

run-frame-top-level  frame &key &allow-other-keys  [Generic Function]
          

Runs the top-level function for the frame frame. The default method on application-frame simply invokes the top-level function for the frame (which defaults to default-frame-top-level). [annotate]

[annotate]

run-frame-top-level  (frame application-frame) &key  [:Around Method]
          

The :around method of run-frame-top-level on the application-frame class is responsible for establish the initial dynamic bindings for the application, including (but not limited to) binding *application-frame* to frame, binding *input-context* to nil, resetting the delimiter and activation gestures, and binding *input-wait-test*, *input-wait-handler*, and *pointer-button-press-handler* to nil. [annotate]

[annotate]

default-frame-top-level  frame &key command-parser command-unparser partial-command-parser prompt [Generic Function]
          

The default top-level function for application frames. This function implements a "read-eval-print" loop that displays a prompt, calls read-frame-command, then calls execute-frame-command, and finally redisplays all of the panes that need to be redisplayed. [annotate]

default-frame-top-level will also establish a simple restart for abort, and bind the standard stream variables as follows. *standard-input* will be bound to the value returned by frame-standard-input. *standard-output* will be bound to the value returned by frame-standard-output. *query-io* will be bound to the value returned by frame-query-io. *error-output* will be bound to the value returned by frame-error-output. It is unspecified what *terminal-io*, *debug-io*, and *trace-output* will be bound to. [annotate]

prompt is either a string to use as the prompt (defaulting to "Command: "), or a function of two arguments, a stream and the frame. [annotate]

command-parser, command-unparser, and partial-command-parser are the same as for read-command. command-parser defaults to command-line-command-parser if there is an interactor, otherwise it defaults to menu-only-command-parser. command-unparser defaults to command-line-command-unparser. partial-command-parser defaults to command-line-read-remaining-arguments-for-partial-command if there is an interactor, otherwise it defaults to menu-only-read-remaining-arguments-for-partial-command. default-frame-top-level binds *command-parser*, *command-unparser*, and *partial-command-parser* to the values of command-parser, command-unparser, and partial-command-parser. [annotate]

[annotate]

Note: default-frame-top-level is a generic function, which means that it could be extended or customized based on the class of FRAME. Under what circumstances does it make sense to do so, though? Probably only with auxiliary methods, rather than overriding primary methods, no? [edit]-- Christophe Rhodes 2006-04-26 13:10Z
 

read-frame-command  frame &key (stream *standard-input*) [Generic Function]
          

Reads a command from the stream stream on behalf of the frame frame. The returned value is a command object. [annotate]

The default method (on standard-application-frame) for read-frame-command simply calls read-command, supplying frame's current command table as the command table. [annotate]

[annotate]

execute-frame-command  frame command [Generic Function]
          

Executes the command command on behalf of the frame frame. command is a command object, that is, a cons of a command name and a list of the command's arguments. [annotate]

The default method (on standard-application-frame) for execute-frame-command simply applies the command-name of command to command-arguments of command. [annotate]

If process that execute-frame-command is invoked in is not the same process the one frame is running in, CLIM may need to make special provisions in order for the command to be correctly executed, since as queueing up a special "command event" in frame's event queue. The exact details of how this should work is left unspecified. [annotate]

[annotate]

command-enabled  command-name frame [Generic Function]
          

Returns true if the command named by command-name is presently enabled in the frame frame, otherwise returns false. If command-name is not accessible to the command table being used by frame, command-enabled returns false. [annotate]

Whether or not a particular command is currently enabled is stored independently for each instance of an application frame; this status can vary between frames that share a single command table. [annotate]

[annotate]

(setf command-enabled)  enabled command-name frame [Generic Function]
          

If enabled is false, this disables the use of the command named by command-name while in the frame frame. Otherwise if enabled is true, the use of the command is enabled. After the command has been enabled (or disabled), note-command-enabled (or note-command-disabled) is invoked on the frame manager and the frame in order to update the appearance of the interface, for example, "graying out" a disabled command. [annotate]

If command-name is not accessible to the command table being used by frame, using setf on command-enabled does nothing. [annotate]

[annotate]

display-command-menu  frame stream &key command-table initial-spacing row-wise max-width max-height n-rows n-columns (cell-align-x :left) (cell-align-y :top) [Generic Function]
          

Displays the menu associated with the specified command table on stream by calling display-command-table-menu. If command-table is not supplied, it defaults to (frame-command-table stream). This function is generally used as the display function for panes that contain command menus. [annotate]

Note: It should probably be (frame-command-table frame) [edit]-- Troels "Athas" Henriksen 2006-12-14 18:03Z
 

initial-spacing, max-width, max-height, n-rows, n-columns, row-wise, cell-align-x, and cell-align-y are as for formatting-item-list. [annotate]

[annotate]