Make monitorhandler support Attribute categories. Resolve 1807.

This commit is contained in:
Griatch 2022-01-08 21:58:03 +01:00
parent a8b52b76b3
commit cc22a776ee
2 changed files with 26 additions and 4 deletions

View file

@ -130,6 +130,10 @@ Up requirements to Django 3.2+, Twisted 21+
to `.remove(key, category=None, return_exception=False, ...)` for consistency.
- New `command cooldown` contrib for making it easier to manage commands using
dynamic cooldowns between uses (owllex)
- Restructured `contrib/` folder, placing all contribs as separate packages under
subfolders. All imports will need to be updated.
- Made `MonitorHandler.add/remove` support `category` for monitoring Attributes
with a category (before only key was used, ignoring category entirely).
### Evennia 0.9.5 (2019-2020)

View file

@ -93,11 +93,25 @@ class MonitorHandler(object):
# make sure to clean data from database
ServerConfig.objects.conf(key=self.savekey, delete=True)
def _attr_category_fieldname(self, fieldname, category):
"""
Modify the saved fieldname to make sure to differentiate between Attributes
with different categories.
"""
return f"{fieldname}[{category}]" if category else fieldname
def at_update(self, obj, fieldname):
"""
Called by the field/attribute as it saves.
"""
# if this an Attribute with a category we should differentiate
fieldname = self._attr_category_fieldname(
fieldname, obj.db_category
if fieldname == "db_value" and hasattr(obj, "db_category") else None
)
to_delete = []
if obj in self.monitors and fieldname in self.monitors[obj]:
for idstring, (callback, persistent, kwargs) in self.monitors[obj][fieldname].items():
@ -110,7 +124,8 @@ class MonitorHandler(object):
for (obj, fieldname, idstring) in to_delete:
del self.monitors[obj][fieldname][idstring]
def add(self, obj, fieldname, callback, idstring="", persistent=False, **kwargs):
def add(self, obj, fieldname, callback, idstring="", persistent=False,
category=None, **kwargs):
"""
Add monitoring to a given field or Attribute. A field must
be specified with the full db_* name or it will be assumed
@ -126,6 +141,9 @@ class MonitorHandler(object):
of the same field and object.
persistent (bool, optional): If False, the monitor will survive
a server reload but not a cold restart. This is default.
category (str, optional): This is only used if `fieldname` refers to
an Attribute (i.e. it does not start with `db_`). You must specify this
if you want to target an Attribute with a category.
Keyword Args:
session (Session): If this keyword is given, the monitorhandler will
@ -140,7 +158,7 @@ class MonitorHandler(object):
obj = obj.attributes.get(fieldname, return_obj=True)
if not obj:
return
fieldname = "db_value"
fieldname = self._attr_category_fieldname("db_value", category)
# we try to serialize this data to test it's valid. Otherwise we won't accept it.
try:
@ -160,7 +178,7 @@ class MonitorHandler(object):
else:
self.monitors[obj][fieldname][idstring] = (callback, persistent, kwargs)
def remove(self, obj, fieldname, idstring=""):
def remove(self, obj, fieldname, idstring="", category=None):
"""
Remove a monitor.
"""
@ -168,7 +186,7 @@ class MonitorHandler(object):
obj = obj.attributes.get(fieldname, return_obj=True)
if not obj:
return
fieldname = "db_value"
fieldname = self._attr_category_fieldname("db_value", category)
idstring_dict = self.monitors[obj][fieldname]
if idstring in idstring_dict: