Added an /update switch and a corresponding update command to the typeclass switch system, this allows to soft-update a typeclass and re-run only its at_object_creation, which seems to be the most common use-case.

This commit is contained in:
Griatch 2016-08-31 21:02:15 +02:00
parent 6e89c708d2
commit 80befa96b6
2 changed files with 29 additions and 14 deletions

View file

@ -1563,11 +1563,14 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
@type '' @type ''
@parent '' @parent ''
@swap - this is a shorthand for using /force/reset flags. @swap - this is a shorthand for using /force/reset flags.
@update - this is a shorthand for using the /force/reload flag.
Switch: Switch:
show - display the current typeclass of object show - display the current typeclass of object (default)
reset - clean out *all* the attributes on the object - update - *only* re-run at_object_creation on this object
basically making this a new clean object. meaning locks or other properties set later may remain.
reset - clean out *all* the attributes and properties on the
object - basically making this a new clean object.
force - change to the typeclass also if the object force - change to the typeclass also if the object
already has a typeclass of the same name. already has a typeclass of the same name.
Example: Example:
@ -1580,7 +1583,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
of the new typeclass will be run on the object. If you have of the new typeclass will be run on the object. If you have
clashing properties on the old class, use /reset. By default you clashing properties on the old class, use /reset. By default you
are protected from changing to a typeclass of the same name as the are protected from changing to a typeclass of the same name as the
one you already have, use /force to override this protection. one you already have - use /force to override this protection.
The given typeclass must be identified by its location using The given typeclass must be identified by its location using
python dot-notation pointing to the correct module and class. If python dot-notation pointing to the correct module and class. If
@ -1592,7 +1595,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
""" """
key = "@typeclass" key = "@typeclass"
aliases = ["@type", "@parent", "@swap"] aliases = ["@type", "@parent", "@swap", "@update"]
locks = "cmd:perm(typeclass) or perm(Builders)" locks = "cmd:perm(typeclass) or perm(Builders)"
help_category = "Building" help_category = "Building"
@ -1624,6 +1627,9 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
if self.cmdstring == "@swap": if self.cmdstring == "@swap":
self.switches.append("force") self.switches.append("force")
self.switches.append("reset") self.switches.append("reset")
elif self.cmdstring == "@update":
self.switches.append("force")
self.switches.append("update")
if not obj.access(caller, 'edit'): if not obj.access(caller, 'edit'):
caller.msg("You are not allowed to do that.") caller.msg("You are not allowed to do that.")
@ -1637,11 +1643,14 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
if is_same and not 'force' in self.switches: if is_same and not 'force' in self.switches:
string = "%s already has the typeclass '%s'. Use /force to override." % (obj.name, new_typeclass) string = "%s already has the typeclass '%s'. Use /force to override." % (obj.name, new_typeclass)
else: else:
update = "update" in self.switches
reset = "reset" in self.switches reset = "reset" in self.switches
hooks = "at_object_creation" if update else "all"
old_typeclass_path = obj.typeclass_path old_typeclass_path = obj.typeclass_path
# we let this raise exception if needed # we let this raise exception if needed
obj.swap_typeclass(new_typeclass, clean_attributes=reset, clean_cmdsets=reset) obj.swap_typeclass(new_typeclass, clean_attributes=reset,
clean_cmdsets=reset, run_start_hooks=hooks)
if is_same: if is_same:
string = "%s updated its existing typeclass (%s).\n" % (obj.name, obj.path) string = "%s updated its existing typeclass (%s).\n" % (obj.name, obj.path)
@ -1649,7 +1658,10 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
string = "%s changed typeclass from %s to %s.\n" % (obj.name, string = "%s changed typeclass from %s to %s.\n" % (obj.name,
old_typeclass_path, old_typeclass_path,
obj.typeclass_path) obj.typeclass_path)
string += "Creation hooks were run." if update:
string += "Only the at_object_creation hook was run (update mode)."
else:
string += "All object creation hooks were run."
if reset: if reset:
string += " All old attributes where deleted before the swap." string += " All old attributes where deleted before the swap."
else: else:

View file

@ -414,7 +414,7 @@ class TypedObject(SharedMemoryModel):
return any(hasattr(cls, "path") and cls.path in typeclass for cls in self.__class__.mro()) return any(hasattr(cls, "path") and cls.path in typeclass for cls in self.__class__.mro())
def swap_typeclass(self, new_typeclass, clean_attributes=False, def swap_typeclass(self, new_typeclass, clean_attributes=False,
run_start_hooks=True, no_default=True, clean_cmdsets=False): run_start_hooks="all", no_default=True, clean_cmdsets=False):
""" """
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.
@ -438,16 +438,16 @@ class TypedObject(SharedMemoryModel):
sure nothing in the new typeclass clashes with the old sure nothing in the new typeclass clashes with the old
one. If you supply a list, only those named attributes one. If you supply a list, only those named attributes
will be cleared. will be cleared.
run_start_hooks (bool, optional): Trigger the start hooks run_start_hooks (str or None, optional): This is either None,
of the object, as if it was created for the first time. to not run any hooks, "all" to run all hooks defined by
at_first_start, or a string giving the name of the hook
to run (for example 'at_object_creation'). This will
always be called without arguments.
no_default (bool, optiona): If set, the swapper will not no_default (bool, optiona): If set, the swapper will not
allow for swapping to a default typeclass in case the allow for swapping to a default typeclass in case the
given one fails for some reason. Instead the old one will given one fails for some reason. Instead the old one will
be preserved. be preserved.
clean_cmdsets (bool, optional): Delete all cmdsets on the object. clean_cmdsets (bool, optional): Delete all cmdsets on the object.
Returns:
result (bool): True/False depending on if the swap worked
or not.
""" """
@ -483,9 +483,12 @@ class TypedObject(SharedMemoryModel):
self.cmdset.clear() self.cmdset.clear()
self.cmdset.remove_default() self.cmdset.remove_default()
if run_start_hooks: if run_start_hooks == 'all':
# fake this call to mimic the first save # fake this call to mimic the first save
self.at_first_save() self.at_first_save()
elif run_start_hooks:
# a custom hook-name to call.
getattr(self, run_start_hooks)()
# #
# Lock / permission methods # Lock / permission methods