Move create methods into managers, leave utils.create as wrappers.

Resolve #2118.
This commit is contained in:
Griatch 2022-01-09 00:28:11 +01:00
parent cc22a776ee
commit e70337b6d2
8 changed files with 692 additions and 522 deletions

View file

@ -2,13 +2,19 @@
The custom manager for Scripts.
"""
from django.conf import settings
from django.db.models import Q
from evennia.typeclasses.managers import TypedObjectManager, TypeclassManager
from evennia.utils.utils import make_iter
from evennia.utils.utils import make_iter, class_from_module, dbid_to_obj
from evennia.server import signals
__all__ = ("ScriptManager", "ScriptDBManager")
_GA = object.__getattribute__
_ObjectDB = None
_AccountDB = None
VALIDATE_ITERATION = 0
@ -81,7 +87,6 @@ class ScriptDBManager(TypedObjectManager):
"""
if key:
script = []
dbref = self.dbref(key)
if dbref:
return self.filter(id=dbref)
@ -191,6 +196,129 @@ class ScriptDBManager(TypedObjectManager):
)
return new_script
def create_script(
self,
typeclass=None,
key=None,
obj=None,
account=None,
locks=None,
interval=None,
start_delay=None,
repeats=None,
persistent=None,
autostart=True,
report_to=None,
desc=None,
tags=None,
attributes=None,
):
"""
Create a new script. All scripts are a combination of a database
object that communicates with the database, and an typeclass that
'decorates' the database object into being different types of
scripts. It's behaviour is similar to the game objects except
scripts has a time component and are more limited in scope.
Keyword Args:
typeclass (class or str): Class or python path to a typeclass.
key (str): Name of the new object. If not set, a name of
#dbref will be set.
obj (Object): The entity on which this Script sits. If this
is `None`, we are creating a "global" script.
account (Account): The account on which this Script sits. It is
exclusiv to `obj`.
locks (str): one or more lockstrings, separated by semicolons.
interval (int): The triggering interval for this Script, in
seconds. If unset, the Script will not have a timing
component.
start_delay (bool): If `True`, will wait `interval` seconds
before triggering the first time.
repeats (int): The number of times to trigger before stopping.
If unset, will repeat indefinitely.
persistent (bool): If this Script survives a server shutdown
or not (all Scripts will survive a reload).
autostart (bool): If this Script will start immediately when
created or if the `start` method must be called explicitly.
report_to (Object): The object to return error messages to.
desc (str): Optional description of script
tags (list): List of tags or tuples (tag, category).
attributes (list): List if tuples (key, value) or (key, value, category)
(key, value, lockstring) or (key, value, lockstring, default_access).
Returns:
script (obj): An instance of the script created
See evennia.scripts.manager for methods to manipulate existing
scripts in the database.
"""
global _ObjectDB, _AccountDB
if not _ObjectDB:
from evennia.objects.models import ObjectDB as _ObjectDB
from evennia.accounts.models import AccountDB as _AccountDB
typeclass = typeclass if typeclass else settings.BASE_SCRIPT_TYPECLASS
if isinstance(typeclass, str):
# a path is given. Load the actual typeclass
typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS)
# validate input
kwarg = {}
if key:
kwarg["db_key"] = key
if account:
kwarg["db_account"] = dbid_to_obj(account, _AccountDB)
if obj:
kwarg["db_obj"] = dbid_to_obj(obj, _ObjectDB)
if interval:
kwarg["db_interval"] = max(0, interval)
if start_delay:
kwarg["db_start_delay"] = start_delay
if repeats:
kwarg["db_repeats"] = max(0, repeats)
if persistent:
kwarg["db_persistent"] = persistent
if desc:
kwarg["db_desc"] = desc
tags = make_iter(tags) if tags is not None else None
attributes = make_iter(attributes) if attributes is not None else None
# create new instance
new_script = typeclass(**kwarg)
# store the call signature for the signal
new_script._createdict = dict(
key=key,
obj=obj,
account=account,
locks=locks,
interval=interval,
start_delay=start_delay,
repeats=repeats,
persistent=persistent,
autostart=autostart,
report_to=report_to,
desc=desc,
tags=tags,
attributes=attributes,
)
# this will trigger the save signal which in turn calls the
# at_first_save hook on the typeclass, where the _createdict
# can be used.
new_script.save()
if not new_script.id:
# this happens in the case of having a repeating script with `repeats=1` and
# `start_delay=False` - the script will run once and immediately stop before
# save is over.
return None
signals.SIGNAL_SCRIPT_POST_CREATE.send(sender=new_script)
return new_script
class ScriptManager(ScriptDBManager, TypeclassManager):
pass