Added functionality to TypedObject.swap_typeclass to handle various typeclasses safely. Resolves #390.

This commit is contained in:
Griatch 2014-04-21 11:52:48 +02:00
parent 8ad2c18524
commit 12dd202795

View file

@ -44,7 +44,7 @@ from src.server.models import ServerConfig
from src.typeclasses import managers from src.typeclasses import managers
from src.locks.lockhandler import LockHandler from src.locks.lockhandler import LockHandler
from src.utils import logger from src.utils import logger
from src.utils.utils import make_iter, is_iter, to_str from src.utils.utils import make_iter, is_iter, to_str, inherits_from
from src.utils.dbserialize import to_pickle, from_pickle from src.utils.dbserialize import to_pickle, from_pickle
from src.utils.picklefield import PickledObjectField from src.utils.picklefield import PickledObjectField
@ -1014,7 +1014,8 @@ class TypedObject(SharedMemoryModel):
# Object manipulation methods # Object manipulation methods
# #
def swap_typeclass(self, new_typeclass, clean_attributes=False, no_default=True): def swap_typeclass(self, new_typeclass, clean_attributes=False,
run_start_hooks=True, no_default=True):
""" """
This performs an in-situ swap of the typeclass. This means This performs an in-situ swap of the typeclass. This means
that in-game, this object will suddenly be something else. that in-game, this object will suddenly be something else.
@ -1057,6 +1058,13 @@ class TypedObject(SharedMemoryModel):
# Try to set the new path # Try to set the new path
# this will automatically save to database # this will automatically save to database
old_typeclass_path = self.typeclass_path old_typeclass_path = self.typeclass_path
if inherits_from(self, "src.scripts.models.ScriptDB"):
if self.interval > 0:
raise RuntimeError("Cannot use swap_typeclass on time-dependent " \
"Script '%s'.\nStop and start a new Script of the " \
"right type instead." % self.key)
_SA(self, "typeclass_path", new_typeclass.strip()) _SA(self, "typeclass_path", new_typeclass.strip())
# this will automatically use a default class if # this will automatically use a default class if
# there is an error with the given typeclass. # there is an error with the given typeclass.
@ -1082,9 +1090,21 @@ class TypedObject(SharedMemoryModel):
for nattr in self.ndb.all: for nattr in self.ndb.all:
del nattr del nattr
# run hooks for this new typeclass if run_start_hooks:
new_typeclass.basetype_setup() # run hooks for this new typeclass
new_typeclass.at_object_creation() if inherits_from(self, "src.objects.models.ObjectDB"):
new_typeclass.basetype_setup()
new_typeclass.at_object_creation()
elif inherits_from(self, "src.players.models.PlayerDB"):
new_typeclass.basetype_setup()
new_typeclass.at_player_creation()
elif inherits_from(self, "src.scripts.models.ScriptDB"):
new_typeclass.at_script_creation()
new_typeclass.start()
elif inherits_from(self, "src.channels.models.Channel"):
# channels do no initial setup
pass
return True return True
# #