diff --git a/src/commands/default/tests.py b/src/commands/default/tests.py
index 615c577d65..7e4c108b20 100644
--- a/src/commands/default/tests.py
+++ b/src/commands/default/tests.py
@@ -72,7 +72,7 @@ class CommandTest(TestCase):
"sets up testing environment"
self.player = create.create_player("TestPlayer%i" % self.CID, "test@test.com", "testpassword", typeclass=TestPlayerClass)
self.player2 = create.create_player("TestPlayer%ib" % self.CID, "test@test.com", "testpassword", typeclass=TestPlayerClass)
- self.room1 = create.create_object("src.objects.objects.Room", key="Room%i"%self.CID)
+ self.room1 = create.create_object("src.objects.objects.Room", key="Room%i"%self.CID, testmode=True)
self.room1.db.desc = "room_desc"
self.room2 = create.create_object("src.objects.objects.Room", key="Room%ib" % self.CID)
self.obj1 = create.create_object(TestObjectClass, key="Obj%i" % self.CID, location=self.room1, home=self.room1)
diff --git a/src/objects/admin.py b/src/objects/admin.py
index ffb62af803..4cf2a661a3 100644
--- a/src/objects/admin.py
+++ b/src/objects/admin.py
@@ -6,10 +6,8 @@
from django import forms
from django.conf import settings
from django.contrib import admin
-from src.typeclasses.models import Attribute
+from src.typeclasses.models import Attribute, Tag
from src.objects.models import ObjectDB
-from src.typeclasses.models import Tag, LiteAttribute
-
class AttributeInline(admin.TabularInline):
# This class is currently not used, because PickleField objects are not editable.
@@ -23,11 +21,6 @@ class TagInline(admin.TabularInline):
raw_id_fields = ('tag',)
extra = 0
-class LiteAttributeInline(admin.TabularInline):
- model = LiteAttribute
- fields = ('db_key', 'db_category', 'db_data')
- extra = 0
-
class TagAdmin(admin.ModelAdmin):
fields = ('db_key', 'db_category', 'db_data')
@@ -41,11 +34,11 @@ class ObjectCreateForm(forms.ModelForm):
db_typeclass_path = forms.CharField(label="Typeclass",initial="Change to (for example) %s or %s." % (settings.BASE_OBJECT_TYPECLASS, settings.BASE_CHARACTER_TYPECLASS),
widget=forms.TextInput(attrs={'size':'78'}),
help_text="This defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. If you are creating a Character you should use the typeclass defined by settings.BASE_CHARACTER_TYPECLASS or one derived from that.")
- db_permissions = forms.CharField(label="Permissions",
- initial=settings.PERMISSION_PLAYER_DEFAULT,
- required=False,
- widget=forms.TextInput(attrs={'size':'78'}),
- help_text="a comma-separated list of text strings checked by certain locks. They are mainly of use for Character objects. Character permissions overload permissions defined on a controlling Player. Most objects normally don't have any permissions defined.")
+ #db_permissions = forms.CharField(label="Permissions",
+ # initial=settings.PERMISSION_PLAYER_DEFAULT,
+ # required=False,
+ # widget=forms.TextInput(attrs={'size':'78'}),
+ # help_text="a comma-separated list of text strings checked by certain locks. They are mainly of use for Character objects. Character permissions overload permissions defined on a controlling Player. Most objects normally don't have any permissions defined.")
db_cmdset_storage = forms.CharField(label="CmdSet",
initial=settings.CMDSET_CHARACTER,
required=False,
@@ -75,17 +68,24 @@ class ObjectDBAdmin(admin.ModelAdmin):
save_as = True
save_on_top = True
list_select_related = True
- list_filter = ('db_permissions', 'db_typeclass_path')
+ list_filter = ('db_typeclass_path',)
+ #list_filter = ('db_permissions', 'db_typeclass_path')
# editing fields setup
form = ObjectEditForm
fieldsets = (
(None, {
- 'fields': (('db_key','db_typeclass_path'), ('db_permissions', 'db_lock_storage'),
+ 'fields': (('db_key','db_typeclass_path'), ('db_lock_storage', ),
('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
)}),
)
+ #fieldsets = (
+ # (None, {
+ # 'fields': (('db_key','db_typeclass_path'), ('db_permissions', 'db_lock_storage'),
+ # ('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
+ # )}),
+ # )
#deactivated temporarily, they cause empty objects to be created in admin
inlines = [TagInline]
@@ -96,10 +96,16 @@ class ObjectDBAdmin(admin.ModelAdmin):
add_form = ObjectCreateForm
add_fieldsets = (
(None, {
- 'fields': (('db_key','db_typeclass_path'), 'db_permissions',
+ 'fields': (('db_key','db_typeclass_path'),
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
)}),
)
+ #add_fieldsets = (
+ # (None, {
+ # 'fields': (('db_key','db_typeclass_path'), 'db_permissions',
+ # ('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
+ # )}),
+ # )
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
@@ -130,4 +136,4 @@ class ObjectDBAdmin(admin.ModelAdmin):
admin.site.register(ObjectDB, ObjectDBAdmin)
-admin.site.register(Tag, TagAdmin)
\ No newline at end of file
+admin.site.register(Tag, TagAdmin)
diff --git a/src/objects/models.py b/src/objects/models.py
index 14960d22a1..12e054c57f 100644
--- a/src/objects/models.py
+++ b/src/objects/models.py
@@ -19,7 +19,6 @@ from django.db import models
from django.conf import settings
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
-from src.server.caches import get_field_cache, set_field_cache, del_field_cache
from src.server.caches import get_prop_cache, set_prop_cache
from src.typeclasses.typeclass import TypeClass
@@ -165,7 +164,8 @@ class ObjectDB(TypedObject):
We have to be careful here since Player is also
a TypedObject, so as to not create a loop.
"""
- player = get_field_cache(self, "player")
+ player = _GA(self, "db_player")
+ #player = get_field_cache(self, "player")
if player:
try:
return player.typeclass
@@ -178,7 +178,9 @@ class ObjectDB(TypedObject):
"Setter. Allows for self.player = value"
if inherits_from(player, TypeClass):
player = player.dbobj
- set_field_cache(self, "player", player)
+ _SA(self, "db_player", player)
+ _GA(self, "save")()
+ #set_field_cache(self, "player", player)
# we must set this here or superusers won't be able to
# bypass lockchecks unless they start the game connected
# to the character in question.
@@ -187,30 +189,37 @@ class ObjectDB(TypedObject):
#@player.deleter
def __player_del(self):
"Deleter. Allows for del self.player"
- del_field_cache(self, "player")
+ _SA(self, "db_player", None)
+ _GA(self, "save")()
+ #del_field_cache(self, "player")
player = property(__player_get, __player_set, __player_del)
- # sessid property (wraps db_sessid)
+ #sessid property (wraps db_sessid)
#@property
- #def __sessid_get(self):
- # """
- # Getter. Allows for value = self.sessid. Since sessid
- # is directly related to self.player, we cannot have
- # a sessid without a player being connected (but the
- # opposite could be true).
- # """
- # if not get_field_cache(self, "sessid"):
- # del_field_cache(self, "sessid")
- # return get_field_cache(self, "sessid")
- ##@sessid.setter
- #def __sessid_set(self, sessid):
- # "Setter. Allows for self.player = value"
- # set_field_cache(self, "sessid", sessid)
- ##@sessid.deleter
- #def __sessid_del(self):
- # "Deleter. Allows for del self.player"
- # del_field_cache(self, "sessid")
- #sessid = property(__sessid_get, __sessid_set, __sessid_del)
+ def __sessid_get(self):
+ """
+ Getter. Allows for value = self.sessid. Since sessid
+ is directly related to self.player, we cannot have
+ a sessid without a player being connected (but the
+ opposite could be true).
+ """
+ return _GA(self, "db_sessid")
+ #if not get_field_cache(self, "sessid"):
+ # del_field_cache(self, "sessid")
+ #return get_field_cache(self, "sessid")
+ #@sessid.setter
+ def __sessid_set(self, sessid):
+ "Setter. Allows for self.player = value"
+ _SA(self, "db_sessid", sessid)
+ _GA(self, "save")()
+ #set_field_cache(self, "sessid", sessid)
+ #@sessid.deleter
+ def __sessid_del(self):
+ "Deleter. Allows for del self.player"
+ _SA(self, "db_sessid", None)
+ _GA(self, "save")()
+ #del_field_cache(self, "sessid")
+ sessid = property(__sessid_get, __sessid_set, __sessid_del)
def _at_db_location_save(self, new_value, old_value=None):
"This is called automatically just before a new location is saved."
@@ -311,79 +320,79 @@ class ObjectDB(TypedObject):
# home property (wraps db_home)
#@property
- def __home_get(self):
- "Getter. Allows for value = self.home"
- home = get_field_cache(self, "home")
- if home:
- return _GA(home, "typeclass")
- return None
- #@home.setter
- def __home_set(self, home):
- "Setter. Allows for self.home = value"
- try:
- if home == None or type(home) == ObjectDB:
- hom = home
- elif ObjectDB.objects.dbref(home):
- hom = ObjectDB.objects.dbref_search(home)
- if hom and hasattr(hom,'dbobj'):
- hom = _GA(hom, "dbobj")
- else:
- hom = _GA(home, "dbobj")
- else:
- hom = _GA(home, "dbobj")
- set_field_cache(self, "home", hom)
- except Exception:
- string = "Cannot set home: "
- string += "%s is not a valid home."
- _GA(self, "msg")(_(string) % home)
- logger.log_trace(string)
- #raise
- #@home.deleter
- def __home_del(self):
- "Deleter. Allows for del self.home."
- _SA(self, "db_home", None)
- _GA(self, "save")()
- del_field_cache(self, "home")
- home = property(__home_get, __home_set, __home_del)
+ #def __home_get(self):
+ # "Getter. Allows for value = self.home"
+ # home = get_field_cache(self, "home")
+ # if home:
+ # return _GA(home, "typeclass")
+ # return None
+ ##@home.setter
+ #def __home_set(self, home):
+ # "Setter. Allows for self.home = value"
+ # try:
+ # if home == None or type(home) == ObjectDB:
+ # hom = home
+ # elif ObjectDB.objects.dbref(home):
+ # hom = ObjectDB.objects.dbref_search(home)
+ # if hom and hasattr(hom,'dbobj'):
+ # hom = _GA(hom, "dbobj")
+ # else:
+ # hom = _GA(home, "dbobj")
+ # else:
+ # hom = _GA(home, "dbobj")
+ # set_field_cache(self, "home", hom)
+ # except Exception:
+ # string = "Cannot set home: "
+ # string += "%s is not a valid home."
+ # _GA(self, "msg")(_(string) % home)
+ # logger.log_trace(string)
+ # #raise
+ ##@home.deleter
+ #def __home_del(self):
+ # "Deleter. Allows for del self.home."
+ # _SA(self, "db_home", None)
+ # _GA(self, "save")()
+ # del_field_cache(self, "home")
+ #home = property(__home_get, __home_set, __home_del)
# destination property (wraps db_destination)
#@property
- def __destination_get(self):
- "Getter. Allows for value = self.destination."
- dest = get_field_cache(self, "destination")
- if dest:
- return _GA(dest, "typeclass")
- return None
- #@destination.setter
- def __destination_set(self, destination):
- "Setter. Allows for self.destination = destination"
- try:
- if destination == None or type(destination) == ObjectDB:
- # destination is None or a valid object
- dest = destination
- elif ObjectDB.objects.dbref(destination):
- # destination is a dbref; search
- dest = ObjectDB.objects.dbref_search(destination)
- if dest and _GA(self, "_hasattr")(dest,'dbobj'):
- dest = _GA(dest, "dbobj")
- else:
- dest = _GA(destination, "dbobj")
- else:
- dest = destination.dbobj
- set_field_cache(self, "destination", dest)
- except Exception:
- string = "Cannot set destination: "
- string += "%s is not a valid destination." % destination
- _GA(self, "msg")(string)
- logger.log_trace(string)
- raise
- #@destination.deleter
- def __destination_del(self):
- "Deleter. Allows for del self.destination"
- _SA(self, "db_destination", None)
- _GA(self, "save")()
- del_field_cache(self, "destination")
- destination = property(__destination_get, __destination_set, __destination_del)
+ #def __destination_get(self):
+ # "Getter. Allows for value = self.destination."
+ # dest = get_field_cache(self, "destination")
+ # if dest:
+ # return _GA(dest, "typeclass")
+ # return None
+ ##@destination.setter
+ #def __destination_set(self, destination):
+ # "Setter. Allows for self.destination = destination"
+ # try:
+ # if destination == None or type(destination) == ObjectDB:
+ # # destination is None or a valid object
+ # dest = destination
+ # elif ObjectDB.objects.dbref(destination):
+ # # destination is a dbref; search
+ # dest = ObjectDB.objects.dbref_search(destination)
+ # if dest and _GA(self, "_hasattr")(dest,'dbobj'):
+ # dest = _GA(dest, "dbobj")
+ # else:
+ # dest = _GA(destination, "dbobj")
+ # else:
+ # dest = destination.dbobj
+ # set_field_cache(self, "destination", dest)
+ # except Exception:
+ # string = "Cannot set destination: "
+ # string += "%s is not a valid destination." % destination
+ # _GA(self, "msg")(string)
+ # logger.log_trace(string)
+ # raise
+ ##@destination.deleter
+ #def __destination_del(self):
+ # "Deleter. Allows for del self.destination"
+ # _SA(self, "db_destination", None)
+ # _GA(self, "save")()
+ # del_field_cache(self, "destination")
+ #destination = property(__destination_get, __destination_set, __destination_del)
# cmdset_storage property.
# This seems very sensitive to caching, so leaving it be for now. /Griatch
diff --git a/src/players/admin.py b/src/players/admin.py
index 52db397665..3e5de18090 100644
--- a/src/players/admin.py
+++ b/src/players/admin.py
@@ -94,11 +94,11 @@ class PlayerForm(forms.ModelForm):
initial=settings.BASE_PLAYER_TYPECLASS,
widget=forms.TextInput(attrs={'size':'78'}),
help_text="Required. Defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. Defaults to settings.BASE_PLAYER_TYPECLASS.")
- db_permissions = forms.CharField(label="Permissions",
- initial=settings.PERMISSION_PLAYER_DEFAULT,
- required=False,
- widget=forms.TextInput(attrs={'size':'78'}),
- help_text="In-game permissions. A comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. A Player permission can be overloaded by the permissions of a controlled Character. Normal players use 'Players' by default.")
+ #db_permissions = forms.CharField(label="Permissions",
+ # initial=settings.PERMISSION_PLAYER_DEFAULT,
+ # required=False,
+ # widget=forms.TextInput(attrs={'size':'78'}),
+ # help_text="In-game permissions. A comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. A Player permission can be overloaded by the permissions of a controlled Character. Normal players use 'Players' by default.")
db_lock_storage = forms.CharField(label="Locks",
widget=forms.Textarea(attrs={'cols':'100', 'rows':'2'}),
required=False,
@@ -116,7 +116,8 @@ class PlayerInline(admin.StackedInline):
form = PlayerForm
fieldsets = (
("In-game Permissions and Locks",
- {'fields': ('db_permissions', 'db_lock_storage'),
+ {'fields': ('db_lock_storage',),
+ #{'fields': ('db_permissions', 'db_lock_storage'),
'description':"These are permissions/locks for in-game use. They are unrelated to website access rights."}),
("In-game Player data",
{'fields':('db_typeclass_path', 'db_cmdset_storage'),
@@ -140,8 +141,10 @@ class PlayerDBAdmin(BaseUserAdmin):
'description':'Relevant only to the website.'}),
('Website Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions','groups'),
'description': "These are permissions/permission groups for accessing the admin site. They are unrelated to in-game access rights."}),
- ('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_permissions', 'db_lock_storage'),
+ ('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_lock_storage'),
'description': 'These are attributes that are more relevant to gameplay.'}))
+ #('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_permissions', 'db_lock_storage'),
+ # 'description': 'These are attributes that are more relevant to gameplay.'}))
add_fieldsets = (
diff --git a/src/players/models.py b/src/players/models.py
index 3647b33b55..0a56082d68 100644
--- a/src/players/models.py
+++ b/src/players/models.py
@@ -21,8 +21,6 @@ from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils.encoding import smart_str
-from src.server.caches import get_field_cache, set_field_cache
-
from src.players import manager
from src.scripts.models import ScriptDB
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
@@ -165,19 +163,19 @@ class PlayerDB(TypedObject, AbstractUser):
_GA(self, "save")()
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
- #@property
- def is_connected_get(self):
- "Getter. Allows for value = self.is_connected"
- return get_field_cache(self, "is_connected")
- #@is_connected.setter
- def is_connected_set(self, value):
- "Setter. Allows for self.is_connected = value"
- set_field_cache(self, "is_connected", value)
- #@is_connected.deleter
- def is_connected_del(self):
- "Deleter. Allows for del is_connected"
- set_field_cache(self, "is_connected", False)
- is_connected = property(is_connected_get, is_connected_set, is_connected_del)
+ ##@property
+ #def is_connected_get(self):
+ # "Getter. Allows for value = self.is_connected"
+ # return get_field_cache(self, "is_connected")
+ ##@is_connected.setter
+ #def is_connected_set(self, value):
+ # "Setter. Allows for self.is_connected = value"
+ # set_field_cache(self, "is_connected", value)
+ ##@is_connected.deleter
+ #def is_connected_del(self):
+ # "Deleter. Allows for del is_connected"
+ # set_field_cache(self, "is_connected", False)
+ #is_connected = property(is_connected_get, is_connected_set, is_connected_del)
class Meta:
"Define Django meta options"
diff --git a/src/server/caches.py b/src/server/caches.py
index 884697cf4b..b74db1068d 100644
--- a/src/server/caches.py
+++ b/src/server/caches.py
@@ -3,6 +3,7 @@ Central caching module.
"""
+from sys import getsizeof
import os, threading
from collections import defaultdict
@@ -21,16 +22,9 @@ _IS_MAIN_THREAD = threading.currentThread().getName() == "MainThread"
# Set up the cache stores
#
-_FIELD_CACHE = {}
_ATTR_CACHE = {}
_PROP_CACHE = defaultdict(dict)
-# OOB trackers
-_TRACKED_FIELDS = {}
-_TRACKED_ATTRS = {}
-_TRACKED_CACHE = {}
-
-
#------------------------------------------------------------
# Cache key hash generation
#------------------------------------------------------------
@@ -110,7 +104,7 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
if callable(handler):
#hid = hashid(instance, "-%s" % fieldname)
try:
- old_value = _GA(instance, _GA(field, "get_cache_name")())#_FIELD_CACHE.get(hid) if hid else None
+ old_value = _GA(instance, _GA(field, "get_cache_name")())
except AttributeError:
old_value=None
# the handler may modify the stored value in various ways
@@ -127,21 +121,6 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
def get_cache_sizes():
return (0, 0), (0, 0), (0, 0)
-def get_field_cache(obj, name):
- return _GA(obj, "db_%s" % name)
-def set_field_cache(obj, name, val):
- _SA(obj, "db_%s" % name, val)
- _GA(obj, "save")()
- #hid = hashid(obj)
- #if _OOB_FIELD_UPDATE_HOOKS[hid].get(name):
- # _OOB_HANDLER.update(hid, name, val)
-def del_field_cache(obj, name):
- _SA(obj, "db_%s" % name, None)
- _GA(obj, "save")()
- #hid = hashid(obj)
- #if _OOB_FIELD_UPDATE_HOOKS[hid].get(name):
- # _OOB_HANDLER.update(hid, name, None)
-
#------------------------------------------------------------
# Attr cache - caching the attribute objects related to a given object to
@@ -151,11 +130,10 @@ def del_field_cache(obj, name):
# connected to m2m_changed signal in respective model class
def post_attr_update(sender, **kwargs):
- "Called when the many2many relation changes some way"
+ "Called when the many2many relation changes (NOT when updating the value of an Attribute!)"
obj = kwargs['instance']
model = kwargs['model']
action = kwargs['action']
- #print "update_attr_cache:", obj, model, action
if kwargs['reverse']:
# the reverse relation changed (the Attribute itself was acted on)
pass
@@ -183,7 +161,7 @@ def post_attr_update(sender, **kwargs):
def get_attr_cache(obj, attrname):
"Called by getting attribute"
hid = hashid(obj, "-%s" % attrname)
- return hid and _ATTR_CACHE.get(hid, None) or None
+ return _ATTR_CACHE.get(hid, None)
def set_attr_cache(obj, attrname, attrobj):
"Set the attr cache manually; this can be used to update"
@@ -217,28 +195,20 @@ def clear_obj_attr_cache(obj):
def get_prop_cache(obj, propname):
"retrieve data from cache"
hid = hashid(obj, "-%s" % propname)
- if hid:
- #print "get_prop_cache", hid, propname, _PROP_CACHE.get(hid, None)
- return _PROP_CACHE[hid].get(propname, None)
+ return _PROP_CACHE[hid].get(propname, None) if hid else None
def set_prop_cache(obj, propname, propvalue):
"Set property cache"
hid = hashid(obj, "-%s" % propname)
- if obj and hasattr(obj, "oobhandler"):
- obj.oobhandler.update(propname, _GA(obj, propname), propvalue, type="property", action="set")
if hid:
- #print "set_prop_cache", propname, propvalue
_PROP_CACHE[hid][propname] = propvalue
- #_PROP_CACHE.set(hid, propvalue)
def del_prop_cache(obj, propname):
"Delete element from property cache"
hid = hashid(obj, "-%s" % propname)
- if obj and hasattr(obj, "oobhandler"):
- obj.oobhandler.update(propname, _GA(obj, propname), None, type="property", action="delete")
- if hid and propname in _PROP_CACHE[hid]:
- del _PROP_CACHE[hid][propname]
- #_PROP_CACHE.delete(hid)
+ if hid:
+ if propname in _PROP_CACHE[hid]:
+ del _PROP_CACHE[hid][propname]
def flush_prop_cache():
"Clear property cache"
@@ -246,84 +216,17 @@ def flush_prop_cache():
_PROP_CACHE = defaultdict(dict)
#_PROP_CACHE.clear()
+def get_cache_sizes():
+ """
+ Get cache sizes, expressed in number of objects and memory size in MB
+ """
+ global _ATTR_CACHE, _PROP_CACHE
+ attr_n = len(_ATTR_CACHE)
+ attr_mb = sum(getsizeof(obj) for obj in _ATTR_CACHE) / 1024.0
+ field_n = 0 #sum(len(dic) for dic in _FIELD_CACHE.values())
+ field_mb = 0 # sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _FIELD_CACHE.values()) / 1024.0
+ prop_n = sum(len(dic) for dic in _PROP_CACHE.values())
+ prop_mb = sum(sum([getsizeof(obj) for obj in dic.values()]) for dic in _PROP_CACHE.values()) / 1024.0
+ return (attr_n, attr_mb), (field_n, field_mb), (prop_n, prop_mb)
+
-#_ENABLE_LOCAL_CACHES = settings.GAME_CACHE_TYPE
-## oob helper functions
-# OOB hooks (OOB not yet functional, don't use yet)
-#_OOB_FIELD_UPDATE_HOOKS = defaultdict(dict)
-#_OOB_PROP_UPDATE_HOOKS = defaultdict(dict)
-#_OOB_ATTR_UPDATE_HOOKS = defaultdict(dict)
-#_OOB_NDB_UPDATE_HOOKS = defaultdict(dict)
-#_OOB_CUSTOM_UPDATE_HOOKS = defaultdict(dict)
-#
-#_OOB_HANDLER = None # set by oob handler when it initializes
-#def register_oob_update_hook(obj,name, entity="field"):
-# """
-# Register hook function to be called when field/property/db/ndb is updated.
-# Given function will be called with function(obj, entityname, newvalue, *args, **kwargs)
-# entity - one of "field", "property", "db", "ndb" or "custom"
-# """
-# hid = hashid(obj)
-# if hid:
-# 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
-# elif entity == "db":
-# global _OOB_ATTR_UPDATE_HOOKS
-# _OOB_ATTR_UPDATE_HOOKS[hid][name] = True
-# elif entity == "ndb":
-# global _OOB_NDB_UPDATE_HOOKS
-# _OOB_NDB_UPDATE_HOOKS[hid][name] = True
-# elif entity == "custom":
-# global _OOB_CUSTOM_UPDATE_HOOKS
-# _OOB_CUSTOM_UPDATE_HOOKS[hid][name] = True
-# else:
-# return None
-#
-#def unregister_oob_update_hook(obj, name, entity="property"):
-# """
-# Un-register a report hook
-# """
-# hid = hashid(obj)
-# if hid:
-# global _OOB_FIELD_UPDATE_HOOKS,_OOB_PROP_UPDATE_HOOKS, _OOB_ATTR_UPDATE_HOOKS
-# global _OOB_CUSTOM_UPDATE_HOOKS, _OOB_NDB_UPDATE_HOOKS
-# if entity == "field" and name in _OOB_FIELD_UPDATE_HOOKS:
-# del _OOB_FIELD_UPDATE_HOOKS[hid][name]
-# elif entity == "property" and name in _OOB_PROP_UPDATE_HOOKS:
-# del _OOB_PROP_UPDATE_HOOKS[hid][name]
-# elif entity == "db" and name in _OOB_ATTR_UPDATE_HOOKS:
-# del _OOB_ATTR_UPDATE_HOOKS[hid][name]
-# elif entity == "ndb" and name in _OOB_NDB_UPDATE_HOOKS:
-# del _OOB_NDB_UPDATE_HOOKS[hid][name]
-# elif entity == "custom" and name in _OOB_CUSTOM_UPDATE_HOOKS:
-# del _OOB_CUSTOM_UPDATE_HOOKS[hid][name]
-# else:
-# return None
-#
-#def call_ndb_hooks(obj, attrname, value):
-# """
-# No caching is done of ndb here, but
-# we use this as a way to call OOB hooks.
-# """
-# hid = hashid(obj)
-# if hid:
-# oob_hook = _OOB_NDB_UPDATE_HOOKS[hid].get(attrname)
-# if oob_hook:
-# oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2])
-#
-#def call_custom_hooks(obj, attrname, value):
-# """
-# Custom handler for developers adding their own oob hooks, e.g. to
-# custom typeclass properties.
-# """
-# hid = hashid(obj)
-# if hid:
-# oob_hook = _OOB_CUSTOM_UPDATE_HOOKS[hid].get(attrname)
-# if oob_hook:
-# oob_hook[0](obj.typeclass, attrname, value, *oob_hook[1], **oob_hook[2])
-#
diff --git a/src/server/portal/portalsessionhandler.py b/src/server/portal/portalsessionhandler.py
index 2424e14641..f0dbb40dac 100644
--- a/src/server/portal/portalsessionhandler.py
+++ b/src/server/portal/portalsessionhandler.py
@@ -121,7 +121,7 @@ class PortalSessionHandler(SessionHandler):
return [sess for sess in self.get_sessions(include_unloggedin=True)
if hasattr(sess, 'suid') and sess.suid == suid]
- def data_in(self, session, string="", **kwargs):
+ def data_in(self, session, text="", **kwargs):
"""
Called by portal sessions for relaying data coming
in from the protocol to the server. data is
@@ -129,7 +129,7 @@ class PortalSessionHandler(SessionHandler):
"""
#print "portal_data_in:", string
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
- msg=string,
+ msg=text,
data=kwargs)
def announce_all(self, message):
"""
diff --git a/src/server/portal/webclient.py b/src/server/portal/webclient.py
index 3737efb633..14d87d8c42 100644
--- a/src/server/portal/webclient.py
+++ b/src/server/portal/webclient.py
@@ -137,9 +137,9 @@ class WebClient(resource.Resource):
sess = self.sessionhandler.session_from_suid(suid)
if sess:
sess = sess[0]
- string = request.args.get('msg', [''])[0]
+ text = request.args.get('msg', [''])[0]
data = request.args.get('data', [None])[0]
- sess.sessionhandler.data_in(sess, string, data)
+ sess.sessionhandler.data_in(sess, text, data=data)
return ''
def mode_receive(self, request):
diff --git a/src/server/server.py b/src/server/server.py
index b7e8f6a281..21429e4b53 100644
--- a/src/server/server.py
+++ b/src/server/server.py
@@ -36,6 +36,12 @@ from django.db.models.signals import pre_save
from src.server.caches import field_pre_save
pre_save.connect(field_pre_save, dispatch_uid="fieldcache")
+from django.db.models.signals import m2m_changed
+from src.typeclasses.models import TypedObject
+from src.server.caches import post_attr_update
+# connect to attribute cache signal
+m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through)
+
_SA = object.__setattr__
if os.name == 'nt':
diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py
index 2106ac4049..eb6b9b0109 100644
--- a/src/typeclasses/models.py
+++ b/src/typeclasses/models.py
@@ -42,7 +42,6 @@ from django.db.models import Q
from django.db.models.signals import m2m_changed
from src.utils.idmapper.models import SharedMemoryModel
-from src.server.caches import get_field_cache, set_field_cache, del_field_cache
from src.server.caches import get_attr_cache, del_attr_cache, set_attr_cache
from src.server.caches import get_prop_cache, set_prop_cache, flush_attr_cache
from src.server.caches import post_attr_update
@@ -363,7 +362,7 @@ class AttributeHandler(object):
if attr_obj.count():
# re-use old attribute object
attr_obj = attr_obj[0]
- set_attr_cache(self.obj, key, attr_obj) # renew cache
+ #set_attr_cache(self.obj, key, attr_obj) # renew cache
else:
# no old attr available; create new (caches automatically)
attr_obj = Attribute(db_key=key, db_category=category)
@@ -1423,5 +1422,3 @@ class TypedObject(SharedMemoryModel):
-# connect to attribute cache signal
-m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through)
diff --git a/src/utils/create.py b/src/utils/create.py
index c734540633..5cd4c52c3f 100644
--- a/src/utils/create.py
+++ b/src/utils/create.py
@@ -53,7 +53,7 @@ _GA = object.__getattribute__
def create_object(typeclass, key=None, location=None,
home=None, permissions=None, locks=None,
- aliases=None, destination=None, report_to=None):
+ aliases=None, destination=None, report_to=None, testmode=False):
"""
Create a new in-game object. Any game object is a combination
of a database object that stores data persistently to
@@ -69,6 +69,7 @@ def create_object(typeclass, key=None, location=None,
If report_to is not set, errors will be raised as en Exception
containing the error message. If set, this method will return
None upon errors.
+ testmode is only intended for Evennia unittest system
"""
global _Object, _ObjectDB
if not _Object:
@@ -134,6 +135,9 @@ def create_object(typeclass, key=None, location=None,
# perform a move_to in order to display eventual messages.
if home:
new_object.home = home
+ elif testmode:
+ # this is required by unittest
+ pass
else:
new_object.home = settings.CHARACTER_DEFAULT_HOME