| @@ -1,7 +1,12 @@ | |||||
| package dag | package dag | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "reflect" | |||||
| "strings" | |||||
| "gitlink.org.cn/cloudream/common/utils/lo2" | "gitlink.org.cn/cloudream/common/utils/lo2" | ||||
| "gitlink.org.cn/cloudream/common/utils/reflect2" | |||||
| ) | ) | ||||
| type Graph struct { | type Graph struct { | ||||
| @@ -55,6 +60,100 @@ func (g *Graph) NewValueVar() *ValueVar { | |||||
| return &ValueVar{} | return &ValueVar{} | ||||
| } | } | ||||
| func (g *Graph) Dump() string { | |||||
| nodeIDs := make(map[Node]int) | |||||
| for i, node := range g.Nodes { | |||||
| nodeIDs[node] = i | |||||
| } | |||||
| var sb strings.Builder | |||||
| for _, node := range g.Nodes { | |||||
| id, ok := nodeIDs[node] | |||||
| if !ok { | |||||
| id = len(nodeIDs) | |||||
| nodeIDs[node] = id | |||||
| } | |||||
| sb.WriteString(fmt.Sprintf("[%v]%v\n", id, nodeTypeName(node))) | |||||
| if node.InputStreams().Len() > 0 { | |||||
| sb.WriteString("SIn: ") | |||||
| for i, in := range node.InputStreams().Slots { | |||||
| if i > 0 { | |||||
| sb.WriteString(", ") | |||||
| } | |||||
| if in == nil { | |||||
| sb.WriteString("?") | |||||
| } else { | |||||
| sb.WriteString(fmt.Sprintf("%v", nodeIDs[in.Src])) | |||||
| } | |||||
| } | |||||
| sb.WriteString("\n") | |||||
| } | |||||
| if node.OutputStreams().Len() > 0 { | |||||
| sb.WriteString("SOut: ") | |||||
| for i, out := range node.OutputStreams().Slots { | |||||
| if i > 0 { | |||||
| sb.WriteString(", ") | |||||
| } | |||||
| sb.WriteString("(") | |||||
| for i2, dst := range out.Dst { | |||||
| if i2 > 0 { | |||||
| sb.WriteString(", ") | |||||
| } | |||||
| sb.WriteString(fmt.Sprintf("%v", nodeIDs[dst])) | |||||
| } | |||||
| sb.WriteString(")") | |||||
| } | |||||
| sb.WriteString("\n") | |||||
| } | |||||
| if node.InputValues().Len() > 0 { | |||||
| sb.WriteString("VIn: ") | |||||
| for i, in := range node.InputValues().Slots { | |||||
| if i > 0 { | |||||
| sb.WriteString(", ") | |||||
| } | |||||
| if in == nil { | |||||
| sb.WriteString("?") | |||||
| } else { | |||||
| sb.WriteString(fmt.Sprintf("%v", nodeIDs[in.Src])) | |||||
| } | |||||
| } | |||||
| sb.WriteString("\n") | |||||
| } | |||||
| if node.OutputValues().Len() > 0 { | |||||
| sb.WriteString("VOut: ") | |||||
| for i, out := range node.OutputValues().Slots { | |||||
| if i > 0 { | |||||
| sb.WriteString(", ") | |||||
| } | |||||
| sb.WriteString("(") | |||||
| for i2, dst := range out.Dst { | |||||
| if i2 > 0 { | |||||
| sb.WriteString(", ") | |||||
| } | |||||
| sb.WriteString(fmt.Sprintf("%v", nodeIDs[dst])) | |||||
| } | |||||
| sb.WriteString(")") | |||||
| } | |||||
| sb.WriteString("\n") | |||||
| } | |||||
| } | |||||
| return sb.String() | |||||
| } | |||||
| func nodeTypeName(node Node) string { | |||||
| typ := reflect2.TypeOfValue(node) | |||||
| for typ.Kind() == reflect.Ptr { | |||||
| typ = typ.Elem() | |||||
| } | |||||
| return typ.Name() | |||||
| } | |||||
| func AddNode[N Node](graph *Graph, typ N) N { | func AddNode[N Node](graph *Graph, typ N) N { | ||||
| graph.AddNode(typ) | graph.AddNode(typ) | ||||
| return typ | return typ | ||||