Some optimizations, cleanup and a few bugfixes. Just changing a spurious property retrieval in the typeclass removed an extra, pointless database query.
This commit is contained in:
parent
160d4a2807
commit
0dae03156c
5 changed files with 57 additions and 38 deletions
|
|
@ -632,16 +632,13 @@ class ObjectDB(TypedObject):
|
||||||
data (object): an optional data object that may or may not
|
data (object): an optional data object that may or may not
|
||||||
be used by the protocol.
|
be used by the protocol.
|
||||||
"""
|
"""
|
||||||
# This is an important function that must always work.
|
if _GA(self, 'player'):
|
||||||
# we use a different __getattribute__ to avoid recursive loops.
|
_GA(_GA(self, 'player'), "msg")(message, from_obj=from_obj, data=data)
|
||||||
|
|
||||||
if object.__getattribute__(self, 'player'):
|
|
||||||
object.__getattribute__(self, 'player').msg(message, from_obj=from_obj, data=data)
|
|
||||||
|
|
||||||
def emit_to(self, message, from_obj=None, data=None):
|
def emit_to(self, message, from_obj=None, data=None):
|
||||||
"Deprecated. Alias for msg"
|
"Deprecated. Alias for msg"
|
||||||
logger.log_depmsg("emit_to() is deprecated. Use msg() instead.")
|
logger.log_depmsg("emit_to() is deprecated. Use msg() instead.")
|
||||||
self.msg(message, from_obj, data)
|
_GA(self, "msg")(message, from_obj, data)
|
||||||
|
|
||||||
def msg_contents(self, message, exclude=None, from_obj=None, data=None):
|
def msg_contents(self, message, exclude=None, from_obj=None, data=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
from django.contrib.contenttypes.models import ContentType
|
|
||||||
|
|
||||||
from src.typeclasses.models import _get_cache, _set_cache, _del_cache
|
from src.typeclasses.models import _get_cache, _set_cache, _del_cache
|
||||||
from src.server.sessionhandler import SESSIONS
|
from src.server.sessionhandler import SESSIONS
|
||||||
|
|
@ -64,6 +63,8 @@ _GA = object.__getattribute__
|
||||||
_SA = object.__setattr__
|
_SA = object.__setattr__
|
||||||
_DA = object.__delattr__
|
_DA = object.__delattr__
|
||||||
|
|
||||||
|
_TYPECLASS = None
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# PlayerAttribute
|
# PlayerAttribute
|
||||||
|
|
@ -199,8 +200,11 @@ class PlayerDB(TypedObject):
|
||||||
#@obj.setter
|
#@obj.setter
|
||||||
def obj_set(self, value):
|
def obj_set(self, value):
|
||||||
"Setter. Allows for self.obj = value"
|
"Setter. Allows for self.obj = value"
|
||||||
from src.typeclasses.typeclass import TypeClass
|
global _TYPECLASS
|
||||||
if isinstance(value, TypeClass):
|
if not _TYPECLASS:
|
||||||
|
from src.typeclasses.typeclass import TypeClass as _TYPECLASS
|
||||||
|
|
||||||
|
if isinstance(value, _TYPECLASS):
|
||||||
value = value.dbobj
|
value = value.dbobj
|
||||||
try:
|
try:
|
||||||
_set_cache(self, "obj", value)
|
_set_cache(self, "obj", value)
|
||||||
|
|
@ -260,7 +264,6 @@ class PlayerDB(TypedObject):
|
||||||
#@is_connected.setter
|
#@is_connected.setter
|
||||||
def is_connected_set(self, value):
|
def is_connected_set(self, value):
|
||||||
"Setter. Allows for self.is_connected = value"
|
"Setter. Allows for self.is_connected = value"
|
||||||
print "set_is_connected:", self, value
|
|
||||||
_set_cache(self, "is_connected", value)
|
_set_cache(self, "is_connected", value)
|
||||||
#@is_connected.deleter
|
#@is_connected.deleter
|
||||||
def is_connected_del(self):
|
def is_connected_del(self):
|
||||||
|
|
@ -356,21 +359,19 @@ class PlayerDB(TypedObject):
|
||||||
Evennia -> User
|
Evennia -> User
|
||||||
This is the main route for sending data back to the user from the server.
|
This is the main route for sending data back to the user from the server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if from_obj:
|
if from_obj:
|
||||||
try:
|
try:
|
||||||
from_obj.at_msg_send(outgoing_string, to_obj=self, data=data)
|
_GA(from_obj, "at_msg_send")(outgoing_string, to_obj=self, data=data)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
if (_GA(self, "character") and not
|
||||||
if (object.__getattribute__(self, "character")
|
_GA(self, "character").at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
|
||||||
and not self.character.at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
|
|
||||||
# the at_msg_receive() hook may block receiving of certain messages
|
# the at_msg_receive() hook may block receiving of certain messages
|
||||||
return
|
return
|
||||||
|
|
||||||
outgoing_string = utils.to_str(outgoing_string, force_string=True)
|
outgoing_string = utils.to_str(outgoing_string, force_string=True)
|
||||||
|
|
||||||
for session in object.__getattribute__(self, 'sessions'):
|
for session in _GA(self, 'sessions'):
|
||||||
session.msg(outgoing_string, data)
|
session.msg(outgoing_string, data)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -383,8 +384,8 @@ class PlayerDB(TypedObject):
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
"Make sure to delete user also when deleting player - the two may never exist separately."
|
"Make sure to delete user also when deleting player - the two may never exist separately."
|
||||||
try:
|
try:
|
||||||
if self.user:
|
if _GA(self, "user"):
|
||||||
self.user.delete()
|
_GA(_GA(self, "user"), "delete")()
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
|
|
@ -398,7 +399,7 @@ class PlayerDB(TypedObject):
|
||||||
|
|
||||||
def execute_cmd(self, raw_string):
|
def execute_cmd(self, raw_string):
|
||||||
"""
|
"""
|
||||||
Do something as this playe. This command transparently
|
Do something as this player. This command transparently
|
||||||
lets its typeclass execute the command.
|
lets its typeclass execute the command.
|
||||||
raw_string - raw command input coming from the command line.
|
raw_string - raw command input coming from the command line.
|
||||||
"""
|
"""
|
||||||
|
|
@ -423,8 +424,11 @@ class PlayerDB(TypedObject):
|
||||||
the Player object itself. If no Character exists (since Player is
|
the Player object itself. If no Character exists (since Player is
|
||||||
OOC), None will be returned.
|
OOC), None will be returned.
|
||||||
"""
|
"""
|
||||||
matches = self.__class__.objects.player_search(ostring)
|
matches = _GA(_GA(_GA(self, "_class__"), "objects"), "player_search")(ostring)
|
||||||
matches = _AT_SEARCH_RESULT(self, ostring, matches, global_search=True)
|
matches = _AT_SEARCH_RESULT(self, ostring, matches, global_search=True)
|
||||||
if matches and return_character and hasattr(matches, "character"):
|
if matches and return_character:
|
||||||
return matches.character
|
try:
|
||||||
|
return _GA(matches, "character")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
return matches
|
return matches
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ _DA = object.__delattr__
|
||||||
_PLOADS = pickle.loads
|
_PLOADS = pickle.loads
|
||||||
_PDUMPS = pickle.dumps
|
_PDUMPS = pickle.dumps
|
||||||
|
|
||||||
|
|
||||||
# Property Cache mechanism.
|
# Property Cache mechanism.
|
||||||
|
|
||||||
def _get_cache(obj, name):
|
def _get_cache(obj, name):
|
||||||
|
|
@ -889,6 +890,17 @@ class TypedObject(SharedMemoryModel):
|
||||||
# try to look back to this very database object.)
|
# try to look back to this very database object.)
|
||||||
return _GA(_GA(self, 'typeclass'), propname)
|
return _GA(_GA(self, 'typeclass'), propname)
|
||||||
|
|
||||||
|
def _hasattr(self, obj, attrname):
|
||||||
|
"""
|
||||||
|
Loop-safe version of hasattr, to avoid running a lookup that
|
||||||
|
will be rerouted up the typeclass. Returns True/False.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
_GA(obj, attrname)
|
||||||
|
return True
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
_dbid_cache = None
|
_dbid_cache = None
|
||||||
def __dbid_get(self):
|
def __dbid_get(self):
|
||||||
|
|
@ -1504,7 +1516,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
def nattr(self, attribute_name=None, value=None, delete=False):
|
def nattr(self, attribute_name=None, value=None, delete=False):
|
||||||
"""
|
"""
|
||||||
This is the equivalence of self.attr but for non-persistent
|
This is the equivalence of self.attr but for non-persistent
|
||||||
stores.
|
stores. Will not raise error but return None.
|
||||||
"""
|
"""
|
||||||
if attribute_name == None:
|
if attribute_name == None:
|
||||||
# act as a list method
|
# act as a list method
|
||||||
|
|
@ -1515,11 +1527,11 @@ class TypedObject(SharedMemoryModel):
|
||||||
if not val.startswith['_']]
|
if not val.startswith['_']]
|
||||||
elif delete == True:
|
elif delete == True:
|
||||||
if hasattr(self.ndb, attribute_name):
|
if hasattr(self.ndb, attribute_name):
|
||||||
_DA(self.db, attribute_name)
|
_DA(_GA(self, "db"), attribute_name)
|
||||||
elif value == None:
|
elif value == None:
|
||||||
# act as a getter.
|
# act as a getter.
|
||||||
if hasattr(self.ndb, attribute_name):
|
if hasattr(self.ndb, attribute_name):
|
||||||
_GA(self.ndb, attribute_name)
|
_GA(_GA(self, "ndb"), attribute_name)
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ used by the typesystem or django itself.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from src.utils.logger import log_trace, log_errmsg
|
from src.utils.logger import log_trace, log_errmsg
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
__all__ = ("TypeClass",)
|
__all__ = ("TypeClass",)
|
||||||
|
|
||||||
|
|
@ -115,10 +114,11 @@ class TypeClass(object):
|
||||||
return _GA(dbobj, propname)
|
return _GA(dbobj, propname)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
|
#XXX deprecated
|
||||||
return _GA(dbobj,"get_attribute_raise")(propname)
|
return _GA(dbobj,"get_attribute_raise")(propname)
|
||||||
except AttributeError:
|
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.dbid, dbobj.typeclass_path))
|
raise AttributeError(string % (propname, dbobj, _GA(dbobj, "dbid"), _GA(dbobj, "typeclass_path")))
|
||||||
|
|
||||||
def __setattr__(self, propname, value):
|
def __setattr__(self, propname, value):
|
||||||
"""
|
"""
|
||||||
|
|
@ -134,7 +134,6 @@ class TypeClass(object):
|
||||||
string += " (protected: [%s])" % (", ".join(PROTECTED))
|
string += " (protected: [%s])" % (", ".join(PROTECTED))
|
||||||
log_errmsg(string % (self.name, propname))
|
log_errmsg(string % (self.name, propname))
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dbobj = _GA(self, 'dbobj')
|
dbobj = _GA(self, 'dbobj')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
@ -148,19 +147,20 @@ class TypeClass(object):
|
||||||
_GA(dbobj, propname)
|
_GA(dbobj, propname)
|
||||||
_SA(dbobj, propname, value)
|
_SA(dbobj, propname, value)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
#XXX deprecated
|
||||||
dbobj.set_attribute(propname, value)
|
dbobj.set_attribute(propname, value)
|
||||||
else:
|
else:
|
||||||
_SA(self, propname, value)
|
_SA(self, propname, value)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""
|
"""
|
||||||
dbobj-recognized comparison
|
dbobj-recognized comparison
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return other == self or other == _GA(self, dbobj) or other == _GA(self, dbobj).user
|
return other == self or other == _GA(self, dbobj) or other == _GA(self, dbobj).user
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# if self.dbobj.user fails it means the two previous comparisons failed already
|
# if self.dbobj.user fails it means the two previous comparisons failed already
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def __delattr__(self, propname):
|
def __delattr__(self, propname):
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,13 @@ def is_iter(iterable):
|
||||||
they are actually iterable), since string iterations
|
they are actually iterable), since string iterations
|
||||||
are usually not what we want to do with a string.
|
are usually not what we want to do with a string.
|
||||||
"""
|
"""
|
||||||
return hasattr(iterable, '__iter__')
|
# use a try..except here to avoid a property
|
||||||
|
# lookup when using this from a typeclassed entity
|
||||||
|
try:
|
||||||
|
_GA(iterable, '__iter__')
|
||||||
|
return True
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
def make_iter(obj):
|
def make_iter(obj):
|
||||||
"Makes sure that the object is always iterable."
|
"Makes sure that the object is always iterable."
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue