Merge branch 'cmdparser_refactor' of https://github.com/volundmush/evennia into volundmush-cmdparser_refactor

This commit is contained in:
Griatch 2022-08-02 15:03:00 +02:00
commit 01aa49108e
2 changed files with 29 additions and 35 deletions

View file

@ -61,38 +61,14 @@ def build_matches(raw_string, cmdset, include_prefixes=False):
""" """
matches = [] matches = []
try: try:
if include_prefixes: orig_string = raw_string
# use the cmdname as-is if not include_prefixes and len(raw_string) > 1:
l_raw_string = raw_string.lower() raw_string = raw_string.lstrip(_CMD_IGNORE_PREFIXES)
for cmd in cmdset: search_string = raw_string.lower()
matches.extend( for cmd in cmdset:
[ cmdname, raw_cmdname = cmd.match(search_string, include_prefixes=include_prefixes)
create_match(cmdname, raw_string, cmd, cmdname) if cmdname:
for cmdname in [cmd.key] + cmd.aliases matches.append(create_match(cmdname, raw_string, cmd, raw_cmdname))
if cmdname
and l_raw_string.startswith(cmdname.lower())
and (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname) :]))
]
)
else:
# strip prefixes set in settings
raw_string = (
raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string
)
l_raw_string = raw_string.lower()
for cmd in cmdset:
for raw_cmdname in [cmd.key] + cmd.aliases:
cmdname = (
raw_cmdname.lstrip(_CMD_IGNORE_PREFIXES)
if len(raw_cmdname) > 1
else raw_cmdname
)
if (
cmdname
and l_raw_string.startswith(cmdname.lower())
and (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname) :]))
):
matches.append(create_match(cmdname, raw_string, cmd, raw_cmdname))
except Exception: except Exception:
log_trace("cmdhandler error. raw_input:%s" % raw_string) log_trace("cmdhandler error. raw_input:%s" % raw_string)
return matches return matches

View file

@ -221,6 +221,7 @@ class Command(metaclass=CommandMeta):
""" """
if kwargs: if kwargs:
_init_command(self, **kwargs) _init_command(self, **kwargs)
self._optimize()
@lazy_property @lazy_property
def lockhandler(self): def lockhandler(self):
@ -297,10 +298,15 @@ class Command(metaclass=CommandMeta):
Optimize the key and aliases for lookups. Optimize the key and aliases for lookups.
""" """
# optimization - a set is much faster to match against than a list # optimization - a set is much faster to match against than a list
self._matchset = set([self.key] + self.aliases) matches = [self.key.lower()]
matches.extend(x.lower() for x in self.aliases)
self._matchset = set(matches)
# optimization for looping over keys+aliases # optimization for looping over keys+aliases
self._keyaliases = tuple(self._matchset) self._keyaliases = tuple(self._matchset)
self._noprefix_aliases = {x.lstrip(CMD_IGNORE_PREFIXES): x for x in matches}
def set_key(self, new_key): def set_key(self, new_key):
""" """
Update key. Update key.
@ -336,7 +342,7 @@ class Command(metaclass=CommandMeta):
self.aliases = list(set(alias for alias in aliases if alias != self.key)) self.aliases = list(set(alias for alias in aliases if alias != self.key))
self._optimize() self._optimize()
def match(self, cmdname): def match(self, cmdname, include_prefixes=True):
""" """
This is called by the system when searching the available commands, This is called by the system when searching the available commands,
in order to determine if this is the one we wanted. cmdname was in order to determine if this is the one we wanted. cmdname was
@ -345,11 +351,23 @@ class Command(metaclass=CommandMeta):
Args: Args:
cmdname (str): Always lowercase when reaching this point. cmdname (str): Always lowercase when reaching this point.
Kwargs:
include_prefixes (bool): If false, will compare against the _noprefix
variants of commandnames.
Returns: Returns:
result (bool): Match result. result (bool): Match result.
""" """
return cmdname in self._matchset if include_prefixes:
for cmd_key in self._keyaliases:
if cmdname.startswith(cmd_key) and (not self.arg_regex or self.arg_regex.match(cmdname[len(cmd_key) :])):
return cmd_key, cmd_key
else:
for k, v in self._noprefix_aliases.items():
if cmdname.startswith(k) and (not self.arg_regex or self.arg_regex.match(cmdname[len(k) :])):
return k, v
return None, None
def access(self, srcobj, access_type="cmd", default=False): def access(self, srcobj, access_type="cmd", default=False):
""" """