# # Draws out the relationships between a series of nodes # in UDrawGraph format (UDrawGraph used to be called Da Vinci). # The resulting graph may be cyclic. The graph doesn't have to be # fully connected. class Traceable_Node: def __init__(self): pass def successors(self): return [] def label(self): return '' def Trace_UDG(root_node_list, alt_label=None, alt_successors=None): nodes_done = dict() edge_dir = '' #a("_DIR","inverse")' uid = [ 0 ] def Get_ID(): # unique id uid[ 0 ] += 1 return uid[ 0 ] def Do_Edge((node, label)): id = Get_ID() # TODO: use label parameter if ( nodes_done.has_key( node ) ): return 'e("a%u",[a("OBJECT","%s")%s],r("link%u"))' % (id, label, edge_dir, nodes_done[ node ]) else: return 'e("a%u",[a("OBJECT","%s")%s],%s)' % (id, label, edge_dir, ','.join(Do_Node(node))) def Do_Node(node): id = Get_ID() if ( nodes_done.has_key( node ) ): return [] nodes_done[ node ] = id out = [] if ( alt_successors == None ): l = node.successors() else: l = alt_successors(node) try: for record in l: if ( record == None ): pass elif ( type(record) == tuple ): out.append(Do_Edge(record)) else: out.append(Do_Edge((record, ''))) except TypeError, x: print 'l is', repr(l) raise x if ( alt_label == None ): label = node.label() else: label = alt_label(node) return ['l("link%u",n("c%u",[a("OBJECT","%s")],[%s]))' % (id, id, label, ','.join(out))] out = [] for node in root_node_list: out.extend(Do_Node(node)) return ''.join([ '[', ','.join(out), ']\n' ]) def Trace_UDG_File(fname, root_node_list, alt_label=None, alt_successors=None): f = file(fname, 'wt') f.write(Trace_UDG(root_node_list, alt_label, alt_successors)) f.close() def Trace_UDG_Test(fname): class Node(Traceable_Node): def __init__(self, l, s): self.s = s self.l = l def successors(self): return self.s def label(self): return self.l r = Node('rock', []) p = Node('paper', [r]) s = Node('scissors', [p]) r.s = [s] c = Node('core', []) a = Node('arm', [(c, 'pwnz')]) Trace_UDG_File(fname, [r, a]) if ( __name__ == "__main__" ): Trace_UDG_Test('test.daVinci')