Make EvMenu nodes-options' 'exec' callbacks able to return a string for dynamic goto replacement.
This commit is contained in:
parent
a403cc9576
commit
f7936df104
1 changed files with 46 additions and 14 deletions
|
|
@ -71,10 +71,14 @@ menu is immediately exited and the default "look" command is called.
|
||||||
# fallback when no other option matches the user input.
|
# fallback when no other option matches the user input.
|
||||||
'desc': description, # optional description
|
'desc': description, # optional description
|
||||||
'goto': nodekey, # node to go to when chosen
|
'goto': nodekey, # node to go to when chosen
|
||||||
'exec': nodekey}, # node or callback to trigger as callback when chosen.
|
'exec': nodekey}, # node or callback to trigger as callback when chosen. This
|
||||||
# If a node key is given, the node will be executed once
|
# will execute *before* going to the next node. Both node
|
||||||
# but its return values are ignored. If a callable is
|
# and the explicit callback will be called as normal nodes
|
||||||
# given, it must accept one or two args, like any node.
|
# (with caller and/or raw_string args). If the callable/node
|
||||||
|
# returns a single string (only), this will replace the current
|
||||||
|
# goto location string in-place. Note that relying to
|
||||||
|
# much on letting exec assign the goto location can make it
|
||||||
|
# hard to debug your menu logic.
|
||||||
{...}, ...)
|
{...}, ...)
|
||||||
|
|
||||||
If key is not given, the option will automatically be identified by
|
If key is not given, the option will automatically be identified by
|
||||||
|
|
@ -99,7 +103,9 @@ Example:
|
||||||
|
|
||||||
def callback1(caller):
|
def callback1(caller):
|
||||||
# this is called when choosing the "testing" option in node1
|
# this is called when choosing the "testing" option in node1
|
||||||
# (before going to node2). It needs not have return values.
|
# (before going to node2). If it returned a string, say 'node3',
|
||||||
|
# then the next node would be node3 instead of node2 as specified
|
||||||
|
# by the normal 'goto' option key above.
|
||||||
caller.msg("Callback called!")
|
caller.msg("Callback called!")
|
||||||
|
|
||||||
def node2(caller):
|
def node2(caller):
|
||||||
|
|
@ -371,7 +377,7 @@ def null_node_formatter(nodetext, optionstext, caller=None):
|
||||||
|
|
||||||
def evtable_parse_input(menuobject, raw_string, caller):
|
def evtable_parse_input(menuobject, raw_string, caller):
|
||||||
"""
|
"""
|
||||||
Processes the user' node inputs.
|
Processes the user's node inputs.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
menuobject (EvMenu): The EvMenu instance
|
menuobject (EvMenu): The EvMenu instance
|
||||||
|
|
@ -710,21 +716,44 @@ class EvMenu(object):
|
||||||
|
|
||||||
|
|
||||||
def callback_goto(self, callback, goto, raw_string):
|
def callback_goto(self, callback, goto, raw_string):
|
||||||
|
"""
|
||||||
|
Call callback and goto in sequence.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
callback (callable or str): Callback to run before goto. If
|
||||||
|
the callback returns a string, this is used to replace
|
||||||
|
the `goto` string before going to the next node.
|
||||||
|
goto (str): The target node to go to next (unless replaced
|
||||||
|
by `callable`)..
|
||||||
|
raw_string (str): The original user input.
|
||||||
|
|
||||||
|
"""
|
||||||
if callback:
|
if callback:
|
||||||
self.callback(callback, raw_string)
|
# replace goto only if callback returns
|
||||||
|
goto = self.callback(callback, raw_string) or goto
|
||||||
if goto:
|
if goto:
|
||||||
self.goto(goto, raw_string)
|
self.goto(goto, raw_string)
|
||||||
|
|
||||||
def callback(self, nodename, raw_string):
|
def callback(self, nodename, raw_string):
|
||||||
"""
|
"""
|
||||||
Run a node as a callback. This makes no use of the return
|
Run a function or node as a callback (with the 'exec' option key).
|
||||||
values from the node.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nodename (str): Name of node.
|
nodename (callable or str): A callable to run as
|
||||||
|
`callable(caller, raw_string)`, or the Name of an existing
|
||||||
|
node to run as a callable. This may or may not return
|
||||||
|
a string.
|
||||||
raw_string (str): The raw default string entered on the
|
raw_string (str): The raw default string entered on the
|
||||||
previous node (only used if the node accepts it as an
|
previous node (only used if the node accepts it as an
|
||||||
argument)
|
argument)
|
||||||
|
Returns:
|
||||||
|
new_goto (str or None): A replacement goto location string or
|
||||||
|
None (no replacement).
|
||||||
|
Notes:
|
||||||
|
Relying on exec callbacks to set the goto location is
|
||||||
|
very powerful but will easily lead to spaghetti structure and
|
||||||
|
hard-to-trace paths through the menu logic. So be careful with
|
||||||
|
relying on this.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if callable(nodename):
|
if callable(nodename):
|
||||||
|
|
@ -732,20 +761,23 @@ class EvMenu(object):
|
||||||
try:
|
try:
|
||||||
if len(getargspec(nodename).args) > 1:
|
if len(getargspec(nodename).args) > 1:
|
||||||
# callable accepting raw_string
|
# callable accepting raw_string
|
||||||
nodename(self.caller, raw_string)
|
ret = nodename(self.caller, raw_string)
|
||||||
else:
|
else:
|
||||||
# normal callable, only the caller as arg
|
# normal callable, only the caller as arg
|
||||||
nodename(self.caller)
|
ret = nodename(self.caller)
|
||||||
except Exception:
|
except Exception:
|
||||||
self.caller.msg(_ERR_GENERAL.format(nodename=nodename), self._session)
|
self.caller.msg(_ERR_GENERAL.format(nodename=nodename), self._session)
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
# nodename is a string; lookup as node
|
# nodename is a string; lookup as node
|
||||||
try:
|
try:
|
||||||
# execute the node; we make no use of the return values here.
|
# execute the node
|
||||||
self._execute_node(nodename, raw_string)
|
ret = self._execute_node(nodename, raw_string)
|
||||||
except EvMenuError:
|
except EvMenuError:
|
||||||
return
|
return
|
||||||
|
if isinstance(basestring, ret):
|
||||||
|
# only return a value if a string (a goto target), ignore all other returns
|
||||||
|
return ret
|
||||||
|
|
||||||
def goto(self, nodename, raw_string):
|
def goto(self, nodename, raw_string):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue