Updated scripts/ directory source to use Google style docstrings as per #709.
This commit is contained in:
parent
13042e6d1a
commit
d23a8a94db
4 changed files with 263 additions and 130 deletions
|
|
@ -38,9 +38,16 @@ class ScriptDBManager(TypedObjectManager):
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_all_scripts_on_obj(self, obj, key=None):
|
def get_all_scripts_on_obj(self, obj, key=None):
|
||||||
"""
|
"""
|
||||||
Returns as result all the Scripts related to a particular object.
|
Find all Scripts related to a particular object.
|
||||||
key can be given as a dbref or name string. If given, only scripts
|
|
||||||
matching the key on the object will be returned.
|
Args:
|
||||||
|
obj (Object): Object whose Scripts we are looking for.
|
||||||
|
key (str, optional): Script identifier - can be given as a
|
||||||
|
dbref or name string. If given, only scripts matching the
|
||||||
|
key on the object will be returned.
|
||||||
|
Returns:
|
||||||
|
matches (list): Matching scripts.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not obj:
|
if not obj:
|
||||||
return []
|
return []
|
||||||
|
|
@ -64,8 +71,15 @@ class ScriptDBManager(TypedObjectManager):
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_all_scripts(self, key=None):
|
def get_all_scripts(self, key=None):
|
||||||
"""
|
"""
|
||||||
Return all scripts, alternative only
|
Get all scripts in the database.
|
||||||
scripts with a certain key/dbref
|
|
||||||
|
Args:
|
||||||
|
key (str, optional): Restrict result to only those
|
||||||
|
with matching key or dbref.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
scripts (list): All scripts found, or those matching `key`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if key:
|
if key:
|
||||||
script = []
|
script = []
|
||||||
|
|
@ -79,10 +93,16 @@ class ScriptDBManager(TypedObjectManager):
|
||||||
|
|
||||||
def delete_script(self, dbref):
|
def delete_script(self, dbref):
|
||||||
"""
|
"""
|
||||||
This stops and deletes a specific script directly
|
This stops and deletes a specific script directly from the
|
||||||
from the script database. This might be
|
script database.
|
||||||
needed for global scripts not tied to
|
|
||||||
a specific game object.
|
Args:
|
||||||
|
dbref (int): Database unique id.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
This might be needed for global scripts not tied to a
|
||||||
|
specific game object
|
||||||
|
|
||||||
"""
|
"""
|
||||||
scripts = self.get_id(dbref)
|
scripts = self.get_id(dbref)
|
||||||
for script in make_iter(scripts):
|
for script in make_iter(scripts):
|
||||||
|
|
@ -91,8 +111,12 @@ class ScriptDBManager(TypedObjectManager):
|
||||||
def remove_non_persistent(self, obj=None):
|
def remove_non_persistent(self, obj=None):
|
||||||
"""
|
"""
|
||||||
This cleans up the script database of all non-persistent
|
This cleans up the script database of all non-persistent
|
||||||
scripts, or only those on obj. It is called every time the server
|
scripts. It is called every time the server restarts.
|
||||||
restarts.
|
|
||||||
|
Args:
|
||||||
|
obj (Object, optional): Only remove non-persistent scripts
|
||||||
|
assigned to this object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if obj:
|
if obj:
|
||||||
to_stop = self.filter(db_obj=obj, db_persistent=False, db_is_active=True)
|
to_stop = self.filter(db_obj=obj, db_persistent=False, db_is_active=True)
|
||||||
|
|
@ -114,26 +138,32 @@ class ScriptDBManager(TypedObjectManager):
|
||||||
all objects run scripts that are still valid in the context
|
all objects run scripts that are still valid in the context
|
||||||
they are in. This is called by the game engine at regular
|
they are in. This is called by the game engine at regular
|
||||||
intervals but can also be initiated by player scripts.
|
intervals but can also be initiated by player scripts.
|
||||||
If key and/or obj is given, only update the related
|
|
||||||
script/object.
|
|
||||||
|
|
||||||
Only one of the arguments are supposed to be supplied
|
Only one of the arguments are supposed to be supplied
|
||||||
at a time, since they are exclusive to each other.
|
at a time, since they are exclusive to each other.
|
||||||
|
|
||||||
scripts = a list of scripts objects obtained somewhere.
|
Args:
|
||||||
obj = validate only scripts defined on a special object.
|
scripts (list, optional): A list of script objects to
|
||||||
key = validate only scripts with a particular key
|
validate.
|
||||||
dbref = validate only the single script with this particular id.
|
obj (Object, optional): Validate only scripts defined on
|
||||||
|
this object.
|
||||||
|
key (str): Validate only scripts with this key.
|
||||||
|
dbref (int): Validate only the single script with this
|
||||||
|
particular id.
|
||||||
|
init_mode (str, optional): This is used during server
|
||||||
|
upstart and can have three values:
|
||||||
|
- `False` (no init mode). Called during run.
|
||||||
|
- `"reset"` - server reboot. Kill non-persistent scripts
|
||||||
|
- `"reload"` - server reload. Keep non-persistent scripts.
|
||||||
|
Returns:
|
||||||
|
nr_started, nr_stopped (tuple): Statistics on how many objects
|
||||||
|
where started and stopped.
|
||||||
|
|
||||||
init_mode - This is used during server upstart and can have
|
Notes:
|
||||||
three values:
|
This method also makes sure start any scripts it validates
|
||||||
False (no init mode). Called during run.
|
which should be harmless, since already-active scripts have
|
||||||
"reset" - server reboot. Kill non-persistent scripts
|
the property 'is_running' set and will be skipped.
|
||||||
"reload" - server reload. Keep non-persistent scripts.
|
|
||||||
|
|
||||||
This method also makes sure start any scripts it validates,
|
|
||||||
this should be harmless, since already-active scripts
|
|
||||||
have the property 'is_running' set and will be skipped.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# we store a variable that tracks if we are calling a
|
# we store a variable that tracks if we are calling a
|
||||||
|
|
@ -194,10 +224,13 @@ class ScriptDBManager(TypedObjectManager):
|
||||||
"""
|
"""
|
||||||
Search for a particular script.
|
Search for a particular script.
|
||||||
|
|
||||||
ostring - search criterion - a script ID or key
|
Args:
|
||||||
obj - limit search to scripts defined on this object
|
ostring (str): Search criterion - a script dbef or key.
|
||||||
only_timed - limit search only to scripts that run
|
obj (Object, optional): Limit search to scripts defined on
|
||||||
|
this object
|
||||||
|
only_timed (bool): Limit search only to scripts that run
|
||||||
on a timer.
|
on a timer.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ostring = ostring.strip()
|
ostring = ostring.strip()
|
||||||
|
|
@ -218,7 +251,18 @@ class ScriptDBManager(TypedObjectManager):
|
||||||
|
|
||||||
def copy_script(self, original_script, new_key=None, new_obj=None, new_locks=None):
|
def copy_script(self, original_script, new_key=None, new_obj=None, new_locks=None):
|
||||||
"""
|
"""
|
||||||
Make an identical copy of the original_script
|
Make an identical copy of the original_script.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
original_script (Script): The Script to copy.
|
||||||
|
new_key (str, optional): Rename the copy.
|
||||||
|
new_obj (Object, optional): Place copy on different Object.
|
||||||
|
new_locks (str, optional): Give copy different locks from
|
||||||
|
the original.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
script_copy (Script): A new Script instance, copied from
|
||||||
|
the original.
|
||||||
"""
|
"""
|
||||||
typeclass = original_script.typeclass_path
|
typeclass = original_script.typeclass_path
|
||||||
new_key = new_key if new_key is not None else original_script.key
|
new_key = new_key if new_key is not None else original_script.key
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ Scripts are entities that perform some sort of action, either only
|
||||||
once or repeatedly. They can be directly linked to a particular
|
once or repeatedly. They can be directly linked to a particular
|
||||||
Evennia Object or be stand-alonw (in the latter case it is considered
|
Evennia Object or be stand-alonw (in the latter case it is considered
|
||||||
a 'global' script). Scripts can indicate both actions related to the
|
a 'global' script). Scripts can indicate both actions related to the
|
||||||
game world as well as pure behind-the-scenes events and
|
game world as well as pure behind-the-scenes events and effects.
|
||||||
effects. Everything that has a time component in the game (i.e. is not
|
Everything that has a time component in the game (i.e. is not
|
||||||
hard-coded at startup or directly created/controlled by players) is
|
hard-coded at startup or directly created/controlled by players) is
|
||||||
handled by Scripts.
|
handled by Scripts.
|
||||||
|
|
||||||
|
|
@ -14,14 +14,14 @@ Scripts can also implement at_start and at_end hooks for preparing and
|
||||||
cleaning whatever effect they have had on the game object.
|
cleaning whatever effect they have had on the game object.
|
||||||
|
|
||||||
Common examples of uses of Scripts:
|
Common examples of uses of Scripts:
|
||||||
- load the default cmdset to the player object's cmdhandler
|
|
||||||
|
- Load the default cmdset to the player object's cmdhandler
|
||||||
when logging in.
|
when logging in.
|
||||||
- switch to a different state, such as entering a text editor,
|
- Switch to a different state, such as entering a text editor,
|
||||||
start combat or enter a dark room.
|
start combat or enter a dark room.
|
||||||
- Weather patterns in-game
|
- Merge a new cmdset with the default one for changing which
|
||||||
- merge a new cmdset with the default one for changing which
|
|
||||||
commands are available at a particular time
|
commands are available at a particular time
|
||||||
- give the player/object a time-limited bonus/effect
|
- Give the player/object a time-limited bonus/effect
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
@ -118,9 +118,10 @@ class ScriptDB(TypedObject):
|
||||||
# obj property
|
# obj property
|
||||||
def __get_obj(self):
|
def __get_obj(self):
|
||||||
"""
|
"""
|
||||||
property wrapper that homogenizes access to either
|
Property wrapper that homogenizes access to either the
|
||||||
the db_player or db_obj field, using the same obj
|
db_player or db_obj field, using the same object property
|
||||||
property name
|
name.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
obj = _GA(self, "db_player")
|
obj = _GA(self, "db_player")
|
||||||
if not obj:
|
if not obj:
|
||||||
|
|
@ -131,6 +132,7 @@ class ScriptDB(TypedObject):
|
||||||
"""
|
"""
|
||||||
Set player or obj to their right database field. If
|
Set player or obj to their right database field. If
|
||||||
a dbref is given, assume ObjectDB.
|
a dbref is given, assume ObjectDB.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
value = _GA(value, "dbobj")
|
value = _GA(value, "dbobj")
|
||||||
|
|
@ -157,25 +159,3 @@ class ScriptDB(TypedObject):
|
||||||
_GA(self, "save")(update_fields=[fname])
|
_GA(self, "save")(update_fields=[fname])
|
||||||
obj = property(__get_obj, __set_obj)
|
obj = property(__get_obj, __set_obj)
|
||||||
object = property(__get_obj, __set_obj)
|
object = property(__get_obj, __set_obj)
|
||||||
|
|
||||||
|
|
||||||
# def at_typeclass_error(self):
|
|
||||||
# """
|
|
||||||
# If this is called, it means the typeclass has a critical
|
|
||||||
# error and cannot even be loaded. We don't allow a script
|
|
||||||
# to be created under those circumstances. Already created,
|
|
||||||
# permanent scripts are set to already be active so they
|
|
||||||
# won't get activated now (next reboot the bug might be fixed)
|
|
||||||
# """
|
|
||||||
# # By setting is_active=True, we trick the script not to run "again".
|
|
||||||
# self.is_active = True
|
|
||||||
# return super(ScriptDB, self).at_typeclass_error()
|
|
||||||
#
|
|
||||||
# delete_iter = 0
|
|
||||||
# def delete(self):
|
|
||||||
# "Delete script"
|
|
||||||
# if self.delete_iter > 0:
|
|
||||||
# return
|
|
||||||
# self.delete_iter += 1
|
|
||||||
# _GA(self, "attributes").clear()
|
|
||||||
# super(ScriptDB, self).delete()
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
"""
|
"""
|
||||||
The script handler makes sure to check through all stored scripts
|
The script handler makes sure to check through all stored scripts to
|
||||||
to make sure they are still relevant.
|
make sure they are still relevant. A scripthandler is automatically
|
||||||
A scripthandler is automatically added to all game objects. You
|
added to all game objects. You access it through the property
|
||||||
access it through the property `scripts` on the game object.
|
`scripts` on the game object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from evennia.scripts.models import ScriptDB
|
from evennia.scripts.models import ScriptDB
|
||||||
|
|
@ -14,20 +15,24 @@ from django.utils.translation import ugettext as _
|
||||||
class ScriptHandler(object):
|
class ScriptHandler(object):
|
||||||
"""
|
"""
|
||||||
Implements the handler. This sits on each game object.
|
Implements the handler. This sits on each game object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
"""
|
"""
|
||||||
Set up internal state.
|
Set up internal state.
|
||||||
obj - a reference to the object this handler is attached to.
|
|
||||||
|
|
||||||
We retrieve all scripts attached to this object and check
|
Args:
|
||||||
if they are all persistent. If they are not, they are just
|
obj (Object): A reference to the object this handler is
|
||||||
cruft left over from a server shutdown.
|
attached to.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"List the scripts tied to this object"
|
"""
|
||||||
|
List the scripts tied to this object.
|
||||||
|
|
||||||
|
"""
|
||||||
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj)
|
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj)
|
||||||
string = ""
|
string = ""
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
|
|
@ -51,12 +56,14 @@ class ScriptHandler(object):
|
||||||
"""
|
"""
|
||||||
Add a script to this object.
|
Add a script to this object.
|
||||||
|
|
||||||
scriptclass - either a class object
|
Args:
|
||||||
inheriting from Script, an instantiated script object
|
scriptclass (Scriptclass, Script or str): Either a class
|
||||||
or a python path to such a class object.
|
object inheriting from DefaultScript, an instantiated
|
||||||
key - optional identifier for the script (often set in script
|
script object or a python path to such a class object.
|
||||||
definition)
|
key (str, optional): Identifier for the script (often set
|
||||||
autostart - start the script upon adding it
|
in script definition and listings)
|
||||||
|
autostart (bool, optional): Start the script upon adding it.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.obj.__dbclass__.__name__ == "PlayerDB":
|
if self.obj.__dbclass__.__name__ == "PlayerDB":
|
||||||
# we add to a Player, not an Object
|
# we add to a Player, not an Object
|
||||||
|
|
@ -71,56 +78,74 @@ class ScriptHandler(object):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def start(self, scriptid):
|
def start(self, key):
|
||||||
"""
|
"""
|
||||||
Find an already added script and force-start it
|
Find scripts and force-start them
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The script's key or dbref.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
nr_started (int): The number of started scripts found.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=key)
|
||||||
num = 0
|
num = 0
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
num += script.start()
|
num += script.start()
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def get(self, scriptid):
|
def get(self, key):
|
||||||
"""
|
"""
|
||||||
Return one or all scripts on this object matching `scriptid`. Will return
|
Search scripts on this object.
|
||||||
a list.
|
|
||||||
"""
|
|
||||||
return ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
|
||||||
|
|
||||||
def delete(self, scriptid=None):
|
Args:
|
||||||
|
key (str): Search criterion, the script's key or dbref.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
scripts (list): The found scripts matching `key`.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=key)
|
||||||
|
|
||||||
|
def delete(self, key=None):
|
||||||
"""
|
"""
|
||||||
Forcibly delete a script from this object.
|
Forcibly delete a script from this object.
|
||||||
|
|
||||||
scriptid can be a script key or the path to a script (in the
|
Args:
|
||||||
|
key (str, optional): A script key or the path to a script (in the
|
||||||
latter case all scripts with this path will be deleted!)
|
latter case all scripts with this path will be deleted!)
|
||||||
If no scriptid is set, delete all scripts on the object.
|
If no key is given, delete *all* scripts on the object!
|
||||||
|
|
||||||
"""
|
"""
|
||||||
delscripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
delscripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=key)
|
||||||
if not delscripts:
|
if not delscripts:
|
||||||
delscripts = [script for script in ScriptDB.objects.get_all_scripts_on_obj(self.obj) if script.path == scriptid]
|
delscripts = [script for script in ScriptDB.objects.get_all_scripts_on_obj(self.obj) if script.path == key]
|
||||||
num = 0
|
num = 0
|
||||||
for script in delscripts:
|
for script in delscripts:
|
||||||
num += script.stop()
|
num += script.stop()
|
||||||
return num
|
return num
|
||||||
|
# alias to delete
|
||||||
|
stop = delete
|
||||||
|
|
||||||
def stop(self, scriptid=None):
|
def all(self):
|
||||||
"""
|
"""
|
||||||
Alias for delete. scriptid can be a script key or a script path string.
|
Get all scripts stored in this handler.
|
||||||
"""
|
|
||||||
return self.delete(scriptid)
|
|
||||||
|
|
||||||
def all(self, scriptid=None):
|
|
||||||
"""
|
"""
|
||||||
Get all scripts stored in the handler, alternatively all matching a key.
|
return ScriptDB.objects.get_all_scripts_on_obj(self.obj)
|
||||||
"""
|
|
||||||
return ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
|
||||||
|
|
||||||
def validate(self, init_mode=False):
|
def validate(self, init_mode=False):
|
||||||
"""
|
"""
|
||||||
Runs a validation on this object's scripts only.
|
Runs a validation on this object's scripts only. This should
|
||||||
This should be called regularly to crank the wheels.
|
be called regularly to crank the wheels.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
init_mode (str, optional): - This is used during server
|
||||||
|
upstart and can have three values:
|
||||||
|
- `False` (no init mode). Called during run.
|
||||||
|
- `"reset"` - server reboot. Kill non-persistent scripts
|
||||||
|
- `"reload"` - server reload. Keep non-persistent scripts.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ScriptDB.objects.validate(obj=self.obj, init_mode=init_mode)
|
ScriptDB.objects.validate(obj=self.obj, init_mode=init_mode)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,12 @@ class Ticker(object):
|
||||||
If overloading, this callback is expected to handle all
|
If overloading, this callback is expected to handle all
|
||||||
subscriptions when it is triggered. It should not return
|
subscriptions when it is triggered. It should not return
|
||||||
anything and should not traceback on poorly designed hooks.
|
anything and should not traceback on poorly designed hooks.
|
||||||
The callback should ideally work under @inlineCallbacks so it can yield
|
The callback should ideally work under @inlineCallbacks so it
|
||||||
appropriately.
|
can yield appropriately.
|
||||||
|
|
||||||
|
The _hook_key, which is passed down through the handler via
|
||||||
|
kwargs is used here to identify which hook method to call.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for store_key, (obj, args, kwargs) in self.subscriptions.items():
|
for store_key, (obj, args, kwargs) in self.subscriptions.items():
|
||||||
hook_key = yield kwargs.pop("_hook_key", "at_tick")
|
hook_key = yield kwargs.pop("_hook_key", "at_tick")
|
||||||
|
|
@ -111,6 +115,10 @@ class Ticker(object):
|
||||||
def __init__(self, interval):
|
def __init__(self, interval):
|
||||||
"""
|
"""
|
||||||
Set up the ticker
|
Set up the ticker
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interval (int): The stepping interval.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
self.subscriptions = {}
|
self.subscriptions = {}
|
||||||
|
|
@ -119,8 +127,12 @@ class Ticker(object):
|
||||||
|
|
||||||
def validate(self, start_delay=None):
|
def validate(self, start_delay=None):
|
||||||
"""
|
"""
|
||||||
Start/stop the task depending on how many
|
Start/stop the task depending on how many subscribers we have
|
||||||
subscribers we have using it.
|
using it.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
start_delay (int): Time to way before starting.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
subs = self.subscriptions
|
subs = self.subscriptions
|
||||||
if None in subs.values():
|
if None in subs.values():
|
||||||
|
|
@ -135,9 +147,19 @@ class Ticker(object):
|
||||||
|
|
||||||
def add(self, store_key, obj, *args, **kwargs):
|
def add(self, store_key, obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Sign up a subscriber to this ticker. If kwargs contains
|
Sign up a subscriber to this ticker.
|
||||||
a keyword _start_delay, this will be used to delay the start
|
Args:
|
||||||
of the trigger instead of interval.
|
store_key (str): Unique storage hash for this ticker subscription.
|
||||||
|
obj (Object): Object subscribing to this ticker.
|
||||||
|
args (any, optional): Arguments to call the hook method with.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
_start_delay (int): If set, this will be
|
||||||
|
used to delay the start of the trigger instead of
|
||||||
|
`interval`.
|
||||||
|
_hooK_key (str): This carries the name of the hook method
|
||||||
|
to call. It is passed on as-is from this method.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
start_delay = kwargs.pop("_start_delay", None)
|
start_delay = kwargs.pop("_start_delay", None)
|
||||||
self.subscriptions[store_key] = (obj, args, kwargs)
|
self.subscriptions[store_key] = (obj, args, kwargs)
|
||||||
|
|
@ -146,13 +168,18 @@ class Ticker(object):
|
||||||
def remove(self, store_key):
|
def remove(self, store_key):
|
||||||
"""
|
"""
|
||||||
Unsubscribe object from this ticker
|
Unsubscribe object from this ticker
|
||||||
|
|
||||||
|
Args:
|
||||||
|
store_key (str): Unique store key.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.subscriptions.pop(store_key, False)
|
self.subscriptions.pop(store_key, False)
|
||||||
self.validate()
|
self.validate()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Kill the Task, regardless of subscriptions
|
Kill the Task, regardless of subscriptions.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.subscriptions = {}
|
self.subscriptions = {}
|
||||||
self.validate()
|
self.validate()
|
||||||
|
|
@ -160,18 +187,37 @@ class Ticker(object):
|
||||||
|
|
||||||
class TickerPool(object):
|
class TickerPool(object):
|
||||||
"""
|
"""
|
||||||
This maintains a pool of Twisted LoopingCall tasks
|
This maintains a pool of
|
||||||
for calling subscribed objects at given times.
|
`evennia.scripts.scripts.ExtendedLoopingCall` tasks for calling
|
||||||
|
subscribed objects at given times.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ticker_class = Ticker
|
ticker_class = Ticker
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"Initialize the pool"
|
"""
|
||||||
|
Initialize the pool.
|
||||||
|
|
||||||
|
"""
|
||||||
self.tickers = {}
|
self.tickers = {}
|
||||||
|
|
||||||
def add(self, store_key, obj, interval, *args, **kwargs):
|
def add(self, store_key, obj, interval, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Add new ticker subscriber
|
Add new ticker subscriber.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
store_key (str): Unique storage hash.
|
||||||
|
obj (Object): Object subscribing.
|
||||||
|
interval (int): How often to call the ticker.
|
||||||
|
args (any, optional): Arguments to send to the hook method.
|
||||||
|
|
||||||
|
Kwargs:
|
||||||
|
_start_delay (int): If set, this will be
|
||||||
|
used to delay the start of the trigger instead of
|
||||||
|
`interval`. It is passed on as-is from this method.
|
||||||
|
_hooK_key (str): This carries the name of the hook method
|
||||||
|
to call. It is passed on as-is from this method.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not interval:
|
if not interval:
|
||||||
log_err(_ERROR_ADD_INTERVAL.format(store_key=store_key, obj=obj,
|
log_err(_ERROR_ADD_INTERVAL.format(store_key=store_key, obj=obj,
|
||||||
|
|
@ -184,7 +230,16 @@ class TickerPool(object):
|
||||||
|
|
||||||
def remove(self, store_key, interval):
|
def remove(self, store_key, interval):
|
||||||
"""
|
"""
|
||||||
Remove subscription from pool
|
Remove subscription from pool.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
store_key (str): Unique storage hash.
|
||||||
|
interval (int): Ticker interval.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
A given subscription is uniquely identified both
|
||||||
|
via its `store_key` and its `interval`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if interval in self.tickers:
|
if interval in self.tickers:
|
||||||
self.tickers[interval].remove(store_key)
|
self.tickers[interval].remove(store_key)
|
||||||
|
|
@ -193,7 +248,11 @@ class TickerPool(object):
|
||||||
"""
|
"""
|
||||||
Stop all scripts in pool. This is done at server reload since
|
Stop all scripts in pool. This is done at server reload since
|
||||||
restoring the pool will automatically re-populate the pool.
|
restoring the pool will automatically re-populate the pool.
|
||||||
If interval is given, only stop tickers with that interval.
|
|
||||||
|
Args:
|
||||||
|
interval (int, optional): Only stop tickers with this
|
||||||
|
interval.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if interval and interval in self.tickers:
|
if interval and interval in self.tickers:
|
||||||
self.tickers[interval].stop()
|
self.tickers[interval].stop()
|
||||||
|
|
@ -207,12 +266,17 @@ class TickerHandler(object):
|
||||||
The Tickerhandler maintains a pool of tasks for subscribing
|
The Tickerhandler maintains a pool of tasks for subscribing
|
||||||
objects to various tick rates. The pool maintains creation
|
objects to various tick rates. The pool maintains creation
|
||||||
instructions and and re-applies them at a server restart.
|
instructions and and re-applies them at a server restart.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ticker_pool_class = TickerPool
|
ticker_pool_class = TickerPool
|
||||||
|
|
||||||
def __init__(self, save_name="ticker_storage"):
|
def __init__(self, save_name="ticker_storage"):
|
||||||
"""
|
"""
|
||||||
Initialize handler
|
Initialize handler
|
||||||
|
|
||||||
|
save_name (str, optional): The name of the ServerConfig
|
||||||
|
instance to store the handler state persistently.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.ticker_storage = {}
|
self.ticker_storage = {}
|
||||||
self.save_name = save_name
|
self.save_name = save_name
|
||||||
|
|
@ -220,10 +284,16 @@ class TickerHandler(object):
|
||||||
|
|
||||||
def _store_key(self, obj, interval, idstring=""):
|
def _store_key(self, obj, interval, idstring=""):
|
||||||
"""
|
"""
|
||||||
Tries to create a store_key for the object.
|
Tries to create a store_key for the object. Returns a tuple
|
||||||
Returns a tuple (isdb, store_key) where isdb
|
(isdb, store_key) where isdb is a boolean True if obj was a
|
||||||
is a boolean True if obj was a database object,
|
database object, False otherwise.
|
||||||
False otherwise.
|
|
||||||
|
Args:
|
||||||
|
obj (Object): Subscribing object.
|
||||||
|
interval (int): Ticker interval
|
||||||
|
idstring (str, optional): Additional separator between
|
||||||
|
different subscription types.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if hasattr(obj, "db_key"):
|
if hasattr(obj, "db_key"):
|
||||||
# create a store_key using the database representation
|
# create a store_key using the database representation
|
||||||
|
|
@ -243,9 +313,10 @@ class TickerHandler(object):
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
Save ticker_storage as a serialized string into a temporary
|
Save ticker_storage as a serialized string into a temporary
|
||||||
ServerConf field. Whereas saving is done on the fly, if called by
|
ServerConf field. Whereas saving is done on the fly, if called
|
||||||
server when it shuts down, the current timer of each ticker will be
|
by server when it shuts down, the current timer of each ticker
|
||||||
saved so it can start over from that point.
|
will be saved so it can start over from that point.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.ticker_storage:
|
if self.ticker_storage:
|
||||||
start_delays = dict((interval, ticker.task.next_call_time())
|
start_delays = dict((interval, ticker.task.next_call_time())
|
||||||
|
|
@ -349,10 +420,15 @@ class TickerHandler(object):
|
||||||
|
|
||||||
def clear(self, interval=None):
|
def clear(self, interval=None):
|
||||||
"""
|
"""
|
||||||
Stop/remove all tickers from handler, or the ones
|
Stop/remove all tickers from handler.
|
||||||
with a given interval. This is the only supported
|
|
||||||
way to kill tickers for non-db objects. If interval
|
Args:
|
||||||
is given, only stop tickers with this interval.
|
interval (int): Only stop tickers with this interval.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
This is the only supported way to kill tickers related to
|
||||||
|
non-db objects.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.ticker_pool.stop(interval)
|
self.ticker_pool.stop(interval)
|
||||||
if interval:
|
if interval:
|
||||||
|
|
@ -365,9 +441,17 @@ class TickerHandler(object):
|
||||||
|
|
||||||
def all(self, interval=None):
|
def all(self, interval=None):
|
||||||
"""
|
"""
|
||||||
Get the subsciptions for a given interval. If interval
|
Get all subscriptions.
|
||||||
is not given, return a dictionary with lists for every
|
|
||||||
interval in the tickerhandler.
|
Args:
|
||||||
|
interval (int): Limit match to tickers with this interval.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tickers (list): If `interval` was given, this is a list of
|
||||||
|
tickers using that interval.
|
||||||
|
tickerpool_layout (dict): If `interval` was *not* given,
|
||||||
|
this is a dict {interval1: [ticker1, ticker2, ...], ...}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if interval is None:
|
if interval is None:
|
||||||
# return dict of all, ordered by interval
|
# return dict of all, ordered by interval
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue