diff --git a/game/gamesrc/conf/examples/oobfuncs.py b/game/gamesrc/conf/examples/oobfuncs.py index ab3ca66e9b..24c7422cb9 100644 --- a/game/gamesrc/conf/examples/oobfuncs.py +++ b/game/gamesrc/conf/examples/oobfuncs.py @@ -7,10 +7,15 @@ is selected by settings.OOB_FUNC_MODULE. All functions defined global in this module will be available - for the oob system to call. They will be called with a session/character + for the oob system to call. They will be called in the following + way: + + a session/character as first argument (depending on if the session is logged in or not), following by any number of extra arguments. The return value will be packed and returned to the oob protocol and can be on any form. + + """ def testoob(character, *args, **kwargs): @@ -19,8 +24,6 @@ def testoob(character, *args, **kwargs): return "testoob did stuff to the input string '%s'!" % val - - # MSDP_MAP is a standard suggestions for making it easy to create generic guis. # this maps MSDP command names to Evennia commands found in OOB_FUNC_MODULE. It # is up to these commands to return data on proper form. diff --git a/src/commands/default/building.py b/src/commands/default/building.py index c2bc798412..8f5b27ef4d 100644 --- a/src/commands/default/building.py +++ b/src/commands/default/building.py @@ -1585,7 +1585,7 @@ class CmdExamine(ObjManipCommand): else: db_attr = [(attr.key, attr.value) for attr in ObjAttribute.objects.filter(db_obj=obj)] try: - ndb_attr = [(aname, avalue) for aname, avalue in obj.ndb.__dict__.items()] + ndb_attr = [(aname, avalue) for aname, avalue in obj.ndb.__dict__.items() if not aname.startswith("_")] except Exception: ndb_attr = None string = "" diff --git a/src/server/caches.py b/src/server/caches.py index 4e84afab31..eb269c5012 100644 --- a/src/server/caches.py +++ b/src/server/caches.py @@ -80,6 +80,7 @@ def register_oob_update_hook(obj,name, entity="field"): if entity == "field": global _OOB_FIELD_UPDATE_HOOKS _OOB_FIELD_UPDATE_HOOKS[hid][name] = True + return elif entity == "property": global _OOB_PROP_UPDATE_HOOKS _OOB_PROP_UPDATE_HOOKS[hid][name] = True @@ -94,7 +95,6 @@ def register_oob_update_hook(obj,name, entity="field"): _OOB_CUSTOM_UPDATE_HOOKS[hid][name] = True else: return None - return hid def unregister_oob_update_hook(obj, name, entity="property"): """ @@ -116,7 +116,6 @@ def unregister_oob_update_hook(obj, name, entity="property"): del _OOB_CUSTOM_UPDATE_HOOKS[hid][name] else: return None - return hid # on-object database field cache def get_field_cache(obj, name): diff --git a/src/server/oobhandler.py b/src/server/oobhandler.py index 4a2ecca250..f921a792ee 100644 --- a/src/server/oobhandler.py +++ b/src/server/oobhandler.py @@ -3,7 +3,7 @@ OOB - Out-of-band central handler This module presents a central API for requesting data from objects in Evennia via OOB negotiation. It is meant specifically to be imported -and used by the module defined in settings.OOB_MODULE. +and used by the module defined in settings.OOB_FUNC_MODULE. Import src.server.oobhandler and use the methods in OOBHANDLER. @@ -26,6 +26,18 @@ track_active - this is an active reporting mechanism making use of a Script. Thi Trivial operations such as get/setting individual properties one time is best done directly from the OOB_MODULE functions. +Examples of call from OOB_FUNC_MODULE: + +from src.server.oobhandler import OOBHANDLER + +def track_desc(session, *args, **kwargs): + "Sets up a passive watch for the desc attribute on session object" + if session.player and session.player.character: + char = session.player.character + OOBHANDLER.track_passive(session, char, "desc", entity="db") + # to start off we return the value once + return char.db.desc + """ from collections import defaultdict @@ -104,7 +116,7 @@ class OOBhandler(object): # set reference on caches module caches._OOB_HANDLER = self - def track_passive(self, tracker, tracked, name, function, entity="db", *args, **kwargs): + def track_passive(self, tracker, tracked, key, callback=None, mode="db", *args, **kwargs): """ Passively track changes to an object property, attribute or non-db-attribute. Uses cache hooks to @@ -112,12 +124,12 @@ class OOBhandler(object): tracker - object who is tracking tracked - object being tracked - name - field/property/attribute/ndb nam to watch - function - function object to call when entity update. When entitye + key - field/property/attribute/ndb nam to watch + function - function object to call when entity update. When entitye is updated, this function will be called with called - with function(obj, name, new_value, *args, **kwargs) + with function(obj, key, new_value, *args, **kwargs) *args - additional, optional arguments to send to function - entity (keyword) - the type of entity to track. One of + mode (keyword) - the type of entity to track. One of "property", "db", "ndb" or "custom" ("property" includes both changes to database fields and cached on-model properties) **kwargs - additional, optionak keywords to send to function @@ -133,28 +145,32 @@ class OOBhandler(object): try: tracked = tracked.dbobj except AttributeError: pass + def default_callback(tracker, tracked, key, new_val, *args, **kwargs): + "Callback used if no function is supplied" + pass + thid = hashid(tracked) if not thid: return - oob_call = (function, tracked, name, args, kwargs) + oob_call = (function, tracked, key, args, kwargs) if thid not in self.track_passive_subs: - if entity in ("db", "ndb", "custom"): - caches.register_oob_update_hook(tracked, name, entity=entity) - elif entity == "property": + if mode in ("db", "ndb", "custom"): + caches.register_oob_update_hook(tracked, key, mode=mode) + elif mode == "property": # track property/field. We must first determine which cache to use. - if hasattr(tracked, 'db_%s' % name.lstrip("db_")): - hid = caches.register_oob_update_hook(tracked, name, entity="field") + if hasattr(tracked, 'db_%s' % key.lstrip("db_")): + hid = caches.register_oob_update_hook(tracked, key, mode="field") else: - hid = caches.register_oob_update_hook(tracked, name, entity="property") - if not self.track_pass_subs[hid][name]: - self.track_pass_subs[hid][name] = {tracker:oob_call} + hid = caches.register_oob_update_hook(tracked, key, mode="property") + if not self.track_pass_subs[hid][key]: + self.track_pass_subs[hid][key] = {tracker:oob_call} else: - self.track_passive_subs[hid][name][tracker] = oob_call + self.track_passive_subs[hid][key][tracker] = oob_call - def untrack_passive(self, tracker, tracked, name, entity="db"): + def untrack_passive(self, tracker, tracked, key, mode="db"): """ Remove passive tracking from an object's entity. - entity - one of "property", "db", "ndb" or "custom" + mode - one of "property", "db", "ndb" or "custom" """ try: tracked = tracked.dbobj except AttributeError: pass @@ -162,27 +178,29 @@ class OOBhandler(object): thid = hashid(tracked) if not thid: return - if len(self.track_passive_subs[thid][name]) == 1: - if entity in ("db", "ndb", "custom"): - caches.unregister_oob_update_hook(tracked, name, entity=entity) - elif entity == "property": - if hasattr(tracked, 'db_%s' % name.lstrip("db_")): - caches.unregister_oob_update_hook(tracked, name, entity="field") + if len(self.track_passive_subs[thid][key]) == 1: + if mode in ("db", "ndb", "custom"): + caches.unregister_oob_update_hook(tracked, key, mode=mode) + elif mode == "property": + if hasattr(, 'db_%s' % key.lstrip("db_")): + caches.unregister_oob_update_hook(tracked, key, mode="field") else: - caches.unregister_oob_update_hook(tracked, name, entity="property") + caches.unregister_oob_update_hook(tracked, key, mode="property") - try: del self.track_passive_subs[thid][name][tracker] + try: del self.track_passive_subs[thid][key][tracker] except (KeyError, TypeError): pass - def update(self, hid, name, new_val): + def update(self, hid, key, new_val): """ - This is called by the caches when the tracked object when its property/field/etc is updated, - to inform the oob handler and all subscribing to this particular entity has been updated with new_val. + This is called by the caches when the object when its + property/field/etc is updated, to inform the oob handler and + all subscribing to this particular entity has been updated + with new_val. """ # tell all tracking objects of the update - for tracker, oob in self.track_passive_subs[hid][name].items(): + for tracker, oob in self.track_passive_subs[hid][key].items(): try: - # function(tracker, tracked, key, new_value, *args, **kwargs) + # function(tracker, , key, new_value, *args, **kwargs) oob[0](tracker, oob[1], oob[2], new_val, *oob[3], **oob[4]) except Exception: logger.log_trace()