mirror of
https://github.com/evennia/evennia.git
synced 2026-03-31 04:57:16 +02:00
Changed how lazy-loading of handlers work, using a werkzeug recipe. Much more efficient now.
This commit is contained in:
parent
680e603c4d
commit
e6950aadf2
10 changed files with 125 additions and 144 deletions
|
|
@ -141,7 +141,6 @@ class CmdClimb(Command):
|
|||
obj = self.caller.search(self.args.strip())
|
||||
if not obj:
|
||||
return
|
||||
print "obj", "self.obj", obj, self
|
||||
if obj != self.obj:
|
||||
self.caller.msg("Try as you might, you cannot climb that.")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ All commands in Evennia inherit from the 'Command' class in this module.
|
|||
|
||||
import re
|
||||
from src.locks.lockhandler import LockHandler
|
||||
from src.utils.utils import is_iter, fill, LazyLoadHandler
|
||||
from src.utils.utils import is_iter, fill, lazy_property
|
||||
|
||||
|
||||
def _init_command(mcs, **kwargs):
|
||||
|
|
@ -155,7 +155,10 @@ class Command(object):
|
|||
overloading evential same-named class properties."""
|
||||
if kwargs:
|
||||
_init_command(self, **kwargs)
|
||||
self.lockhandler = LazyLoadHandler(self, "lockhandler", LockHandler)
|
||||
|
||||
@lazy_property
|
||||
def lockhandler(self):
|
||||
return LockHandler(self)
|
||||
|
||||
def __str__(self):
|
||||
"Print the command"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from src.utils.idmapper.models import SharedMemoryModel
|
|||
from src.comms import managers
|
||||
from src.comms.managers import identify_object
|
||||
from src.locks.lockhandler import LockHandler
|
||||
from src.utils.utils import crop, make_iter, LazyLoadHandler
|
||||
from src.utils.utils import crop, make_iter, lazy_property
|
||||
|
||||
__all__ = ("Msg", "TempMsg", "ChannelDB")
|
||||
|
||||
|
|
@ -103,7 +103,6 @@ class Msg(SharedMemoryModel):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
SharedMemoryModel.__init__(self, *args, **kwargs)
|
||||
#_SA(self, "locks", LazyLoadHandler(self, "locks", LockHandler))
|
||||
self.extra_senders = []
|
||||
|
||||
class Meta:
|
||||
|
|
@ -299,10 +298,13 @@ class TempMsg(object):
|
|||
self.header = header
|
||||
self.message = message
|
||||
self.lock_storage = lockstring
|
||||
self.locks = LazyLoadHandler(self, "locks", LockHandler)
|
||||
self.hide_from = hide_from and make_iter(hide_from) or []
|
||||
self.date_sent = datetime.now()
|
||||
|
||||
@lazy_property
|
||||
def locks(self):
|
||||
return LockHandler(self)
|
||||
|
||||
def __str__(self):
|
||||
"This handles what is shown when e.g. printing the message"
|
||||
senders = ",".join(obj.key for obj in self.senders)
|
||||
|
|
@ -359,12 +361,6 @@ class ChannelDB(TypedObject):
|
|||
_typeclass_paths = settings.CHANNEL_TYPECLASS_PATHS
|
||||
_default_typeclass_path = settings.BASE_CHANNEL_TYPECLASS or "src.comms.comms.Channel"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
TypedObject.__init__(self, *args, **kwargs)
|
||||
_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
||||
_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
||||
_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
||||
|
||||
class Meta:
|
||||
"Define Django meta options"
|
||||
verbose_name = "Channel"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from src.utils.idmapper.models import SharedMemoryModel
|
|||
from src.help.manager import HelpEntryManager
|
||||
from src.typeclasses.models import Tag, TagHandler
|
||||
from src.locks.lockhandler import LockHandler
|
||||
from src.utils.utils import LazyLoadHandler
|
||||
from src.utils.utils import lazy_property
|
||||
__all__ = ("HelpEntry",)
|
||||
|
||||
|
||||
|
|
@ -66,10 +66,16 @@ class HelpEntry(SharedMemoryModel):
|
|||
objects = HelpEntryManager()
|
||||
_is_deleted = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
SharedMemoryModel.__init__(self, *args, **kwargs)
|
||||
self.locks = LazyLoadHandler(self, "locks", LockHandler)
|
||||
self.tags = LazyLoadHandler(self, "tags", TagHandler)
|
||||
# lazy-loaded handlers
|
||||
|
||||
@lazy_property
|
||||
def locks(self):
|
||||
return LockHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def tags(self):
|
||||
return TagHandler(self)
|
||||
|
||||
|
||||
class Meta:
|
||||
"Define Django meta options"
|
||||
|
|
|
|||
|
|
@ -19,16 +19,15 @@ from django.db import models
|
|||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from src.typeclasses.models import (TypedObject, TagHandler, NickHandler,
|
||||
AliasHandler, AttributeHandler)
|
||||
from src.typeclasses.models import TypedObject, NickHandler
|
||||
from src.objects.manager import ObjectManager
|
||||
from src.players.models import PlayerDB
|
||||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
from src.commands import cmdhandler
|
||||
from src.scripts.scripthandler import ScriptHandler
|
||||
from src.utils import logger
|
||||
from src.utils.utils import (make_iter, to_str, to_unicode,
|
||||
variable_from_module, dbref, LazyLoadHandler)
|
||||
from src.utils.utils import (make_iter, to_str, to_unicode, lazy_property,
|
||||
variable_from_module, dbref)
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
|
@ -130,19 +129,18 @@ class ObjectDB(TypedObject):
|
|||
_typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
|
||||
_default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object"
|
||||
|
||||
# Add the object-specific handlers
|
||||
def __init__(self, *args, **kwargs):
|
||||
"Parent must be initialized first."
|
||||
TypedObject.__init__(self, *args, **kwargs)
|
||||
# handlers
|
||||
_SA(self, "cmdset", LazyLoadHandler(self, "cmdset", CmdSetHandler, True))
|
||||
_SA(self, "scripts", LazyLoadHandler(self, "scripts", ScriptHandler))
|
||||
_SA(self, "nicks", LazyLoadHandler(self, "nicks", NickHandler))
|
||||
#_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
||||
#_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
||||
#_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
||||
# make sure to sync the contents cache when initializing
|
||||
#_GA(self, "contents_update")()
|
||||
# lazy-load handlers
|
||||
@lazy_property
|
||||
def cmdset(self):
|
||||
return CmdSetHandler(self, True)
|
||||
|
||||
@lazy_property
|
||||
def scripts(self):
|
||||
return ScriptHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def nicks(self):
|
||||
return NickHandler(self)
|
||||
|
||||
def _at_db_player_postsave(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -23,13 +23,12 @@ from django.utils.encoding import smart_str
|
|||
|
||||
from src.players import manager
|
||||
from src.scripts.models import ScriptDB
|
||||
from src.typeclasses.models import (TypedObject, TagHandler, NickHandler,
|
||||
AliasHandler, AttributeHandler)
|
||||
from src.typeclasses.models import (TypedObject, NickHandler)
|
||||
from src.scripts.scripthandler import ScriptHandler
|
||||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
from src.commands import cmdhandler
|
||||
from src.utils import utils, logger
|
||||
from src.utils.utils import to_str, make_iter, LazyLoadHandler
|
||||
from src.utils.utils import to_str, make_iter, lazy_property
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
|
@ -111,15 +110,19 @@ class PlayerDB(TypedObject, AbstractUser):
|
|||
app_label = 'players'
|
||||
verbose_name = 'Player'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"Parent must be initiated first"
|
||||
TypedObject.__init__(self, *args, **kwargs)
|
||||
# handlers
|
||||
_SA(self, "cmdset", LazyLoadHandler(self, "cmdset", CmdSetHandler, True))
|
||||
_SA(self, "scripts", LazyLoadHandler(self, "scripts", ScriptHandler))
|
||||
_SA(self, "nicks", LazyLoadHandler(self, "nicks", NickHandler))
|
||||
#_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
||||
#_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
||||
# lazy-loading of handlers
|
||||
@lazy_property
|
||||
def cmdset(self):
|
||||
return CmdSetHandler(self, True)
|
||||
|
||||
@lazy_property
|
||||
def scripts(self):
|
||||
return ScriptHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def nicks(self):
|
||||
return NickHandler(self)
|
||||
|
||||
|
||||
# alias to the objs property
|
||||
def __characters_get(self):
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ Common examples of uses of Scripts:
|
|||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from src.typeclasses.models import TypedObject, TagHandler, AttributeHandler
|
||||
from src.typeclasses.models import TypedObject
|
||||
from src.scripts.manager import ScriptManager
|
||||
from src.utils.utils import dbref, to_str, LazyLoadHandler
|
||||
from src.utils.utils import dbref, to_str
|
||||
|
||||
__all__ = ("ScriptDB",)
|
||||
_GA = object.__getattribute__
|
||||
|
|
@ -108,13 +108,6 @@ class ScriptDB(TypedObject):
|
|||
"Define Django meta options"
|
||||
verbose_name = "Script"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ScriptDB, self).__init__(*args, **kwargs)
|
||||
_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
||||
_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
||||
#_SA(self, "aliases", AliasHandler(self))
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# ScriptDB class properties
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ from django.conf import settings
|
|||
#from src.scripts.models import ScriptDB
|
||||
from src.comms.models import ChannelDB
|
||||
from src.utils import logger, utils
|
||||
from src.utils.utils import make_iter, to_unicode, LazyLoadHandler
|
||||
from src.commands import cmdhandler, cmdsethandler
|
||||
from src.utils.utils import make_iter, to_unicode
|
||||
from src.commands.cmdhandler import cmdhandler
|
||||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
from src.server.session import Session
|
||||
|
||||
IDLE_COMMAND = settings.IDLE_COMMAND
|
||||
|
|
@ -49,7 +50,7 @@ class ServerSession(Session):
|
|||
self.puppet = None
|
||||
self.player = None
|
||||
self.cmdset_storage_string = ""
|
||||
self.cmdset = LazyLoadHandler(self, "cmdset", cmdsethandler.CmdSetHandler, True)
|
||||
self.cmdset = CmdSetHandler(self, True)
|
||||
|
||||
def __cmdset_storage_get(self):
|
||||
return [path.strip() for path in self.cmdset_storage_string.split(',')]
|
||||
|
|
@ -103,7 +104,7 @@ class ServerSession(Session):
|
|||
self.player.save()
|
||||
|
||||
# add the session-level cmdset
|
||||
self.cmdset = LazyLoadHandler(self, "cmdset", cmdsethandler.CmdSetHandler, True)
|
||||
self.cmdset = CmdSetHandler(self, True)
|
||||
|
||||
def at_disconnect(self):
|
||||
"""
|
||||
|
|
@ -198,7 +199,7 @@ class ServerSession(Session):
|
|||
else:
|
||||
text = self.player.nicks.nickreplace(text,
|
||||
categories=("inputline", "channels"), include_player=False)
|
||||
cmdhandler.cmdhandler(self, text, callertype="session", sessid=self.sessid)
|
||||
cmdhandler(self, text, callertype="session", sessid=self.sessid)
|
||||
self.update_session_counters()
|
||||
if "oob" in kwargs:
|
||||
# handle oob instructions
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import weakref
|
|||
from django.db import models
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from django.utils.encoding import smart_str
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
|
|
@ -48,7 +47,7 @@ from src.typeclasses import managers
|
|||
from src.locks.lockhandler import LockHandler
|
||||
from src.utils import logger
|
||||
from src.utils.utils import (
|
||||
make_iter, is_iter, to_str, inherits_from, LazyLoadHandler)
|
||||
make_iter, is_iter, to_str, inherits_from, lazy_property)
|
||||
from src.utils.dbserialize import to_pickle, from_pickle
|
||||
from src.utils.picklefield import PickledObjectField
|
||||
|
||||
|
|
@ -132,12 +131,9 @@ class Attribute(SharedMemoryModel):
|
|||
# Database manager
|
||||
objects = managers.AttributeManager()
|
||||
|
||||
# Lock handler self.locks
|
||||
def __init__(self, *args, **kwargs):
|
||||
"Initializes the parent first -important!"
|
||||
#SharedMemoryModel.__init__(self, *args, **kwargs)
|
||||
super(Attribute, self).__init__(*args, **kwargs)
|
||||
self.locks = LazyLoadHandler(self, "locks", LockHandler)
|
||||
@lazy_property
|
||||
def locks(self):
|
||||
return LockHandler(self)
|
||||
|
||||
class Meta:
|
||||
"Define Django meta options"
|
||||
|
|
@ -801,15 +797,33 @@ class TypedObject(SharedMemoryModel):
|
|||
def __init__(self, *args, **kwargs):
|
||||
"We must initialize the parent first - important!"
|
||||
super(TypedObject, self).__init__(*args, **kwargs)
|
||||
#SharedMemoryModel.__init__(self, *args, **kwargs)
|
||||
_SA(self, "dbobj", self) # this allows for self-reference
|
||||
_SA(self, "locks", LazyLoadHandler(self, "locks", LockHandler))
|
||||
_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
||||
_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
||||
_SA(self, "permissions", LazyLoadHandler(self, "permissions", PermissionHandler))
|
||||
_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
||||
_SA(self, "nattributes", NAttributeHandler(self))
|
||||
#_SA(self, "nattributes", LazyLoadHandler(self, "nattributes", NAttributeHandler))
|
||||
|
||||
# initialize all handlers in a lazy fashion
|
||||
@lazy_property
|
||||
def attributes(self):
|
||||
return AttributeHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def locks(self):
|
||||
return LockHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def tags(self):
|
||||
return TagHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def aliases(self):
|
||||
return AliasHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def permissions(self):
|
||||
return PermissionHandler(self)
|
||||
|
||||
@lazy_property
|
||||
def nattributes(self):
|
||||
return NAttributeHandler(self)
|
||||
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
|
|
@ -1276,13 +1290,10 @@ class TypedObject(SharedMemoryModel):
|
|||
if not TICKER_HANDLER:
|
||||
from src.scripts.tickerhandler import TICKER_HANDLER
|
||||
TICKER_HANDLER.remove(self) # removes objects' all ticker subscriptions
|
||||
if not isinstance(_GA(self, "permissions"), LazyLoadHandler):
|
||||
_GA(self, "permissions").clear()
|
||||
if not isinstance(_GA(self, "attributes"), LazyLoadHandler):
|
||||
_GA(self, "attributes").clear()
|
||||
if not isinstance(_GA(self, "aliases"), LazyLoadHandler):
|
||||
_GA(self, "aliases").clear()
|
||||
if hasattr(self, "nicks") and not isinstance(_GA(self, "nicks"), LazyLoadHandler):
|
||||
_GA(self, "permissions").clear()
|
||||
_GA(self, "attributes").clear()
|
||||
_GA(self, "aliases").clear()
|
||||
if hasattr(self, "nicks"):
|
||||
_GA(self, "nicks").clear()
|
||||
_SA(self, "_cached_typeclass", None)
|
||||
_GA(self, "flush_from_cache")()
|
||||
|
|
|
|||
|
|
@ -1060,67 +1060,38 @@ def deepsize(obj, max_depth=4):
|
|||
size = getsizeof(obj) + sum([p[1] for p in sizedict.values()])
|
||||
return size
|
||||
|
||||
# lazy load handlers
|
||||
|
||||
import weakref
|
||||
class LazyLoadHandler(object):
|
||||
# lazy load handler
|
||||
_missing = object()
|
||||
class lazy_property(object):
|
||||
"""
|
||||
Load handlers only when they are actually accessed
|
||||
Delays loading of property until first access. Credit goes to
|
||||
the Implementation in the werkzeug suite:
|
||||
http://werkzeug.pocoo.org/docs/utils/#werkzeug.utils.cached_property
|
||||
|
||||
This should be used as a decorator in a class and is in Evennia
|
||||
mainly used to lazy-load handlers:
|
||||
|
||||
@lazy_property
|
||||
def attributes(self):
|
||||
return AttributeHandler(self)
|
||||
|
||||
Once initialized, the AttributeHandler will be available
|
||||
as a property "attributes" on the object.
|
||||
|
||||
"""
|
||||
def __init__(self, obj, name, cls, *args):
|
||||
"""
|
||||
Set up a delayed load of a class. The 'name' must be named the
|
||||
same as the variable to which the LazyLoadHandler is assigned.
|
||||
"""
|
||||
_SA(self, "obj", weakref.ref(obj))
|
||||
_SA(self, "name", name)
|
||||
_SA(self, "cls", cls)
|
||||
_SA(self, "args", args)
|
||||
def __init__(self, func, name=None, doc=None):
|
||||
"Store all properties for now"
|
||||
self.__name__ = name or func.__name__
|
||||
self.__module__ = func.__module__
|
||||
self.__doc__ = doc or func.__doc__
|
||||
self.func = func
|
||||
|
||||
def _instantiate(self):
|
||||
"""
|
||||
Initialize handler as cls(obj, *args)
|
||||
"""
|
||||
obj = _GA(self, "obj")()
|
||||
instance = _GA(self, "cls")(weakref.proxy(obj), *_GA(self, "args"))
|
||||
_SA(obj, _GA(self, "name"), instance)
|
||||
return instance
|
||||
|
||||
def __getattribute__(self, name):
|
||||
"""
|
||||
Access means loading the handler
|
||||
"""
|
||||
return getattr(_GA(self, "_instantiate")(), name)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
"""
|
||||
Setting means loading the handler
|
||||
"""
|
||||
setattr(_GA(self, "_instantiate")(), name, value)
|
||||
|
||||
def __delattr__(self, name):
|
||||
"""
|
||||
Deleting also triggers loading of handler
|
||||
"""
|
||||
delattr(_GA(self, "_instantiate")(), name)
|
||||
|
||||
def __repr__(self):
|
||||
return repr(_GA(self, "_instantiate")())
|
||||
def __str__(self):
|
||||
return str(_GA(self, "_instantiate")())
|
||||
def __unicode__(self):
|
||||
return str(_GA(self, "_instantiate")())
|
||||
|
||||
class NonWeakLazyLoadHandler(LazyLoadHandler):
|
||||
"""
|
||||
Variation of LazyLoadHandler that does not
|
||||
create a weak reference when initiating.
|
||||
"""
|
||||
def _instantiate(self):
|
||||
"""
|
||||
Initialize handler as cls(obj, *args)
|
||||
"""
|
||||
obj = _GA(self, "obj")()
|
||||
instance = _GA(self, "cls")(obj, *_GA(self, "args"))
|
||||
_SA(obj, _GA(self, "name"), instance)
|
||||
return instance
|
||||
def __get__(self, obj, type=None):
|
||||
"Triggers initialization"
|
||||
if obj is None:
|
||||
return self
|
||||
value = obj.__dict__.get(self.__name__, _missing)
|
||||
if value is _missing:
|
||||
value = self.func(obj)
|
||||
obj.__dict__[self.__name__] = value
|
||||
return value
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue