Further caching and optimization, making some operations noticeable faster in the end.

This commit is contained in:
Griatch 2012-04-26 17:47:25 +02:00
parent 1a6ef5d983
commit 6e08c011a1
13 changed files with 78 additions and 73 deletions

View file

@ -105,9 +105,10 @@ def get_and_merge_cmdsets(caller):
# Gather cmdsets from location, objects in location or carried
local_objects_cmdsets = [None]
location = None
if hasattr(caller, "location"):
try:
location = caller.location
except Exception:
location = None
if location and not caller_cmdset.no_objs:
# Gather all cmdsets stored on objects in the room and
# also in the caller's inventory and the location itself

View file

@ -158,7 +158,7 @@ def at_search_result(msg_obj, ostring, results, global_search=False):
if hasattr(result, "location") and result.location == msg_obj:
invtext = " (carried)"
if show_dbref:
dbreftext = "(#%i)" % result.id
dbreftext = "(#%i)" % result.dbid
string += "\n %i-%s%s%s" % (num+1, result.name,
dbreftext, invtext)
results = None

View file

@ -82,7 +82,6 @@ DefaultLock: Exits: controls who may traverse the exit to
"""
from django.conf import settings
from src.utils import search
from src.utils import utils
_PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
@ -123,7 +122,7 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs):
try:
perm = args[0].lower()
permissions = [p.lower() for p in accessing_obj.permissions]
except AttributeError, IndexError:
except (AttributeError, IndexError):
return False
if perm in permissions:
@ -193,8 +192,8 @@ def dbref(accessing_obj, accessed_obj, *args, **kwargs):
dbref = int(args[0].strip().strip('#'))
except ValueError:
return False
if hasattr(accessing_obj, 'id'):
return dbref == accessing_obj.id
if hasattr(accessing_obj, 'dbid'):
return dbref == accessing_obj.dbid
return False
def pdbref(accessing_obj, accessed_obj, *args, **kwargs):
@ -255,8 +254,7 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
"compare based on type"
try:
return CF_MAPPING.get(typ, 'default')(val1, val2)
except Exception, e:
#print e
except Exception:
# this might happen if we try to compare two things that cannot be compared
return False
@ -376,7 +374,7 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs):
# helper function. Compares both dbrefs and keys/aliases.
objid = str(objid)
dbref = utils.dbref(objid)
if dbref and any((True for obj in contents if obj.id == dbref)):
if dbref and any((True for obj in contents if obj.dbid == dbref)):
return True
objid = objid.lower()
return any((True for obj in contents
@ -386,13 +384,13 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs):
return check_holds(args[0])
else:
try:
if check_holds(accessed_obj.id):
if check_holds(accessed_obj.dbid):
#print "holds: accessed_obj.id - True"
return True
except Exception:
pass
#print "holds: accessed_obj.obj.id -", hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
return hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.id)
return hasattr(accessed_obj, "obj") and check_holds(accessed_obj.obj.dbid)
def superuser(*args, **kwargs):
"""

View file

@ -346,7 +346,7 @@ class LockHandler(object):
if (not no_superuser_bypass
and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser)))):
or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser)))):
# we grant access to superusers and also to protocol instances that not yet has any player assigned to them (the
# latter is a safety feature since superuser cannot be authenticated at some point during the connection).
return True

View file

@ -247,14 +247,10 @@ class ObjectDB(TypedObject):
"Setter. Allows for self.player = value"
if isinstance(player, TypeClass):
player = player.dbobj
self.db_player = player
self.save()
_set_cache(self, "player", player)
#@player.deleter
def __player_del(self):
"Deleter. Allows for del self.player"
self.db_player = None
self.save()
_del_cache(self, "player")
player = property(__player_get, __player_set, __player_del)
@ -747,7 +743,7 @@ class ObjectDB(TypedObject):
default_home_id = int(settings.CHARACTER_DEFAULT_HOME)
try:
default_home = ObjectDB.objects.get(id=default_home_id)
if default_home.id == self.id:
if default_home.dbid == self.dbid:
# we are deleting default home!
default_home = None
except Exception:
@ -758,7 +754,7 @@ class ObjectDB(TypedObject):
for obj in objs:
home = obj.home
# Obviously, we can't send it back to here.
if not home or (home and home.id == self.id):
if not home or (home and home.dbid == self.dbid):
obj.home = default_home
# If for some reason it's still None...
@ -767,14 +763,14 @@ class ObjectDB(TypedObject):
string += "now has a null location."
obj.location = None
obj.msg("Something went wrong! You are dumped into nowhere. Contact an admin.")
logger.log_errmsg(string % (obj.name, obj.id))
logger.log_errmsg(string % (obj.name, obj.dbid))
return
if obj.has_player:
if home:
string = "Your current location has ceased to exist,"
string += " moving you to %s(#%d)."
obj.msg(string % (home.name, home.id))
obj.msg(string % (home.name, home.dbid))
else:
# Famous last words: The player should never see this.
string = "This place should not exist ... contact an admin."

View file

@ -353,16 +353,14 @@ class Object(TypeClass):
This has be located at this level, having it in the
parent doesn't work.
"""
result = self.id == other
if not result and hasattr(other, "id"):
result = self.id == other.id
if not result:
try:
return self.dbref == other or self.dbref == other.dbref
except AttributeError:
# compare players instead
try:
result = other and self.user.id == other.user.id
return self.player.uid == other or self.player.uid == other.player.uid
except AttributeError:
pass
return result
return False
## hooks called by the game engine

View file

@ -257,10 +257,10 @@ class PlayerDB(TypedObject):
#
def __str__(self):
return smart_str("%s(player %i)" % (self.name, self.id))
return smart_str("%s(player %i)" % (self.name, self.dbid))
def __unicode__(self):
return u"%s(player#%i)" % (self.name, self.id)
return u"%s(player#%i)" % (self.name, self.dbid)
# this is required to properly handle attributes and typeclass loading
_typeclass_paths = settings.PLAYER_TYPECLASS_PATHS

View file

@ -2,25 +2,25 @@
The script handler makes sure to check through all stored scripts
to make sure they are still relevant.
An scripthandler is automatically added to all game objects. You
access it through the property 'scripts' on the game object.
access it through the property 'scripts' on the game object.
"""
from src.scripts.models import ScriptDB
from src.utils import create
from src.utils import create
from src.utils import logger
class ScriptHandler(object):
"""
Implements the handler. This sits on each game object.
Implements the handler. This sits on each game object.
"""
def __init__(self, obj):
"""
Set up internal state.
obj - a reference to the object this handler is attached to.
obj - a reference to the object this handler is attached to.
We retrieve all scripts attached to this object and check
if they are all peristent. If they are not, they are just
cruft left over from a server shutdown.
cruft left over from a server shutdown.
"""
self.obj = obj
@ -32,10 +32,10 @@ class ScriptHandler(object):
interval = "inf"
next_repeat = "inf"
repeats = "inf"
if script.interval > 0:
if script.interval > 0:
interval = script.interval
if script.repeats:
repeats = script.repeats
repeats = script.repeats
try: next_repeat = script.time_until_next_repeat()
except: next_repeat = "?"
string += "\n '%s' (%s/%s, %s repeats): %s" % (script.key,
@ -47,19 +47,19 @@ class ScriptHandler(object):
def add(self, scriptclass, key=None, autostart=True):
"""
Add an script to this object.
Add an script to this object.
scriptclass - either a class object
inheriting from Script, an instantiated script object
or a python path to such a class object.
key - optional identifier for the script (often set in script definition)
autostart - start the script upon adding it
"""
"""
script = create.create_script(scriptclass, key=key, obj=self.obj, autostart=autostart)
if not script:
logger.log_errmsg("Script %s could not be created and/or started." % scriptclass)
return False
return True
return False
return True
def start(self, scriptid):
"""
@ -68,14 +68,14 @@ class ScriptHandler(object):
scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
num = 0
for script in scripts:
num += script.start()
return num
num += script.start()
return num
def delete(self, scriptid):
"""
Forcibly delete a script from this object.
scriptid can be a script key or the path to a script (in the
scriptid can be a script key or the path to a script (in the
latter case all scripts with this path will be deleted!)
"""
@ -85,7 +85,7 @@ class ScriptHandler(object):
num = 0
for script in delscripts:
num += script.stop()
return num
return num
def stop(self, scriptid):
"""
@ -105,4 +105,4 @@ class ScriptHandler(object):
This should be called regularly to crank the wheels.
"""
ScriptDB.objects.validate(obj=self.obj, init_mode=init_mode)

View file

@ -32,7 +32,7 @@ class ScriptClass(TypeClass):
parent doesn't work.
"""
try:
return other.id == self.id
return other.dbid == self.dbid
except Exception:
return False
@ -61,7 +61,7 @@ class ScriptClass(TypeClass):
def _step_err_callback(self, e):
"callback for runner errors"
cname = self.__class__.__name__
estring = "Script %s(#%i) of type '%s': at_repeat() error '%s'." % (self.key, self.id, cname, e.getErrorMessage())
estring = "Script %s(#%i) of type '%s': at_repeat() error '%s'." % (self.key, self.dbid, cname, e.getErrorMessage())
try:
self.dbobj.db_obj.msg(estring)
except Exception:
@ -183,7 +183,7 @@ class ScriptClass(TypeClass):
try:
self._stop_task()
except Exception, e:
logger.log_trace("Stopping script %s(%s)" % (self.key, self.id))
logger.log_trace("Stopping script %s(%s)" % (self.key, self.dbid))
pass
try:
self.dbobj.delete()

View file

@ -139,10 +139,7 @@ class ServerSession(Session):
"""
Get the player associated with this session
"""
if self.logged_in:
return self.player
else:
return None
return self.logged_in and self.player
def get_character(self):
"""

View file

@ -14,7 +14,6 @@ There are two similar but separate stores of sessions:
import time
from django.conf import settings
from django.contrib.auth.models import User
from src.server.models import ServerConfig
from src.commands.cmdhandler import CMD_LOGINSTART
@ -259,12 +258,7 @@ class ServerSessionHandler(SessionHandler):
"""
Given a player, return any matching sessions.
"""
username = player.user.username
try:
uobj = User.objects.get(username=username)
except User.DoesNotExist:
return None
uid = uobj.id
uid = player.uid
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
def sessions_from_character(self, character):

View file

@ -853,7 +853,7 @@ class TypedObject(SharedMemoryModel):
_db_model_name = "typeclass" # used by attributes to safely store objects
def __eq__(self, other):
return other and hasattr(other, 'id') and self.id == other.id
return other and hasattr(other, 'dbid') and self.dbid == other.dbid
def __str__(self):
return smart_str("%s" % self.key)
@ -881,16 +881,35 @@ class TypedObject(SharedMemoryModel):
return _GA(typeclass, propname)
else:
raise AttributeError
#@property
_dbid_cache = None
def __dbid_get(self):
"""
Caches and returns the unique id of the object.
Use this instead of self.id, which is not cached.
"""
dbid = _GA(self, "_dbid_cache")
if not dbid:
dbid = _GA(self, "id")
_SA(self, "_dbid_cache", dbid)
return dbid
def __dbid_set(self, value):
raise Exception("dbid cannot be set!")
def __dbid_del(self):
raise Exception("dbid cannot be deleted!")
dbid = property(__dbid_get, __dbid_set, __dbid_del)
#@property
def __dbref_get(self):
"""
Returns the object's dbref id on the form #NN.
Alternetively, use obj.id directly to get dbref
without any #.
Returns the object's dbref on the form #NN.
"""
return "#%s" % str(_GA(self, "id"))
dbref = property(__dbref_get)
return "#%s" % _GA(self, "_TypedObject__dbid_get")()
def __dbref_set(self):
raise Exception("dbref cannot be set!")
def __dbref_del(self):
raise Exception("dbref cannot be deleted!")
dbref = property(__dbref_get, __dbref_set, __dbref_del)
# typeclass property
#@property

View file

@ -91,6 +91,8 @@ class TypeClass(object):
transparently include the properties on
self.dbobj. Note that dbobj properties have
priority, so if you define a same-named
property on the class, it will NOT be
accessible through getattr.
"""
@ -115,8 +117,8 @@ class TypeClass(object):
try:
return _GA(dbobj,"get_attribute_raise")(propname)
except AttributeError:
string = "Object: '%s' not found on %s(%s), nor on its typeclass %s."
raise AttributeError(string % (propname, dbobj, dbobj.dbref, dbobj.typeclass_path))
string = "Object: '%s' not found on %s(#%s), nor on its typeclass %s."
raise AttributeError(string % (propname, dbobj, dbobj.dbid, dbobj.typeclass_path))
def __setattr__(self, propname, value):
"""
@ -185,9 +187,9 @@ class TypeClass(object):
try:
dbobj.del_attribute_raise(propname)
except AttributeError:
string = "Object: '%s' not found on %s(%s), nor on its typeclass %s."
string = "Object: '%s' not found on %s(#%s), nor on its typeclass %s."
raise AttributeError(string % (propname, dbobj,
dbobj.dbref,
dbobj.dbid,
dbobj.typeclass_path,))
def __str__(self):