Reworked spawner with new batch_add functionality for both tags and attributes.
This commit is contained in:
parent
e34d32bd60
commit
58589126b8
3 changed files with 60 additions and 50 deletions
|
|
@ -508,47 +508,47 @@ class AttributeHandler(object):
|
||||||
# update cache
|
# update cache
|
||||||
self._setcache(keystr, category, new_attr)
|
self._setcache(keystr, category, new_attr)
|
||||||
|
|
||||||
def batch_add(self, key, value, category=None, lockstring="",
|
def batch_add(self, *args, **kwargs):
|
||||||
strattr=False, accessing_obj=None, default_access=True):
|
|
||||||
"""
|
"""
|
||||||
Batch-version of `add()`. This is more efficient than
|
Batch-version of `add()`. This is more efficient than
|
||||||
repeat-calling add when having many Attributes to add.
|
repeat-calling add when having many Attributes to add.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
key (list): A list of Attribute names to add.
|
indata (tuple): Tuples of varying length representing the
|
||||||
value (list): A list of values. It must match the `key`
|
Attribute to add to this object.
|
||||||
list. If `strattr` keyword is set, all entries *must* be
|
- `(key, value)`
|
||||||
strings.
|
- `(key, value, category)`
|
||||||
category (str, optional): The category for the Attribute.
|
- `(key, value, category, lockstring)`
|
||||||
The default `None` is the normal category used.
|
- `(key, value, category, lockstring, default_access)`
|
||||||
lockstring (str, optional): A lock string limiting access
|
|
||||||
to the attribute.
|
Kwargs:
|
||||||
strattr (bool, optional): Make this a string-only Attribute.
|
strattr (bool): If `True`, value must be a string. This
|
||||||
This is only ever useful for optimization purposes.
|
will save the value without pickling which is less
|
||||||
accessing_obj (object, optional): An entity to check for
|
flexible but faster to search (not often used except
|
||||||
the `attrcreate` access-type. If not passing, this method
|
internally).
|
||||||
will be exited.
|
|
||||||
default_access (bool, optional): What access to grant if
|
|
||||||
`accessing_obj` is given but no lock of the type
|
|
||||||
`attrcreate` is defined on the Attribute in question.
|
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
RuntimeError: If `key` and `value` lists are not of the
|
RuntimeError: If trying to pass a non-iterable as argument.
|
||||||
same lengths.
|
|
||||||
|
Notes:
|
||||||
|
The indata tuple order matters, so if you want a lockstring
|
||||||
|
but no category, set the category to `None`. This method
|
||||||
|
does not have the ability to check editing permissions like
|
||||||
|
normal .add does, and is mainly used internally. It does not
|
||||||
|
use the normal self.add but apply the Attributes directly
|
||||||
|
to the database.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if accessing_obj and not self.obj.access(accessing_obj, self._attrcreate, default=default_access):
|
|
||||||
# check create access
|
|
||||||
return
|
|
||||||
|
|
||||||
keys, values = make_iter(key), make_iter(value)
|
|
||||||
|
|
||||||
if len(keys) != len(values):
|
|
||||||
raise RuntimeError("AttributeHandler.add(): key and value lists of different length: %s vs %s" % key, value)
|
|
||||||
category = category.strip().lower() if category is not None else None
|
|
||||||
new_attrobjs = []
|
new_attrobjs = []
|
||||||
for ikey, keystr in enumerate(keys):
|
strattr = kwargs.get('strattr', False)
|
||||||
keystr = keystr.strip().lower()
|
for tup in args:
|
||||||
new_value = values[ikey]
|
if not is_iter(tup) or len(tup) < 2:
|
||||||
|
raise RuntimeError("batch_add requires iterables as arguments (got %r)." % tup)
|
||||||
|
ntup = len(tup)
|
||||||
|
keystr = str(tup[0]).strip().lower()
|
||||||
|
new_value = tup[1]
|
||||||
|
category = str(tup[2]).strip().lower() if tup > 2 else None
|
||||||
|
lockstring = tup[3] if tup > 3 else ""
|
||||||
|
|
||||||
attr_objs = self._getcache(keystr, category)
|
attr_objs = self._getcache(keystr, category)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ class TagHandler(object):
|
||||||
else:
|
else:
|
||||||
return [to_str(tag.db_key) for tag in tags]
|
return [to_str(tag.db_key) for tag in tags]
|
||||||
|
|
||||||
def batch_add(self, *tuples):
|
def batch_add(self, *args):
|
||||||
"""
|
"""
|
||||||
Batch-add tags from a list of tuples.
|
Batch-add tags from a list of tuples.
|
||||||
|
|
||||||
|
|
@ -374,7 +374,7 @@ class TagHandler(object):
|
||||||
"""
|
"""
|
||||||
keys = defaultdict(list)
|
keys = defaultdict(list)
|
||||||
data = {}
|
data = {}
|
||||||
for tup in tuples:
|
for tup in args:
|
||||||
tup = make_iter(tup)
|
tup = make_iter(tup)
|
||||||
nlen = len(tup)
|
nlen = len(tup)
|
||||||
if nlen == 1: # just a key
|
if nlen == 1: # just a key
|
||||||
|
|
@ -387,7 +387,6 @@ class TagHandler(object):
|
||||||
for category, key in keys.iteritems():
|
for category, key in keys.iteritems():
|
||||||
self.add(tag=key, category=category, data=data.get(category, None))
|
self.add(tag=key, category=category, data=data.get(category, None))
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return ",".join(self.all())
|
return ",".join(self.all())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ GOBLIN = {
|
||||||
"resists": ["cold", "poison"],
|
"resists": ["cold", "poison"],
|
||||||
"attacks": ["fists"],
|
"attacks": ["fists"],
|
||||||
"weaknesses": ["fire", "light"]
|
"weaknesses": ["fire", "light"]
|
||||||
"tags:": ["mob", "evil"]
|
"tags": ["mob", "evil", ('greenskin','mob')]
|
||||||
|
"args": [("weapon", "sword")]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -31,21 +32,28 @@ Possible keywords are:
|
||||||
permissions - string or list of permission strings
|
permissions - string or list of permission strings
|
||||||
locks - a lock-string
|
locks - a lock-string
|
||||||
aliases - string or list of strings
|
aliases - string or list of strings
|
||||||
tags - string or list of strings
|
|
||||||
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.
|
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
|
This can be used e.g. to trigger custom handlers on the object. The
|
||||||
execution environment contains 'evennia' for the library and 'obj'
|
execution namespace contains 'evennia' for the library and 'obj'
|
||||||
for accessing the just created object.
|
tags - string or list of strings or tuples `(tagstr, category)`. Plain
|
||||||
any other keywords are interpreted as Attributes and their values.
|
strings will be result in tags with no category (default tags).
|
||||||
|
args - tuple or list of tuples of Attributes to add. This form allows
|
||||||
|
more complex Attributes to be set. Tuples at least specify `(key, value)`
|
||||||
|
but can also specify up to `(key, value, category, lockstring)`. If
|
||||||
|
you want to specify a lockstring but not a category, set the category
|
||||||
|
to `None`.
|
||||||
|
ndb_<name> - value of a nattribute (ndb_ is stripped)
|
||||||
|
other - any other name is interpreted as the key of an Attribute with
|
||||||
|
its value. Such Attributes have no categories.
|
||||||
|
|
||||||
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
|
||||||
return the value to enter into the field and will be called every time
|
return the value to enter into the field and will be called every time
|
||||||
the prototype is used to spawn an object.
|
the prototype is used to spawn an object. Note, if you want to store
|
||||||
|
a callable in an Attribute, embed it in a tuple to the `args` keyword.
|
||||||
|
|
||||||
By specifying a prototype, the child will inherit all prototype slots
|
By specifying the "prototype" key, the prototype becomes a child of
|
||||||
it does not explicitly define itself, while overloading those that it
|
that prototype, inheritng all prototype slots it does not explicitly
|
||||||
does specify.
|
define itself, while overloading those that it does specify.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
GOBLIN_WIZARD = {
|
GOBLIN_WIZARD = {
|
||||||
|
|
@ -252,6 +260,8 @@ def spawn(*prototypes, **kwargs):
|
||||||
alias_string = aliasval() if callable(aliasval) else aliasval
|
alias_string = aliasval() if callable(aliasval) else aliasval
|
||||||
tagval = prot.pop("tags", "")
|
tagval = prot.pop("tags", "")
|
||||||
tags = tagval() if callable(tagval) else tagval
|
tags = tagval() if callable(tagval) else tagval
|
||||||
|
attrval = prot.pop("args", "")
|
||||||
|
attributes = attrval() if callable(tagval) else attrval
|
||||||
|
|
||||||
exval = prot.pop("exec", "")
|
exval = prot.pop("exec", "")
|
||||||
execs = make_iter(exval() if callable(exval) else exval)
|
execs = make_iter(exval() if callable(exval) else exval)
|
||||||
|
|
@ -261,9 +271,10 @@ def spawn(*prototypes, **kwargs):
|
||||||
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
|
||||||
attributes = dict((key, value() if callable(value) else value)
|
simple_attributes = [(key, value) if callable(value) else value
|
||||||
for key, value in prot.items()
|
for key, value in prot.items() if not key.startswith("ndb_")]
|
||||||
if not (key in _CREATE_OBJECT_KWARGS or key.startswith("ndb_")))
|
attributes = attributes + simple_attributes
|
||||||
|
attributes = [tup for tup in attributes if not tup[0] in _CREATE_OBJECT_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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue