mirror of
https://github.com/evennia/evennia.git
synced 2026-03-26 09:46:32 +01:00
Almost working list_node evmenu decorator
This commit is contained in:
parent
0f17e73b8c
commit
3c5d00ac3d
2 changed files with 76 additions and 44 deletions
|
|
@ -1002,61 +1002,82 @@ def list_node(option_list, examine_processor, goto_processor, pagesize=10):
|
|||
|
||||
"""
|
||||
|
||||
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"]))
|
||||
def _input_parser(caller, raw_string, **kwargs):
|
||||
"Parse which input was given, select from option_list"
|
||||
|
||||
nall_options = len(all_options)
|
||||
pages = [all_options[ind:ind + pagesize] for ind in range(0, nall_options, pagesize)]
|
||||
available_choices = kwargs.get("available_choices", [])
|
||||
processor = kwargs.get("selection_processor")
|
||||
try:
|
||||
match_ind = int(re.search(r"[0-9]+$", raw_string).group()) - 1
|
||||
selection = available_choices[match_ind]
|
||||
except (AttributeError, KeyError, IndexError, ValueError):
|
||||
return None
|
||||
|
||||
if processor:
|
||||
try:
|
||||
return processor(caller, selection)
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
return selection
|
||||
|
||||
nall_options = len(option_list)
|
||||
pages = [option_list[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)))
|
||||
page = pages[page_index]
|
||||
|
||||
options = pages[page_index]
|
||||
# dynamic, multi-page option list. We use _input_parser as a goto-callable,
|
||||
# with the `goto_processor` redirecting when we leave the node.
|
||||
options = [{"desc": opt,
|
||||
"goto": (_input_parser,
|
||||
{"available_choices": page,
|
||||
"selection_processor": goto_processor})} for opt in page]
|
||||
|
||||
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})})
|
||||
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. This
|
||||
# allows us to call ourselves over and over, using different kwargs.
|
||||
if page_index > 0:
|
||||
options.append({"key": ("|wb|Wack|n", "b"),
|
||||
"goto": (lambda caller: None,
|
||||
{"optionpage_index": page_index - 1})})
|
||||
if page_index < npages - 1:
|
||||
options.append({"key": ("|wn|Wext|n", "n"),
|
||||
"goto": (lambda caller: None,
|
||||
{"optionpage_index": page_index + 1})})
|
||||
|
||||
options.append({"key": ("|Wcurrent|n", "c"),
|
||||
"desc": "|W({}/{})|n".format(page_index + 1, npages),
|
||||
"goto": (lambda caller: None,
|
||||
{"optionpage_index": page_index})})
|
||||
options.append({"key": "_default",
|
||||
"goto": (lambda caller: None,
|
||||
{"show_detail": True, "optionpage_index": page_index})})
|
||||
|
||||
# update text with detail, if set. Here we call _input_parser like a normal function
|
||||
text_detail = None
|
||||
if raw_string and 'show_detail' in kwargs:
|
||||
text_detail = _input_parser(
|
||||
caller, raw_string, **{"available_choices": page,
|
||||
"selection_processor": examine_processor})
|
||||
if text_detail is None:
|
||||
text_detail = "|rThat's not a valid command or option.|n"
|
||||
|
||||
# add data from the decorated node
|
||||
|
||||
text = ''
|
||||
try:
|
||||
text, extra_options = func(caller, raw_string)
|
||||
except TypeError:
|
||||
try:
|
||||
text, extra_options = func(caller)
|
||||
except Exception:
|
||||
raise
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
else:
|
||||
|
|
@ -1066,14 +1087,14 @@ def list_node(option_list, examine_processor, goto_processor, pagesize=10):
|
|||
extra_options = make_iter(extra_options)
|
||||
options.append(extra_options)
|
||||
|
||||
text = text + "\n\n" + text_detail if text_detail else text
|
||||
|
||||
return text, options
|
||||
|
||||
return _list_node
|
||||
return decorator
|
||||
|
||||
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# Simple input shortcuts
|
||||
|
|
|
|||
|
|
@ -109,13 +109,14 @@ from django.conf import settings
|
|||
from random import randint
|
||||
import evennia
|
||||
from evennia.objects.models import ObjectDB
|
||||
from evennia.utils.utils import make_iter, all_from_module, dbid_to_obj, is_iter, crop
|
||||
from evennia.utils.utils import (
|
||||
make_iter, all_from_module, dbid_to_obj, is_iter, crop, get_all_typeclasses)
|
||||
|
||||
from collections import namedtuple
|
||||
from evennia.scripts.scripts import DefaultScript
|
||||
from evennia.utils.create import create_script
|
||||
from evennia.utils.evtable import EvTable
|
||||
from evennia.utils.evmenu import EvMenu
|
||||
from evennia.utils.evmenu import EvMenu, list_node
|
||||
|
||||
|
||||
_CREATE_OBJECT_KWARGS = ("key", "location", "home", "destination")
|
||||
|
|
@ -856,6 +857,16 @@ def node_prototype(caller):
|
|||
return text, options
|
||||
|
||||
|
||||
def _typeclass_examine(caller, typeclass):
|
||||
return "This is typeclass |y{}|n.".format(typeclass)
|
||||
|
||||
|
||||
def _typeclass_select(caller, typeclass):
|
||||
caller.msg("Selected typeclass |y{}|n.".format(typeclass))
|
||||
return None
|
||||
|
||||
|
||||
@list_node(list(sorted(get_all_typeclasses().keys())), _typeclass_examine, _typeclass_select)
|
||||
def node_typeclass(caller):
|
||||
metaprot = _get_menu_metaprot(caller)
|
||||
prot = metaprot.prototype
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue