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

@ -7,6 +7,9 @@ from django.conf import settings
from django.db.models.fields import exceptions
from evennia.typeclasses.managers import TypedObjectManager, TypeclassManager
from evennia.utils.utils import is_iter, make_iter, string_partial_matching
from evennia.utils.utils import class_from_module, dbid_to_obj
from evennia.server import signals
__all__ = ("ObjectManager", "ObjectDBManager")
_GA = object.__getattribute__
@ -595,6 +598,117 @@ class ObjectDBManager(TypedObjectManager):
"""
self.filter(db_sessid__isnull=False).update(db_sessid=None)
def create_object(
self,
typeclass=None,
key=None,
location=None,
home=None,
permissions=None,
locks=None,
aliases=None,
tags=None,
destination=None,
report_to=None,
nohome=False,
attributes=None,
nattributes=None,
):
"""
Create a new in-game object.
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.
location (Object or str): Obj or #dbref to use as the location of the new object.
home (Object or str): Obj or #dbref to use as the object's home location.
permissions (list): A list of permission strings or tuples (permstring, category).
locks (str): one or more lockstrings, separated by semicolons.
aliases (list): A list of alternative keys or tuples (aliasstring, category).
tags (list): List of tag keys or tuples (tagkey, category) or (tagkey, category, data).
destination (Object or str): Obj or #dbref to use as an Exit's target.
report_to (Object): The object to return error messages to.
nohome (bool): This allows the creation of objects without a
default home location; only used when creating the default
location itself or during unittests.
attributes (list): Tuples on the form (key, value) or (key, value, category),
(key, value, lockstring) or (key, value, lockstring, default_access).
to set as Attributes on the new object.
nattributes (list): Non-persistent tuples on the form (key, value). Note that
adding this rarely makes sense since this data will not survive a reload.
Returns:
object (Object): A newly created object of the given typeclass.
Raises:
ObjectDB.DoesNotExist: If trying to create an Object with
`location` or `home` that can't be found.
"""
typeclass = typeclass if typeclass else settings.BASE_OBJECT_TYPECLASS
# convenience converters to avoid common usage mistake
permissions = make_iter(permissions) if permissions is not None else None
locks = make_iter(locks) if locks is not None else None
aliases = make_iter(aliases) if aliases is not None else None
tags = make_iter(tags) if tags is not None else None
attributes = make_iter(attributes) if attributes is not None else None
if isinstance(typeclass, str):
# a path is given. Load the actual typeclass
typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS)
# Setup input for the create command. We use ObjectDB as baseclass here
# to give us maximum freedom (the typeclasses will load
# correctly when each object is recovered).
location = dbid_to_obj(location, self.model)
destination = dbid_to_obj(destination, self.model)
home = dbid_to_obj(home, self.model)
if not home:
try:
home = dbid_to_obj(settings.DEFAULT_HOME, self.model) if not nohome else None
except self.model_ObjectDB.DoesNotExist:
raise self.model.DoesNotExist(
"settings.DEFAULT_HOME (= '%s') does not exist, or the setting is malformed."
% settings.DEFAULT_HOME
)
# create new instance
new_object = typeclass(
db_key=key,
db_location=location,
db_destination=destination,
db_home=home,
db_typeclass_path=typeclass.path,
)
# store the call signature for the signal
new_object._createdict = dict(
key=key,
location=location,
destination=destination,
home=home,
typeclass=typeclass.path,
permissions=permissions,
locks=locks,
aliases=aliases,
tags=tags,
report_to=report_to,
nohome=nohome,
attributes=attributes,
nattributes=nattributes,
)
# 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_object.save()
signals.SIGNAL_OBJECT_POST_CREATE.send(sender=new_object)
return new_object
class ObjectManager(ObjectDBManager, TypeclassManager):
pass