General Modularity Example Module Projects & Files Commands & Scripting
Windows Menus Charts Tables Buttons & tools
Trees and Taxa Characters & Models Documentation General Utilities
Commands Scripting Snapshots Macros Cloning windows
Also: User's guide to scripting language class MesquiteCommand interface Commandable
class CommandChecker class Snapshot class Puppeteer

MesquiteCommands

(updated August 2005)

So that Mesquite can be scripted by a command-line interface, and perhaps programmable, a system of text-based commands is used underneath most user-interface based commands. Thus, when a user selects a menu item, a text String is passed to the appropriate Commandable object, and the command is executed. This is accomplished by attaching a special object, a MesquiteCommand, to the menu item. The MesquiteCommand stores both the object it is to command, and the text String by which it is to command it. When the menu item is selected, the "doIt" or "doItNewThread" method of the MesquiteCommand is called (with a String passed as parameter). The MesquiteCommand then calls the "doCommand" method of the Commandable object to be commanded, passing the String. An object to receive a command must claim the interface Commandable.

To create a MesquiteCommand, the static method makeCommand in MesquiteModule should be used, as follows:

MesquiteCommand tickleCommand = MesquiteModule.makeCommand("tickleMe", giggleObject);

This creates a command with command name "tickleMe" that will be used on the object giggleObject. If, later,

tickleCommand.doIt("softly");

is called, then the giggleObject.doCommand("tickleMe", "softly", commandRecord, commandChecker) will be called by the MesquiteCommand. (The CommandRecord with boolean method "scripting()" is passed because modules might want to behaved slightly differently if the command is given during the execution of a script (in which case the module might want to avoid querying the user for additional information) versus in response to a direct request by a user.

As a programmer you will rarely call the doCommand or doIt methods yourself. Instead, you will set up menu items, or other user interface widgets, and Mesquite will automatically call doCommand to implement the MesquiteCommand attached to the user interface widget.

As many user-interface commands as possible should use a MesquiteCommand as an intermediary. Currently, MesquiteCommands are used with menus, buttons and tools, and slider controls. Even mouse moves and mouse clicks interact with Mesquite via a MesquiteCommand. See the description of scripting.

The command queue

A user interface action is on the main event thread, and so the menu item or tool storing the command calls the command's method on the main event thread. In order that the main event thread not be blocked by calculations that have hung (e.g., infinite loops), the MesquiteCommand almost always spawns a new thread on which to command its Commandable object. (see MesquiteCommand.doItNewThread()).

The disadvantage of this arrangement is that different calculations threads could be going on at once, which is not a good idea for calculations which could communicate with one another, given that Mesquite's modules are not prepared for reentrancy. Thus, the new thread spawn is put on a queue, and the command only actually gets called once all previously called commands have been executed.

This system needs a bit more sophistication. For example, it should be possible to show a list of queued commands such that the user could cancel any one. (This is important to free the queue of hung threads.) Also, each project should have a separate queue, since information in different projects doesn't communicate with one another.


© W. Maddison & D. Maddison 1999-2005