Command class, helper for writing mud commands
B Razen <odbrazen-/[email protected]>
| Newsgroups | gmane.comp.games.mud.client.lyntin |
|---|---|
| Message-ID | <[email protected]> |
Here is a metaclass and base class I use for defining
commands. It uses python classes as a mini-language,
and introspection to figure out what to do.
First things last, an example that defines a command
'say' that just writes 'say %s' to the mud
class Say(Command):
"""Usage: #say <string>"""
command = 'say'
arg_definition = 'input='
arg_options = 'limitparsing=0'
def do_command(sess, arg):
exported.lyntin_command('say %s' % (arg), 1, sess)
now the meat:
class MetaCommand(type):
all = []
def __init__(cls, name, bases, dict):
"""We touchup the defined class here and add it as
a command"""
func = getattr(cls, 'do_command', None)
if (not func): # must be an intermediate class
return
setattr(cls, 'do_command',
staticmethod(func.im_func)) # don't let anyone on
c.l.py see this
MetaCommand.all.append(cls)
cls.load()
return
class Command(object):
__metaclass__ = MetaCommand
"""The base Command class
To define a command, inherit Command and define a
do_command function in
that class. By default it will be called with one
arg,"""
arg_definition = 'default=' # default to accepting
one arg
arg_options = None
_parse_argdef = re.compile('(\w+)\S*\s*')
def _do_command(cls, session, args_dict, cmd):
args = []
for (m) in
Command._parse_argdef.finditer(cls.arg_definition):
argname = m.group(1)
args.append(args_dict[argname])
cls.do_command(session, *args)
return
_do_command = classmethod(_do_command)
def load(cls):
exported.add_command(cls.command,
cls._do_command, # actually
defined in the base class below
cls.arg_definition,
cls.arg_options, # I'm not
sure what this is for
cls.__doc__, # use the
docstring as helptext
)
return
load = classmethod(load)
def unload(cls):
exported.remove_command(cls.command)
return
We never actually use an instance of the classes,
they are just a shorthand for grouping everything
togther. A file with 30 of these is very readable,
the contents of each command are indented, you never
have to remember where or if you play with a
commands_dict
etc.
The class figures out how many arguments the command
expects, so an argstr of 'input= num:int=3' should
have
a do_command like
def do_command(sess, text, num_arg):
arg_definitions and arg_options are inherited by
children,
so I have a few intermediate classes each defining
an arg/argopts so the kids don't have to.
If you don't like it for the core, feel free to throw
it on the misc contrib page. (should the modules on
the conrtib page be rolled into the tarball in a
crotib/ directory?)
-Razen
__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf