Add 'exec' argument to spawner prototype for running arbitrary code as part of object creation. Make all prototype keys also settable with a callable.

This commit is contained in:
Griatch 2016-08-21 23:03:42 +02:00
parent 49087b50d1
commit 89568b5277

View file

@ -33,6 +33,10 @@ Possible keywords are:
aliases - string or list of strings aliases - string or list of strings
tags - string or list of strings tags - string or list of strings
ndb_<name> - value of a nattribute (ndb_ is stripped) ndb_<name> - value of a nattribute (ndb_ is stripped)
exec - this is a string of python code to execute or a list of such codes.
This can be used e.g. to trigger custom handlers on the object. The
execution environment contains 'evennia' for the library and 'obj'
for accessing the just created object.
any other keywords are interpreted as Attributes and their values. any other keywords are interpreted as Attributes and their values.
Each value can also be a callable that takes no arguments. It should Each value can also be a callable that takes no arguments. It should
@ -84,6 +88,7 @@ import copy
from django.conf import settings from django.conf import settings
from random import randint from random import randint
import evennia
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.utils.utils import make_iter, all_from_module, dbid_to_obj from evennia.utils.utils import make_iter, all_from_module, dbid_to_obj
@ -165,6 +170,10 @@ def _batch_create_object(*objparams):
"tags":objparam[6]} "tags":objparam[6]}
# this triggers all hooks # this triggers all hooks
obj.save() obj.save()
# run eventual extra code
for code in objparam[7]:
if code:
exec(code, {}, {"evennia": evennia, "obj": obj})
objs.append(obj) objs.append(obj)
return objs return objs
@ -211,22 +220,38 @@ def spawn(*prototypes, **kwargs):
if not prot: if not prot:
continue continue
# extract the keyword args we need to create the object itself # extract the keyword args we need to create the object itself. If we get a callable,
# call that to get the value (don't catch errors)
create_kwargs = {} create_kwargs = {}
create_kwargs["db_key"] = prot.pop("key", "Spawned Object %06i" % randint(1,100000)) keyval = prot.pop("key", "Spawned Object %06i" % randint(1,100000))
create_kwargs["db_location"] = _handle_dbref(prot.pop("location", None)) create_kwargs["db_key"] = keyval() if callable(keyval) else keyval
create_kwargs["db_home"] = _handle_dbref(prot.pop("home", settings.DEFAULT_HOME))
create_kwargs["db_destination"] = _handle_dbref(prot.pop("destination", None)) locval = prot.pop("location", None)
create_kwargs["db_typeclass_path"] = prot.pop("typeclass", settings.BASE_OBJECT_TYPECLASS) create_kwargs["db_location"] = locval() if callable(locval) else _handle_dbref(locval)
homval = prot.pop("home", settings.DEFAULT_HOME)
create_kwargs["db_home"] = homval() if callable(homval) else _handle_dbref(homval)
destval = prot.pop("destination", None)
create_kwargs["db_destination"] = destval() if callable(destval) else _handle_dbref(destval)
typval = prot.pop("typeclass", settings.BASE_OBJECT_TYPECLASS)
create_kwargs["db_typeclass_path"] = typval() if callable(typval) else typval
# extract calls to handlers # extract calls to handlers
permission_string = prot.pop("permissions", "") permval = prot.pop("permissions", "")
lock_string = prot.pop("locks", "") permission_string = permval() if callable(permval) else permval
alias_string = prot.pop("aliases", "") lockval = prot.pop("locks", "")
tags = prot.pop("tags", "") lock_string = lockval() if callable(lockval) else lockval
aliasval = prot.pop("aliases", "")
alias_string = aliasval() if callable(aliasval) else aliasval
tagval = prot.pop("tags", "")
tags = tagval() if callable(tagval) else tagval
exval = prot.pop("exec", "")
execs = make_iter(exval() if callable(exval) else exval)
# extract ndb assignments # extract ndb assignments
nattributes = dict((key.split("_", 1)[1], value if callable(value) else value) nattributes = dict((key.split("_", 1)[1], value() if callable(value) else value)
for key, value in prot.items() if key.startswith("ndb_")) for key, value in prot.items() if key.startswith("ndb_"))
# the rest are attributes # the rest are attributes
@ -236,7 +261,7 @@ def spawn(*prototypes, **kwargs):
# pack for call into _batch_create_object # pack for call into _batch_create_object
objsparams.append( (create_kwargs, permission_string, lock_string, objsparams.append( (create_kwargs, permission_string, lock_string,
alias_string, nattributes, attributes, tags) ) alias_string, nattributes, attributes, tags, execs) )
return _batch_create_object(*objsparams) return _batch_create_object(*objsparams)