mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Various speed optimizations in various places, following further profiling.
This commit is contained in:
parent
83fa9397d5
commit
4c83d3e7a1
7 changed files with 75 additions and 59 deletions
|
|
@ -142,7 +142,8 @@ def get_and_merge_cmdsets(caller):
|
|||
# report cmdset errors to user (these should already have been logged)
|
||||
yield [caller.msg(cmdset.message) for cmdset in cmdsets if cmdset.key == "_CMDSET_ERROR"]
|
||||
# sort cmdsets after reverse priority (highest prio are merged in last)
|
||||
cmdsets = yield sorted(cmdsets, key=lambda x: x.priority)
|
||||
yield cmdsets.sort(key=lambda x: x.priority)
|
||||
#cmdsets = yield sorted(cmdsets, key=lambda x: x.priority)
|
||||
|
||||
if cmdsets:
|
||||
# Merge all command sets into one, beginning with the lowest-prio one
|
||||
|
|
|
|||
|
|
@ -144,10 +144,12 @@ class CmdSet(object):
|
|||
if key:
|
||||
self.key = key
|
||||
self.commands = []
|
||||
self.system_commands = []
|
||||
self.actual_mergetype = self.mergetype
|
||||
self.cmdsetobj = cmdsetobj
|
||||
# initialize system
|
||||
self.at_cmdset_creation()
|
||||
self._contains_cache = {}
|
||||
|
||||
# Priority-sensitive merge operations for cmdsets
|
||||
|
||||
|
|
@ -223,7 +225,13 @@ class CmdSet(object):
|
|||
Returns True if this cmdset contains the given command (as defined
|
||||
by command name and aliases). This allows for things like 'if cmd in cmdset'
|
||||
"""
|
||||
return othercmd in self.commands
|
||||
# optimization test
|
||||
try:
|
||||
return self._contains_cache[othercmd]
|
||||
except KeyError:
|
||||
ret = othercmd in self.commands
|
||||
self._contains_cache[othercmd] = ret
|
||||
return ret
|
||||
|
||||
def __add__(self, cmdset_b):
|
||||
"""
|
||||
|
|
@ -327,18 +335,29 @@ class CmdSet(object):
|
|||
cmds = [self._instantiate(c) for c in cmd]
|
||||
else:
|
||||
cmds = [self._instantiate(cmd)]
|
||||
commands = self.commands
|
||||
system_commands = self.system_commands
|
||||
for cmd in cmds:
|
||||
# add all commands
|
||||
if not hasattr(cmd, 'obj'):
|
||||
cmd.obj = self.cmdsetobj
|
||||
try:
|
||||
ic = self.commands.index(cmd)
|
||||
self.commands[ic] = cmd # replace
|
||||
ic = commands.index(cmd)
|
||||
commands[ic] = cmd # replace
|
||||
except ValueError:
|
||||
self.commands.append(cmd)
|
||||
commands.append(cmd)
|
||||
# extra run to make sure to avoid doublets
|
||||
self.commands = list(set(self.commands))
|
||||
self.commands = list(set(commands))
|
||||
#print "In cmdset.add(cmd):", self.key, cmd
|
||||
# add system_command to separate list as well,
|
||||
# for quick look-up
|
||||
if cmd.key.startswith("__"):
|
||||
try:
|
||||
ic = system_commands.index(cmd)
|
||||
system_commands[ic] = cmd # replace
|
||||
except ValueError:
|
||||
system_commands.append(cmd)
|
||||
|
||||
|
||||
def remove(self, cmd):
|
||||
"""
|
||||
|
|
@ -369,7 +388,8 @@ class CmdSet(object):
|
|||
commands starting with double underscore __.
|
||||
These are excempt from merge operations.
|
||||
"""
|
||||
return [cmd for cmd in self.commands if cmd.key.startswith('__')]
|
||||
return self.system_commands
|
||||
#return [cmd for cmd in self.commands if cmd.key.startswith('__')]
|
||||
|
||||
def make_unique(self, caller):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ class CommandMeta(type):
|
|||
mcs.aliases = [str(alias).strip().lower() for alias in mcs.aliases]
|
||||
# optimization - a set is much faster to match against than a list
|
||||
mcs._matchset = set([mcs.key] + mcs.aliases)
|
||||
# optimization for retrieving aliases and key as one list
|
||||
mcs._keyaliases = [mcs.key] + mcs.aliases
|
||||
# optimization for looping over keys+aliases
|
||||
mcs._keyaliases = tuple(mcs._matchset)
|
||||
|
||||
# by default we don't save the command between runs
|
||||
if not hasattr(mcs, "save_for_next"):
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ _ME = _("me")
|
|||
_SELF = _("self")
|
||||
_HERE = _("here")
|
||||
|
||||
|
||||
def clean_content_cache(obj):
|
||||
"Clean obj's content cache"
|
||||
_SA(obj, "_contents_cache", None)
|
||||
|
|
@ -428,8 +427,8 @@ class ObjectDB(TypedObject):
|
|||
Retrieve sessions connected to this object.
|
||||
"""
|
||||
# if the player is not connected, this will simply be an empty list.
|
||||
if self.player:
|
||||
return self.player.sessions
|
||||
if _GA(self, "player"):
|
||||
return _GA(_GA(self, "player"), "sessions")
|
||||
return []
|
||||
sessions = property(__sessions_get)
|
||||
|
||||
|
|
@ -439,14 +438,15 @@ class ObjectDB(TypedObject):
|
|||
Convenience function for checking if an active player is
|
||||
currently connected to this object
|
||||
"""
|
||||
return any(self.sessions)
|
||||
return any(_GA(self, "sessions"))
|
||||
has_player = property(__has_player_get)
|
||||
is_player = property(__has_player_get)
|
||||
|
||||
#@property
|
||||
def __is_superuser_get(self):
|
||||
"Check if user has a player, and if so, if it is a superuser."
|
||||
return any(self.sessions) and self.player.is_superuser
|
||||
#return any(self.sessions) and self.player.is_superuser
|
||||
return any(_GA(self, "sessions")) and _GA(_GA(self, "player"), "is_superuser")
|
||||
is_superuser = property(__is_superuser_get)
|
||||
|
||||
# contents
|
||||
|
|
|
|||
|
|
@ -637,31 +637,26 @@ class Object(TypeClass):
|
|||
"""
|
||||
if not pobject:
|
||||
return
|
||||
string = "{c%s{n" % self.name
|
||||
desc = self.attr("desc")
|
||||
# get and identify all objects
|
||||
visible = (con for con in self.contents if con != pobject and con.access(pobject, "view"))
|
||||
exits, users, things = [], [], []
|
||||
for con in visible:
|
||||
key = con.key
|
||||
if con.destination:
|
||||
exits.append(key)
|
||||
elif con.has_player:
|
||||
users.append("{c%s{n" % key)
|
||||
else:
|
||||
things.append(key)
|
||||
# get description, build string
|
||||
string = "{c%s{n" % self.key
|
||||
desc = self.db.desc
|
||||
if desc:
|
||||
string += "\n %s" % desc
|
||||
exits = []
|
||||
users = []
|
||||
things = []
|
||||
for content in [con for con in self.contents if con.access(pobject, 'view')]:
|
||||
if content == pobject:
|
||||
continue
|
||||
name = content.name
|
||||
if content.destination:
|
||||
exits.append(name)
|
||||
elif content.has_player:
|
||||
users.append(name)
|
||||
else:
|
||||
things.append(name)
|
||||
if exits:
|
||||
string += "\n{wExits:{n " + ", ".join(exits)
|
||||
if users or things:
|
||||
string += "\n{wYou see: {n"
|
||||
if users:
|
||||
string += "{c" + ", ".join(users) + "{n "
|
||||
if things:
|
||||
string += ", ".join(things)
|
||||
string += "\n{wYou see:{n " + ", ".join(users + things)
|
||||
return string
|
||||
|
||||
def at_desc(self, looker=None):
|
||||
|
|
|
|||
|
|
@ -180,9 +180,9 @@ class PlayerDB(TypedObject):
|
|||
"Parent must be initiated first"
|
||||
TypedObject.__init__(self, *args, **kwargs)
|
||||
# handlers
|
||||
self.cmdset = CmdSetHandler(self)
|
||||
self.cmdset.update(init_mode=True)
|
||||
self.nicks = PlayerNickHandler(self)
|
||||
_SA(self, "cmdset", CmdSetHandler(self))
|
||||
_GA(self, "cmdset").update(init_mode=True)
|
||||
_SA(self, "nicks", PlayerNickHandler(self))
|
||||
|
||||
# Wrapper properties to easily set database fields. These are
|
||||
# @property decorators that allows to access these fields using
|
||||
|
|
@ -240,21 +240,21 @@ class PlayerDB(TypedObject):
|
|||
#@property
|
||||
def cmdset_storage_get(self):
|
||||
"Getter. Allows for value = self.name. Returns a list of cmdset_storage."
|
||||
if self.db_cmdset_storage:
|
||||
return [path.strip() for path in self.db_cmdset_storage.split(',')]
|
||||
if _GA(self, "db_cmdset_storage"):
|
||||
return [path.strip() for path in _GA(self, "db_cmdset_storage").split(',')]
|
||||
return []
|
||||
#@cmdset_storage.setter
|
||||
def cmdset_storage_set(self, value):
|
||||
"Setter. Allows for self.name = value. Stores as a comma-separated string."
|
||||
if utils.is_iter(value):
|
||||
value = ",".join([str(val).strip() for val in value])
|
||||
self.db_cmdset_storage = value
|
||||
self.save()
|
||||
_SA(self, "db_cmdset_storage", value)
|
||||
_GA(self, "save")()
|
||||
#@cmdset_storage.deleter
|
||||
def cmdset_storage_del(self):
|
||||
"Deleter. Allows for del self.name"
|
||||
self.db_cmdset_storage = ""
|
||||
self.save()
|
||||
_SA(self, "db_cmdset_storage", "")
|
||||
_GA(self, "save")()
|
||||
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
|
||||
|
||||
#@property
|
||||
|
|
@ -281,10 +281,10 @@ class PlayerDB(TypedObject):
|
|||
#
|
||||
|
||||
def __str__(self):
|
||||
return smart_str("%s(player %s)" % (self.name, self.dbid))
|
||||
return smart_str("%s(player %s)" % (_GA(self, "name"), _GA(self, "dbid")))
|
||||
|
||||
def __unicode__(self):
|
||||
return u"%s(player#%s)" % (self.name, self.dbid)
|
||||
return u"%s(player#%s)" % (_GA(self, "name"), _GA(self, "dbid"))
|
||||
|
||||
# this is required to properly handle attributes and typeclass loading
|
||||
_typeclass_paths = settings.PLAYER_TYPECLASS_PATHS
|
||||
|
|
@ -297,15 +297,15 @@ class PlayerDB(TypedObject):
|
|||
#@property
|
||||
def name_get(self):
|
||||
"Getter. Allows for value = self.name"
|
||||
if not self._name_cache:
|
||||
self._name_cache = self.user.username
|
||||
return self._name_cache
|
||||
if not _GA(self, "_name_cache"):
|
||||
_SA(self, "_name_cache", _GA(self,"user").username)
|
||||
return _GA(self, "_name_cache")
|
||||
#@name.setter
|
||||
def name_set(self, value):
|
||||
"Setter. Allows for player.name = newname"
|
||||
self.user.username = value
|
||||
self.user.save() # this might be stopped by Django?
|
||||
self._name_cache = value
|
||||
_GA(self, "user").username = value
|
||||
_GA(self, "user").save()
|
||||
_SA(self, "_name_cache", value)
|
||||
#@name.deleter
|
||||
def name_del(self):
|
||||
"Deleter. Allows for del self.name"
|
||||
|
|
@ -317,9 +317,9 @@ class PlayerDB(TypedObject):
|
|||
#@property
|
||||
def uid_get(self):
|
||||
"Getter. Retrieves the user id"
|
||||
if not self._uid_cache:
|
||||
self._uid_cache = self.user.id
|
||||
return self._uid_cache
|
||||
if not _GA(self, "_uid_cache"):
|
||||
_SA(self, "_uid_cache", _GA(self, "user").id)
|
||||
return _GA(self, "_uid_cache")
|
||||
def uid_set(self, value):
|
||||
raise Exception("User id cannot be set!")
|
||||
def uid_del(self):
|
||||
|
|
@ -345,9 +345,9 @@ class PlayerDB(TypedObject):
|
|||
_is_superuser_cache = None
|
||||
def is_superuser_get(self):
|
||||
"Superusers have all permissions."
|
||||
if self._is_superuser_cache == None:
|
||||
self._is_superuser_cache = self.user.is_superuser
|
||||
return self._is_superuser_cache
|
||||
if _GA(self, "_is_superuser_cache") == None:
|
||||
_SA(self, "_is_superuser_cache", _GA(self, "user").is_superuser)
|
||||
return _GA(self, "_is_superuser_cache")
|
||||
is_superuser = property(is_superuser_get)
|
||||
|
||||
#
|
||||
|
|
@ -379,7 +379,7 @@ class PlayerDB(TypedObject):
|
|||
"""
|
||||
Swaps character, if possible
|
||||
"""
|
||||
return self.__class__.objects.swap_character(self, new_character, delete_old_character=delete_old_character)
|
||||
return _GA(self, "__class__").objects.swap_character(self, new_character, delete_old_character=delete_old_character)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"Make sure to delete user also when deleting player - the two may never exist separately."
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ DEFAULT_NCLIENTS = 1
|
|||
# time between each 'tick', in seconds, if not set on command
|
||||
# line. All launched clients will be called upon to possibly do an
|
||||
# action with this frequency.
|
||||
DEFAULT_TIMESTEP = 5
|
||||
DEFAULT_TIMESTEP = 2
|
||||
# Port to use, if not specified on command line
|
||||
DEFAULT_PORT = settings.TELNET_PORTS[0]
|
||||
# chance of an action happening, per timestep. This helps to
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue