parent $utilities
object $tree
var $root dbref 'tree
var $root child_index 2
var $root fertile 1
var $root manager $tree
var $root owned [$tree]
var $root owners [$]
var $root writable []
var $root readable ['parameters, 'methods, 'code]
var $root inited 1
var $tree parents_by_tree 0
var $tree children_by_tree 0
method add_as_child
arg tree;
if (!children_by_tree)
children_by_tree = #[];
children_by_tree = children_by_tree.add_elem(tree, sender());
return 1;
.
method add_as_parent
arg tree;
if (!parents_by_tree)
parents_by_tree = #[];
parents_by_tree = parents_by_tree.add_elem(tree, sender());
return 1;
.
method add_child_to_tree
arg tree, child;
.perms(sender(), 'writers);
if (type(tree) != 'symbol)
throw(~type, "tree should be given as a symbol.");
if (tree == 'inheritance)
return .add_child(child);
if (type(child) != 'dbref)
throw(~type, "child should be given as a dbref.");
if (child in ((| children_by_tree[tree] |) || []))
throw(~type, ((child.dbref()) + " is already a child in tree ") + tree);
if (parent in (.ancestors_by_tree(tree)))
throw(~type, ((parent.dbref()) + " is already an ancestor in tree ") + tree);
if (!(child.add_as_child(tree)))
throw(~refuse, "child refuses to be child.");
children_by_tree = children_by_tree.add_elem(tree, child);
.
method add_parent_to_tree
arg tree, parent;
.perms(sender(), 'writers);
if (type(tree) != 'symbol)
throw(~type, "tree should be given as a symbol.");
if (tree == 'inheritance)
return .add_parent(parent);
if (type(parent) != 'dbref)
throw(~type, "parent should be given as a dbref.");
if (parent in ((| parents_by_tree[tree] |) || []))
throw(~type, ((parent.dbref()) + " is already a parent in tree ") + tree);
catch ~tree {
if (parent in (.ancestors_by_tree(tree)))
throw(~type, ((parent.dbref()) + " is already an ancestor in tree ") + tree);
}
if (!(parent.add_as_child(tree)))
throw(~refuse, "parent refuses to be parent.");
parents_by_tree = parents_by_tree.add_elem(tree, parent);
.
method children_by_tree
arg [tree];
if (tree) {
if ((tree[1]) == 'inheritance)
return .children();
catch ~keynf {
return children_by_tree[tree[1]];
} with handler {
throw(~treenf, "No children in tree" + tostr(tree[1]));
}
} else {
return children_by_tree;
}
.
method ancestors_by_tree
arg tree;
var a, par, anc;
if (type(tree) != 'symbol)
throw(~type, "tree should be given as a symbol.");
if (tree == 'inheritance)
return .ancestors();
if (!(tree in dict_keys(parents_by_tree)))
throw(~tree, "not part of tree " + tostr(tree));
par = parents_by_tree[tree];
anc = [];
while (par) {
anc = setadd(anc, par[1]);
par = [@par, @(par[1]).parents_by_tree(tree)];
}
return anc;
.
method del_child_from_tree
arg tree, child;
.perms(sender(), 'writers);
if (type(tree) != 'symbol)
throw(~type, "tree should be given as a symbol.");
if (tree == 'inheritance)
return .del_child(child);
if (type(child) != 'dbref)
throw(~type, "child should be given as a dbref.");
if (!(child in ((| children_by_tree[tree] |) || [])))
throw(~type, ((child.dbref()) + " is not a child in tree ") + tostr(tree));
child.del_as_parent(tree);
children_by_tree = children_by_tree.del_elem(tree, child);
.
method del_parent_from_tree
arg tree, parent;
.perms(sender(), 'writers);
if (type(tree) != 'symbol)
throw(~type, "tree should be given as a symbol.");
if (tree == 'inheritance)
return .del_parent(parent);
if (type(parent) != 'dbref)
throw(~type, "parent should be given as a dbref.");
if (!(parent in ((| parents_by_tree[tree] |) || [])))
throw(~type, ((parent.dbref()) + " is not a parent in tree ") + tostr(tree));
parent.del_as_child(tree);
parents_by_tree = parents_by_tree.del_elem(tree, parent);
.
method parents_by_tree
arg [tree];
if (tree) {
if ((tree[1]) == 'inheritance)
return .parents();
catch ~keynf, ~type {
return parents_by_tree[tree[1]];
} with handler {
throw(~tree, "Not parents in tree " + tostr(tree[1]));
}
} else {
return parents_by_tree;
}
.
method descendents_by_tree
arg tree;
var a, par, anc;
if (type(tree) != 'symbol)
throw(~type, "tree should be given as a symbol.");
if (tree == 'inheritance)
return .descendents();
if (!(tree in dict_keys(children_by_tree)))
throw(~tree, "not part of tree " + tostr(tree));
par = children_by_tree[tree];
anc = [];
while (par) {
anc = setadd(anc, par[1]);
par = [@par, @(par[1]).children_by_tree(tree)];
}
return anc;
.
method init_tree
parents_by_tree = #[];
children_by_tree = #[];
.
method uninit_tree
parents_by_tree = 0;
children_by_tree = 0;
.
method del_as_child
arg tree;
.debug(children_by_tree, tree);
children_by_tree = children_by_tree.del_elem(tree, sender());
.
method del_as_parent
arg tree;
parents_by_tree = parents_by_tree.del_elem(tree, sender());
.