Added recursive loop-detection to the spawner. This should avoid accidentally creating infinite self-references in prototype structures.
This commit is contained in:
parent
b9c8c1695c
commit
fb8cf41b4e
1 changed files with 13 additions and 8 deletions
|
|
@ -84,16 +84,21 @@ _CREATE_OBJECT_KWARGS = ("key", "location", "home", "destination")
|
||||||
_handle_dbref = lambda inp: handle_dbref(inp, ObjectDB)
|
_handle_dbref = lambda inp: handle_dbref(inp, ObjectDB)
|
||||||
|
|
||||||
|
|
||||||
def _get_prototype(dic, prot, protparents):
|
def _get_prototype(dic, prot, protparents, visited):
|
||||||
"Recursively traverse a prototype dictionary, including multiple inheritance"
|
"""
|
||||||
|
Recursively traverse a prototype dictionary,
|
||||||
|
including multiple inheritance and self-reference
|
||||||
|
detection
|
||||||
|
"""
|
||||||
|
visited.append(id(dic))
|
||||||
if "prototype" in dic:
|
if "prototype" in dic:
|
||||||
# move backwards through the inheritance
|
# move backwards through the inheritance
|
||||||
prototypes = dic["prototype"]
|
for prototype in make_iter(dic["prototype"]):
|
||||||
if not hasattr(prototypes, "__iter__"):
|
if id(prototype) in visited:
|
||||||
prototypes = (prototypes,)
|
# a loop was detected. Don't self-reference.
|
||||||
for prototype in prototypes:
|
continue
|
||||||
# Build the prot dictionary in reverse order, overloading
|
# Build the prot dictionary in reverse order, overloading
|
||||||
new_prot = _get_prototype(protparents.get(prototype, {}), prot, protparents)
|
new_prot = _get_prototype(protparents.get(prototype, {}), prot, protparents, visited)
|
||||||
prot.update(new_prot)
|
prot.update(new_prot)
|
||||||
prot.update(dic)
|
prot.update(dic)
|
||||||
prot.pop("prototype", None) # we don't need this anymore
|
prot.pop("prototype", None) # we don't need this anymore
|
||||||
|
|
@ -181,7 +186,7 @@ def spawn(*prototypes, **kwargs):
|
||||||
objsparams = []
|
objsparams = []
|
||||||
for prototype in prototypes:
|
for prototype in prototypes:
|
||||||
|
|
||||||
prot = _get_prototype(prototype, {}, protparents)
|
prot = _get_prototype(prototype, {}, protparents, [])
|
||||||
if not prot:
|
if not prot:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue