mirror of
https://github.com/evennia/evennia.git
synced 2026-03-19 14:26:30 +01:00
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
|
||||
be used by the protocol.
|
||||
"""
|
||||
# This is an important function that must always work.
|
||||
# we use a different __getattribute__ to avoid recursive loops.
|
||||
|
||||
if object.__getattribute__(self, 'player'):
|
||||
object.__getattribute__(self, 'player').msg(message, from_obj=from_obj, data=data)
|
||||
if _GA(self, 'player'):
|
||||
_GA(_GA(self, 'player'), "msg")(message, from_obj=from_obj, data=data)
|
||||
|
||||
def emit_to(self, message, from_obj=None, data=None):
|
||||
"Deprecated. Alias for msg"
|
||||
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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ from django.conf import settings
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
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.server.sessionhandler import SESSIONS
|
||||
|
|
@ -64,6 +63,8 @@ _GA = object.__getattribute__
|
|||
_SA = object.__setattr__
|
||||
_DA = object.__delattr__
|
||||
|
||||
_TYPECLASS = None
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# PlayerAttribute
|
||||
|
|
@ -199,8 +200,11 @@ class PlayerDB(TypedObject):
|
|||
#@obj.setter
|
||||
def obj_set(self, value):
|
||||
"Setter. Allows for self.obj = value"
|
||||
from src.typeclasses.typeclass import TypeClass
|
||||
if isinstance(value, TypeClass):
|
||||
global _TYPECLASS
|
||||
if not _TYPECLASS:
|
||||
from src.typeclasses.typeclass import TypeClass as _TYPECLASS
|
||||
|
||||
if isinstance(value, _TYPECLASS):
|
||||
value = value.dbobj
|
||||
try:
|
||||
_set_cache(self, "obj", value)
|
||||
|
|
@ -260,7 +264,6 @@ class PlayerDB(TypedObject):
|
|||
#@is_connected.setter
|
||||
def is_connected_set(self, value):
|
||||
"Setter. Allows for self.is_connected = value"
|
||||
print "set_is_connected:", self, value
|
||||
_set_cache(self, "is_connected", value)
|
||||
#@is_connected.deleter
|
||||
def is_connected_del(self):
|
||||
|
|
@ -356,21 +359,19 @@ class PlayerDB(TypedObject):
|
|||
Evennia -> User
|
||||
This is the main route for sending data back to the user from the server.
|
||||
"""
|
||||
|
||||
if from_obj:
|
||||
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:
|
||||
pass
|
||||
|
||||
if (object.__getattribute__(self, "character")
|
||||
and not self.character.at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
|
||||
if (_GA(self, "character") and not
|
||||
_GA(self, "character").at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
|
||||
# the at_msg_receive() hook may block receiving of certain messages
|
||||
return
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
|
@ -383,8 +384,8 @@ class PlayerDB(TypedObject):
|
|||
def delete(self, *args, **kwargs):
|
||||
"Make sure to delete user also when deleting player - the two may never exist separately."
|
||||
try:
|
||||
if self.user:
|
||||
self.user.delete()
|
||||
if _GA(self, "user"):
|
||||
_GA(_GA(self, "user"), "delete")()
|
||||
except AssertionError:
|
||||
pass
|
||||
try:
|
||||
|
|
@ -398,7 +399,7 @@ class PlayerDB(TypedObject):
|
|||
|
||||
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.
|
||||
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
|
||||
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)
|
||||
if matches and return_character and hasattr(matches, "character"):
|
||||
return matches.character
|
||||
if matches and return_character:
|
||||
try:
|
||||
return _GA(matches, "character")
|
||||
except:
|
||||
pass
|
||||
return matches
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ _DA = object.__delattr__
|
|||
_PLOADS = pickle.loads
|
||||
_PDUMPS = pickle.dumps
|
||||
|
||||
|
||||
# Property Cache mechanism.
|
||||
|
||||
def _get_cache(obj, name):
|
||||
|
|
@ -889,6 +890,17 @@ class TypedObject(SharedMemoryModel):
|
|||
# try to look back to this very database object.)
|
||||
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
|
||||
_dbid_cache = None
|
||||
def __dbid_get(self):
|
||||
|
|
@ -1504,7 +1516,7 @@ class TypedObject(SharedMemoryModel):
|
|||
def nattr(self, attribute_name=None, value=None, delete=False):
|
||||
"""
|
||||
This is the equivalence of self.attr but for non-persistent
|
||||
stores.
|
||||
stores. Will not raise error but return None.
|
||||
"""
|
||||
if attribute_name == None:
|
||||
# act as a list method
|
||||
|
|
@ -1515,11 +1527,11 @@ class TypedObject(SharedMemoryModel):
|
|||
if not val.startswith['_']]
|
||||
elif delete == True:
|
||||
if hasattr(self.ndb, attribute_name):
|
||||
_DA(self.db, attribute_name)
|
||||
_DA(_GA(self, "db"), attribute_name)
|
||||
elif value == None:
|
||||
# act as a getter.
|
||||
if hasattr(self.ndb, attribute_name):
|
||||
_GA(self.ndb, attribute_name)
|
||||
_GA(_GA(self, "ndb"), attribute_name)
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ used by the typesystem or django itself.
|
|||
"""
|
||||
|
||||
from src.utils.logger import log_trace, log_errmsg
|
||||
from django.conf import settings
|
||||
|
||||
__all__ = ("TypeClass",)
|
||||
|
||||
|
|
@ -115,10 +114,11 @@ class TypeClass(object):
|
|||
return _GA(dbobj, propname)
|
||||
except AttributeError:
|
||||
try:
|
||||
#XXX deprecated
|
||||
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.dbid, dbobj.typeclass_path))
|
||||
raise AttributeError(string % (propname, dbobj, _GA(dbobj, "dbid"), _GA(dbobj, "typeclass_path")))
|
||||
|
||||
def __setattr__(self, propname, value):
|
||||
"""
|
||||
|
|
@ -134,7 +134,6 @@ class TypeClass(object):
|
|||
string += " (protected: [%s])" % (", ".join(PROTECTED))
|
||||
log_errmsg(string % (self.name, propname))
|
||||
return
|
||||
|
||||
try:
|
||||
dbobj = _GA(self, 'dbobj')
|
||||
except AttributeError:
|
||||
|
|
@ -148,19 +147,20 @@ class TypeClass(object):
|
|||
_GA(dbobj, propname)
|
||||
_SA(dbobj, propname, value)
|
||||
except AttributeError:
|
||||
#XXX deprecated
|
||||
dbobj.set_attribute(propname, value)
|
||||
else:
|
||||
_SA(self, propname, value)
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
dbobj-recognized comparison
|
||||
"""
|
||||
try:
|
||||
return other == self or other == _GA(self, dbobj) or other == _GA(self, dbobj).user
|
||||
except AttributeError:
|
||||
# if self.dbobj.user fails it means the two previous comparisons failed already
|
||||
return False
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
dbobj-recognized comparison
|
||||
"""
|
||||
try:
|
||||
return other == self or other == _GA(self, dbobj) or other == _GA(self, dbobj).user
|
||||
except AttributeError:
|
||||
# if self.dbobj.user fails it means the two previous comparisons failed already
|
||||
return False
|
||||
|
||||
|
||||
def __delattr__(self, propname):
|
||||
|
|
|
|||
|
|
@ -34,7 +34,13 @@ def is_iter(iterable):
|
|||
they are actually iterable), since string iterations
|
||||
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):
|
||||
"Makes sure that the object is always iterable."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue