mirror of
https://github.com/evennia/evennia.git
synced 2026-04-01 13:37:17 +02:00
Restructured the way typeclasses are loaded. This makes it possible to run at_init() hooks at initiation also for objects without any custom cases for character/players. at_init() hooks are called only when an object is initiated. This means that a room's at_init() hook is only called when someone looks or enters it or a script operates on it, for example, rest of the time these objects are dormant, most efficiently.
This commit is contained in:
parent
0a1bcd36c2
commit
23cd9e31b1
14 changed files with 142 additions and 109 deletions
|
|
@ -47,9 +47,11 @@ def create_object(typeclass, key=None, location=None,
|
|||
from src.objects.objects import Object
|
||||
from src.objects.models import ObjectDB
|
||||
|
||||
if isinstance(typeclass, ObjectDB):
|
||||
if not typeclass:
|
||||
typeclass = settings.BASE_OBJECT_TYPECLASS
|
||||
elif isinstance(typeclass, ObjectDB):
|
||||
# this is already an objectdb instance, extract its typeclass
|
||||
typeclass = new_db_object.typeclass.path
|
||||
typeclass = typeclass.typeclass.path
|
||||
elif isinstance(typeclass, Object) or utils.inherits_from(typeclass, Object):
|
||||
# this is already an object typeclass, extract its path
|
||||
typeclass = typeclass.path
|
||||
|
|
@ -60,28 +62,22 @@ def create_object(typeclass, key=None, location=None,
|
|||
# assign the typeclass
|
||||
typeclass = utils.to_unicode(typeclass)
|
||||
new_db_object.typeclass_path = typeclass
|
||||
|
||||
# the name/key is often set later in the typeclass. This
|
||||
# is set here as a failsafe.
|
||||
if key:
|
||||
new_db_object.key = key
|
||||
else:
|
||||
new_db_object.key = "#%i" % new_db_object.id
|
||||
|
||||
# this will either load the typeclass or the default one
|
||||
typeclass = new_db_object.typeclass
|
||||
new_object = new_db_object.typeclass
|
||||
|
||||
if not object.__getattribute__(new_db_object, "is_typeclass")(typeclass, exact=True):
|
||||
# this will fail if we gave a typeclass as input and it still gave us a default
|
||||
SharedMemoryModel.delete(new_db_object)
|
||||
return None
|
||||
|
||||
# the name/key is often set later in the typeclass. This
|
||||
# is set here as a failsafe.
|
||||
if key:
|
||||
new_db_object.name = key
|
||||
else:
|
||||
dbref = new_db_object.id
|
||||
if typeclass and hasattr(typeclass, '__name__'):
|
||||
new_db_object.name = "%s%i" % (typeclass.__name__, dbref)
|
||||
else:
|
||||
new_db_object.name = "#%i" % dbref
|
||||
|
||||
# initialize an object of this typeclass.
|
||||
new_object = typeclass(new_db_object)
|
||||
|
||||
# from now on we can use the typeclass object
|
||||
# as if it was the database object.
|
||||
|
||||
|
|
@ -151,39 +147,37 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
|
|||
#print "in create_script", typeclass
|
||||
from src.scripts.models import ScriptDB
|
||||
|
||||
if isinstance(typeclass, ScriptDB):
|
||||
# this is already an objectdb instance, extract its typeclass
|
||||
if not typeclass:
|
||||
typeclass = settings.BASE_SCRIPT_TYPECLASS
|
||||
elif isinstance(typeclass, ScriptDB):
|
||||
# this is already an scriptdb instance, extract its typeclass
|
||||
typeclass = new_db_object.typeclass.path
|
||||
elif isinstance(typeclass, Script) or utils.inherits_from(typeclass, Script):
|
||||
# this is already an object typeclass, extract its path
|
||||
typeclass = typeclass.path
|
||||
# create new database object
|
||||
new_db_object = ScriptDB()
|
||||
|
||||
|
||||
# create new database script
|
||||
new_db_script = ScriptDB()
|
||||
|
||||
# assign the typeclass
|
||||
typeclass = utils.to_unicode(typeclass)
|
||||
new_db_object.typeclass_path = typeclass
|
||||
new_db_script.typeclass_path = typeclass
|
||||
|
||||
# the name/key is often set later in the typeclass. This
|
||||
# is set here as a failsafe.
|
||||
if key:
|
||||
new_db_script.key = key
|
||||
else:
|
||||
new_db_script.key = "#%i" % new_db_script.id
|
||||
|
||||
# this will either load the typeclass or the default one
|
||||
typeclass = new_db_object.typeclass
|
||||
new_script = new_db_script.typeclass
|
||||
|
||||
if not object.__getattribute__(new_db_object, "is_typeclass")(typeclass, exact=True):
|
||||
# this can happen if the default was loaded (due to
|
||||
# inability to load given typeclass), which we
|
||||
# don't accept during creation.
|
||||
SharedMemoryModel.delete(new_db_object)
|
||||
if not object.__getattribute__(new_db_script, "is_typeclass")(typeclass, exact=True):
|
||||
# this will fail if we gave a typeclass as input and it still gave us a default
|
||||
print "failure:", new_db_script, typeclass
|
||||
SharedMemoryModel.delete(new_db_script)
|
||||
return None
|
||||
|
||||
# the typeclass is initialized
|
||||
new_script = typeclass(new_db_object)
|
||||
|
||||
# store variables on the typeclass (which means
|
||||
# it's actually transparently stored on the db object)
|
||||
|
||||
if not key:
|
||||
if typeclass and hasattr(typeclass, '__name__'):
|
||||
new_script.key = "%s" % typeclass.__name__
|
||||
else:
|
||||
new_script.key = "#%i" % new_db_object.id
|
||||
|
||||
if obj:
|
||||
try:
|
||||
|
|
@ -206,6 +200,8 @@ def create_script(typeclass, key=None, obj=None, locks=None, autostart=True):
|
|||
# a new created script should usually be started.
|
||||
if autostart:
|
||||
new_script.start()
|
||||
|
||||
new_db_script.save()
|
||||
return new_script
|
||||
|
||||
#
|
||||
|
|
@ -345,22 +341,29 @@ def create_channel(key, aliases=None, desc=None,
|
|||
#
|
||||
|
||||
def create_player(name, email, password,
|
||||
permissions=None,
|
||||
create_character=True,
|
||||
location=None, typeclass=None, home=None,
|
||||
is_superuser=False, user=None, locks=None):
|
||||
user=None,
|
||||
typeclass=None,
|
||||
is_superuser=False,
|
||||
locks=None, permissions=None,
|
||||
create_character=True, character_typeclass=None,
|
||||
character_location=None, character_home=None):
|
||||
|
||||
|
||||
"""
|
||||
This creates a new player, handling the creation of the User
|
||||
object and its associated Player object. If create_character is
|
||||
object and its associated Player object.
|
||||
|
||||
If create_character is
|
||||
True, a game player object with the same name as the User/Player will
|
||||
also be created. Returns the new game character, or the Player obj if no
|
||||
also be created. Its typeclass and base properties can also be given.
|
||||
|
||||
Returns the new game character, or the Player obj if no
|
||||
character is created. For more info about the typeclass argument,
|
||||
see create_objects() above.
|
||||
|
||||
Note: if user is supplied, it will NOT be modified (args name, email,
|
||||
passw and is_superuser will be ignored). Change those properties
|
||||
explicitly instead.
|
||||
directly on the User instead.
|
||||
|
||||
If no permissions are given (None), the default permission group
|
||||
as defined in settings.PERMISSION_PLAYER_DEFAULT will be
|
||||
|
|
@ -368,16 +371,15 @@ def create_player(name, email, password,
|
|||
occur.
|
||||
|
||||
Concerning is_superuser:
|
||||
A superuser should have access to everything
|
||||
in the game and on the server/web interface. The very first user
|
||||
created in the database is always a superuser (that's using
|
||||
django's own creation, not this one).
|
||||
Usually only the server admin should need to be superuser, all
|
||||
other access levels can be handled with more fine-grained
|
||||
permissions or groups.
|
||||
|
||||
Since superuser overrules all permissions, we don't
|
||||
set any here.
|
||||
A superuser should have access to everything
|
||||
in the game and on the server/web interface. The very first user
|
||||
created in the database is always a superuser (that's using
|
||||
django's own creation, not this one).
|
||||
Usually only the server admin should need to be superuser, all
|
||||
other access levels can be handled with more fine-grained
|
||||
permissions or groups.
|
||||
Since superuser overrules all permissions, we don't
|
||||
set any in this case.
|
||||
|
||||
"""
|
||||
# The system should already have checked so the name/email
|
||||
|
|
@ -385,6 +387,7 @@ def create_player(name, email, password,
|
|||
# getting here.
|
||||
|
||||
from src.players.models import PlayerDB
|
||||
from src.players.player import Player
|
||||
|
||||
if user:
|
||||
new_user = user
|
||||
|
|
@ -394,9 +397,30 @@ def create_player(name, email, password,
|
|||
else:
|
||||
new_user = User.objects.create_user(name, email, password)
|
||||
|
||||
# create the associated Player for this User, and tie them together
|
||||
new_player = PlayerDB(db_key=name, user=new_user)
|
||||
new_player.save()
|
||||
if not typeclass:
|
||||
typeclass = settings.BASE_PLAYER_TYPECLASS
|
||||
elif isinstance(typeclass, PlayerDB):
|
||||
# this is already an objectdb instance, extract its typeclass
|
||||
typeclass = typeclass.typeclass.path
|
||||
elif isinstance(typeclass, Player) or utils.inherits_from(typeclass, Player):
|
||||
# this is already an object typeclass, extract its path
|
||||
typeclass = typeclass.path
|
||||
|
||||
# create new database object
|
||||
new_db_player = PlayerDB(db_key=name, user=new_user)
|
||||
new_db_player.save()
|
||||
|
||||
# assign the typeclass
|
||||
typeclass = utils.to_unicode(typeclass)
|
||||
new_db_player.typeclass_path = typeclass
|
||||
|
||||
# this will either load the typeclass or the default one
|
||||
new_player = new_db_player.typeclass
|
||||
|
||||
if not object.__getattribute__(new_db_player, "is_typeclass")(typeclass, exact=True):
|
||||
# this will fail if we gave a typeclass as input and it still gave us a default
|
||||
SharedMemoryModel.delete(new_db_player)
|
||||
return None
|
||||
|
||||
new_player.basetype_setup() # setup the basic locks and cmdset
|
||||
# call hook method (may override default permissions)
|
||||
|
|
@ -413,12 +437,12 @@ def create_player(name, email, password,
|
|||
|
||||
# create *in-game* 'player' object
|
||||
if create_character:
|
||||
if not typeclass:
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
if not character_typeclass:
|
||||
character_typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
# creating the object automatically links the player
|
||||
# and object together by player.obj <-> obj.player
|
||||
new_character = create_object(typeclass, name,
|
||||
location, home,
|
||||
new_character = create_object(character_typeclass, key=name,
|
||||
location=character_location, home=character_location,
|
||||
permissions=permissions,
|
||||
player=new_player)
|
||||
return new_character
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue