Skip to topic | Skip to bottom
Home
Lily
Lily.CommandProcessingr1.1 - 01 Oct 2003 - 22:57 - TamaraCrowetopic end

Start of topic | Skip to actions

Command Processing

3 November 1994, email to lily-dev@rpi.edu.

When we left our intrepid adventurer last night she had just discovered the entry point of command processing in lily. We now resume with #0:do_command..

Once the user has typed something in, the do_command verb takes over. The primary concern of #0:do_command() is to handle dispatching, prefixing, and suffixing. Dipatching is easy and just involves calling the player objects's do_command() verb. Prefixing and suffixing allow a client to know when a command's output begins and ends. To accomodate this the player object holds a pair of strings in player.fixes. fixes[1] is the prefix string, and fixes[2] is the suffix string.

#0:do_command() an excellent spot to install benchmarking, in MOO terms "tick counting", so it is often the source of those annoying <* "foo" took n ticks *> messages. The command is quickly passed to the player object's do_command() verb. Each kind of player object, including helper, client, and user, has a different do_command() verb. We will discuss the user's version of the verb only.

With Core 2.2a1, command leafing was introduced. This concept was first explored by Prisoner in the CloverLeaf project. With excellent suggestions by both Prisoner and Whammy, lily's leafing feature was developed. At the start of $player:do_command a check is made for the client option leaf. If it exists a client command is sent %begin (command) [task_id], and the task_id is added to a list in the player object. Whenever output is pushed through $player:notify(), if the current task_id is found in the list then %command [task_id] is prepended to the line being sent to the client. At the end of the command's execution %end [task_id] is transmitted.

$player:do_command() is actually a fairly small routine given that it processes all of the input by 99% of the active connections on lily. If argstr begins with a '/', then we know we have a command of some kind. First we look in $player.aliases, if the command, as typed, matches against a line in the aliases list, then insert the alias information into the existing arguments list and string. Now look up the partial command name with $sset_c:find_names which returns a list of commands that can match with what he user typed. Then we pass that list to $list_utils:match() and ask it to match the full command entered by the user against the list of possible matches given by $sset_c:find_names(). At this point we have a list which is empty if there were no matches or a list containing the completely evaluated command name (ie /whe returns {"/where"}). If the fully resolved name is in the list of cardgame commands *and*i the player is participating in a cardgame call the player's cardgame's do_command() verb. Otherwise call verb defined by $command_mode:(command_name)(), for example, $command_mode:({"/where"}[1])();.

If the command begins with '$' and the player is in $admins, follow the same process detailed above, leaving out the cardgame stuff and the alias expansion.

If the command begins with '@' and the player is a programmer, call the corresponding verb on $admin. This uses the old MOO style of command processing. For more information on this, check out the LambdaMOO Programmer's Manual.

If the command begins with '?' and the player is a helper (i.e. player.helper = 1=), follow the same process detailed for '@' commands, but call the command name on object $help_mgr.

At this stage we have processed all the known command prefixes, {"?","@","$","/"}. We then assume it is a message and call the $command_mode:send() verb.

The send() verb is quite litterally the largest and most complex verb on the entire system, outweighing the sendlist() verb by almost 40 lines. Much of the reason for this complexity is, like sendlist(), send() is an amalgam of every single pidling little request ever for sending. Amazingly enough send() casts into stone bugs that existing in Clover which became later day features. Also, send() makes use of an amazingly large number of properties in the player object, so I'll will do a brief rundown those properties over here.

With all that out of the way lets begin moving through the send() verb:

The verb options with an attempt to regular expression match the argstr, the player's command input as a string. If successful the msg and unprocessed recipients strings are broken off from each other and stored. If unsuccessful the msg is presumed to be the entire argstr and an attempt is made to use the send_recip. If successful lr_save is used to hold onto the real last_recip value. If unsuccessful the last_msg value is still filled with the attempted send and the verb returns.

At this point 'msg' and 'recips' are filled with text values corresponding to their names. If 'recips' is blank then an attempt is made to send to...

I'll send another letter covering message processing since I am disgusted by the way I've writen $command_mode:send() and I am substantially rewriting it.

Oh, and if you're programming complicated boolean expressions, you might want to look at an intro to set theory.

-- TamaraCrowe - 01 Oct 2003
to top


You are here: Lily > DeveloperGuide > CommandProcessing

to top

Copyright © 1999-2009 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding this site? Contact Christopher Masto <chris@masto.com>.