Home
About
Policies
FAQ
Forums
Registration
Password Recovery

User:Orbus

From Tapestries MUCK

Revision as of 23:24, 8 March 2015 by Orbus (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Hi. I'm Orbus on Tapestries.

I write frameworks in MPI sometimes. I share them here before I publish them.

Contents

MPI Software

I'm making this code available for anyone to use. If you incorporate any of it into another piece of software, I'd appreciate (but don't require) hearing from you to find out what you're using it for.

CommandLib

CommandLib is a top-level command that you can use on an action to handle parsing of the actual command the player typed.

It's built to handle situations that use the standard MUCK convention of a base-level command that may take arguments and some subcommands that are single words beginning with #.

Source

These commands assume you have an object named command that you would like to install CommandLib onto. You'll want to change the name of the object appropriately.

These also assume you have an action linked to gen-nothing. On Tapestries, you can create this object and link it appropriately with the following commands:

@action command

@link command=$nothing

This code sets up CommandLib itself on the object:

@set command=_msgmacs/error:{if:{prop!:/_cmd/{:1}/_error},{exec!:/_cmd/{:1}/_error},{if:{prop!:/_error},{exec!:/_error},{:1}{if:{:2}, #{:2},} is not a valid command.}}

@succ command={with:subcmd,{sublist:{&arg},1,1, },{null:{if:{eq:{midstr:{&subcmd},1,1},#},{set:subcmd,{midstr:{&subcmd},2,-1}},{set:subcmd,}}}{if:{&subcmd},{if:{prop!:/_cmd/{&cmd}/_sub/{&subcmd}},{with:args,{strip:{sublist:{&arg} ,2,-1, }},{null:{set:arg,{&args}}}{exec!:/_cmd/{&cmd}/_sub/{&subcmd}}},{error:{&cmd},{&subcmd}}},{if:{prop!:/_cmd/{&cmd}/_base},{exec!:/_cmd/{&cmd}/_base},{error:{&cmd}}}}}

Implementing Your Command

Where You Put Code
  • /_cmd/command/_base
    • Called when the player enters command without a subcommand, with or without other arguments.
  • /_cmd/command/_sub/subcommand
    • Called when the player enters command #subcommand, with or without other arguments.
  • /_cmd/command/_error
    • Called when the player enters command #subcommand, with or without other arguments, but there isn't any code to run for that subcommand.
  • /_error
    • Called when the player enters command with or without a subcommand, but there isn't any code to run for that command.
    • Also called when the player enters command #subcommand, with or without other arguments, and there isn't any code to run for that subcommand, and there also isn't an error handler defined for that subcommand.
Getting User Input

Any MPI called by CommandLib can rely on three variables being defined:

  • {&cmd} works exactly the way that the docs define.
  • {&subcmd} will be blank if the player did not type a subcommand, or will have the name of the subcommand without the # if the player did.
  • {&arg} works the way that the docs define when there is no subcommand. If there is a subcommand, then the subcommand will be removed from {&arg} before your MPI is called.

Examples:

  • page orbus=Why did you write this crazy parser library?
    • &cmd: "page"
    • &subcmd: ""
    • &args: "orbus=Why did you write this crazy parser library?"
  • page #mail orbus=I missed you, I'll ask my question later!
    • &cmd: "page"
    • &subcmd: "mail"
    • &args: "orbus=I missed you, I'll ask my question later!"
  • page #help
    • &cmd: "page"
    • &subcmd: "help"
    • &args: ""
  • page
    • &cmd: "page"
    • &subcmd: ""
    • &args: ""

Example

Here's a simplified version of page that we'll use for an example:

We're calling this "mypage" so that you can actually create this object and see how this all works; the "page" command is a little bit magic and you can't override it. (Which is good!)

mypage <player> = <message>
mypage #mail <players>=<mesg>
mypage #help

We also want it to work if the player types mp instead of mypage.

First, we want to create an action that will accept the mypage or mp commands:

@action mypage;mp

@link mypage=$nothing

Then, we'll install CommandLib on that action. (See the Source section; we're not copying the code down here.)

Now, we can set up command handlers for page.

@set mypage=/_cmd/mypage/_base:{null:This would be the code that handles actually sending a message to someone.,{tell:Fake-page!}}

No, I'm not actually implementing page. This is an example of how argument-parsing works, not an exercise in re-implementing things that work well already.

@set mypage=/_cmd/mypage/_sub/mail:{null:This would be the code to handle sending mail.,{tell:Fake-mail!}}

@set mypage=/_cmd/mypage/_sub/help:{&cmd} player = message to send a page{nl}{&cmd} #mail player = message to send mail

As you can see, you can put raw text and MPI in these blocks. The result of evaluating your MPI and text will be shown to the player.

Duplicating all of that code for the mp command would be annoying. So let's redirect anything that uses mp to mypage:

@set mypage=/_cmd/mp/_base:{exec!:/_cmd/mypage/_base}

@set mypage=/_cmd/mp/_error:{if:{prop!:/_cmd/mypage/_sub/{&subcmd}},{prop!:/_cmd/mypage/_sub/{&subcmd}},{error:mypage,{&subcmd}}}

Okay, this is a little bit clever. Rather than registering every subcommand on mp as a redirect to the corresponding subcommand on mypage, we register the unknown-subcommand error. All subcommands are unknown, so we always run this error handler when there's a subcommand. Then, the error handler checks whether the subcommand exists on mypage, and if it does it runs it. If it doesn't exist on mypage, it throws into the error handler again, but this time it runs the mypage error handler.

Right now, if you use a #subcommand that isn't recognized, you get the not-that-helpful default error message: "mypage #subcommand is not a valid command." Let's make that more helpful by adding a better error handler - say, one that tells you how to get help:

@set mypage=/_cmd/mypage/_error:{&cmd} #{&subcmd} isn't something I know how to do.{nl}Type "{&cmd} #help" for help.

You can try that out by typing mypage #badcommand, and you'll get the new error message. Because of the redirection we did to mp, you can also type mp #badcommand to get the friendly error.

And now you've seen everything CommandLib can do!

Personal tools
Namespaces
Variants
Actions
navagation
information
wiki
Toolbox