[feat] Script refactor; decouple timer component from script lifetime. Resolve #1715
This commit is contained in:
parent
cd579fb649
commit
b5195a6e96
29 changed files with 1136 additions and 1266 deletions
|
|
@ -155,12 +155,12 @@ class GlobalScriptContainer(Container):
|
|||
new_script.start()
|
||||
return new_script
|
||||
|
||||
if (
|
||||
(found.interval != interval)
|
||||
if ((found.interval != interval)
|
||||
or (found.start_delay != start_delay)
|
||||
or (found.repeats != repeats)
|
||||
):
|
||||
found.restart(interval=interval, start_delay=start_delay, repeats=repeats)
|
||||
# the setup changed
|
||||
found.start(interval=interval, start_delay=start_delay, repeats=repeats)
|
||||
if found.desc != desc:
|
||||
found.desc = desc
|
||||
return found
|
||||
|
|
|
|||
|
|
@ -31,9 +31,11 @@ class TestCreateScript(EvenniaTest):
|
|||
self.repeats = 1
|
||||
self.persistent = False
|
||||
|
||||
# script is already stopped (interval=1, start_delay=False)
|
||||
# script should still exist even though repeats=1, start_delay=False
|
||||
script = create.create_script(TestScriptB, key="test_script")
|
||||
assert script is None
|
||||
assert script
|
||||
# but the timer should be inactive now
|
||||
assert not script.is_active
|
||||
|
||||
def test_create_script_w_repeats_equal_1_persisted(self):
|
||||
class TestScriptB1(DefaultScript):
|
||||
|
|
@ -45,7 +47,9 @@ class TestCreateScript(EvenniaTest):
|
|||
|
||||
# script is already stopped (interval=1, start_delay=False)
|
||||
script = create.create_script(TestScriptB1, key="test_script")
|
||||
assert script is None
|
||||
assert script
|
||||
assert not script.is_active
|
||||
|
||||
|
||||
def test_create_script_w_repeats_equal_2(self):
|
||||
class TestScriptC(DefaultScript):
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@ _MULTIMATCH_TEMPLATE = settings.SEARCH_MULTIMATCH_TEMPLATE
|
|||
_EVENNIA_DIR = settings.EVENNIA_DIR
|
||||
_GAME_DIR = settings.GAME_DIR
|
||||
ENCODINGS = settings.ENCODINGS
|
||||
|
||||
_TASK_HANDLER = None
|
||||
_TICKER_HANDLER = None
|
||||
|
||||
_GA = object.__getattribute__
|
||||
_SA = object.__setattr__
|
||||
_DA = object.__delattr__
|
||||
|
|
@ -1016,7 +1020,6 @@ def uses_database(name="sqlite3"):
|
|||
return engine == "django.db.backends.%s" % name
|
||||
|
||||
|
||||
_TASK_HANDLER = None
|
||||
|
||||
|
||||
def delay(timedelay, callback, *args, **kwargs):
|
||||
|
|
@ -1050,12 +1053,81 @@ def delay(timedelay, callback, *args, **kwargs):
|
|||
|
||||
"""
|
||||
global _TASK_HANDLER
|
||||
# Do some imports here to avoid circular import and speed things up
|
||||
if _TASK_HANDLER is None:
|
||||
from evennia.scripts.taskhandler import TASK_HANDLER as _TASK_HANDLER
|
||||
|
||||
return _TASK_HANDLER.add(timedelay, callback, *args, **kwargs)
|
||||
|
||||
|
||||
def repeat(interval, callback, persistent=True, idstring="", stop=False,
|
||||
store_key=None, *args, **kwargs):
|
||||
"""
|
||||
Start a repeating task using the TickerHandler.
|
||||
|
||||
Args:
|
||||
interval (int): How often to call callback.
|
||||
callback (callable): This will be called with `*args, **kwargs` every
|
||||
`interval` seconds. This must be possible to pickle regardless
|
||||
of if `persistent` is set or not!
|
||||
persistent (bool, optional): If ticker survives a server reload.
|
||||
idstring (str, optional): Separates multiple tickers. This is useful
|
||||
mainly if wanting to set up multiple repeats for the same
|
||||
interval/callback but with different args/kwargs.
|
||||
stop (bool, optional): If set, use the given parameters to _stop_ a running
|
||||
ticker instead of creating a new one.
|
||||
store_key (tuple, optional): This is only used in combination with `stop` and
|
||||
should be the return given from the original `repeat` call. If this
|
||||
is given, all other args except `stop` are ignored.
|
||||
*args, **kwargs: Used as arguments to `callback`.
|
||||
|
||||
Returns:
|
||||
tuple or None: This is the `store_key` - the identifier for the created ticker.
|
||||
Store this and pass into unrepat() in order to to stop this ticker
|
||||
later. It this lost you need to stop the ticker via TICKER_HANDLER.remove
|
||||
by supplying all the same arguments
|
||||
directly. No return if `stop=True`
|
||||
|
||||
Raises:
|
||||
KeyError: If trying to stop a ticker that was not found.
|
||||
|
||||
"""
|
||||
global _TICKER_HANDLER
|
||||
if _TICKER_HANDLER is None:
|
||||
from evennia.scripts.tickerhandler import TICKER_HANDLER as _TICKER_HANDLER
|
||||
|
||||
if stop:
|
||||
# we pass all args, but only store_key matters if given
|
||||
_TICKER_HANDLER.remove(interval=interval,
|
||||
callback=callback,
|
||||
idstring=idstring,
|
||||
persistent=persistent,
|
||||
store_key=store_key)
|
||||
else:
|
||||
return _TICKER_HANDLER.add(interval=interval,
|
||||
callback=callback,
|
||||
idstring=idstring,
|
||||
persistent=persistent)
|
||||
|
||||
def unrepeat(store_key):
|
||||
"""
|
||||
This is used to stop a ticker previously started with `repeat`.
|
||||
|
||||
Args:
|
||||
store_key (tuple): This is the return from `repeat`, used to uniquely
|
||||
identify the ticker to stop.
|
||||
|
||||
Returns:
|
||||
bool: True if a ticker was stopped, False if not (for example because no
|
||||
matching ticker was found or it was already stopped).
|
||||
|
||||
"""
|
||||
try:
|
||||
repeat(None, None, stop=True, store_key=store_key)
|
||||
return True
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
|
||||
_PPOOL = None
|
||||
_PCMD = None
|
||||
_PROC_ERR = "A process has ended with a probable error condition: process ended by signal 9."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue