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()); .