Start add list_node EvMenu node decorator

This commit is contained in:
Griatch 2018-03-28 00:02:00 +02:00
parent b799b7280a
commit ca746f9af2

View file

@ -166,6 +166,7 @@ evennia.utils.evmenu`.
from __future__ import print_function
import random
from builtins import object, range
import re
from textwrap import dedent
from inspect import isfunction, getargspec
@ -972,6 +973,107 @@ class EvMenu(object):
return separator1 + "|n" + nodetext + "|n" + separator2 + "|n" + optionstext
# -----------------------------------------------------------
#
# List node
#
# -----------------------------------------------------------
def list_node(option_list, examine_processor, goto_processor, pagesize=10):
"""
Decorator for making an EvMenu node into a multi-page list node. Will add new options,
prepending those options added in the node.
Args:
option_list (list): List of strings indicating the options.
examine_processor (callable): Will be called with the caller and the chosen option when
examining said option. Should return a text string to display in the node.
goto_processor (callable): Will be called with caller and
the chosen option from the optionlist. Should return the target node to goto after the
selection.
pagesize (int): How many options to show per page.
Example:
@list_node(['foo', 'bar'], examine_processor, goto_processor)
def node_index(caller):
text = "describing the list"
return text, []
"""
def _rerouter(caller, raw_string):
"Parse which input was given, select from option_list"
caller.ndb._menutree
goto_processor
def decorator(func):
all_options = [{"desc": opt, "goto": _rerouter} for opt in option_list]
all_options = list(sorted(all_options, key=lambda d: d["desc"]))
nall_options = len(all_options)
pages = [all_options[ind:ind + pagesize] for ind in range(0, nall_options, pagesize)]
npages = len(pages)
def _examine_select(caller, raw_string, **kwargs):
match = re.search(r"[0-9]+$", raw_string)
page_index = kwargs.get("optionpage_index", 0)
def _list_node(caller, raw_string, **kwargs):
# update text with detail, if set
# dynamic, multi-page option list
page_index = max(0, min(npages - 1, kwargs.get("optionpage_index", 0)))
options = pages[page_index]
if options:
if npages > 1:
# if the goto callable returns None, the same node is rerun, and
# kwargs not used by the callable are passed on to the node.
if page_index > 0:
options.append({"desc": "prev",
"goto": (lambda caller: None,
{"optionpage_index": page_index - 1})})
if page_index < npages - 1:
options.append({"desc": "next",
"goto": (lambda caller: None,
{"optionpage_index": page_index + 1})})
options.append({"key": "_default",
"goto": (_examine_select, {"optionpage_index": page_index})})
# add data from the decorated node
try:
text, extra_options = func(caller, raw_string)
except Exception:
logger.log_trace()
else:
if isinstance(extra_options, {}):
extra_options = [extra_options]
else:
extra_options = make_iter(extra_options)
options.append(extra_options)
return text, options
return _list_node
return decorator
# -------------------------------------------------------------------------------------------------
#
# Simple input shortcuts