func parseSignalGraph(text, context string) (job *PasteJob, ok bool) { xmlsg := backend.XmlSignalGraph{} _, xmlerr := xmlsg.Read([]byte(text)) if xmlerr != nil { return } for _, l := range xmlsg.Libraries { _, err := global.LibraryMgr().Access(l.Name) if err != nil { fmt.Printf("parseSignalGraph error: referenced library %s not accessible.\n", l.Name) return } } var njob *NewElementJob njob = NewElementJobNew(context, eSignalGraph) job = PasteJobNew() job.context = context job.newElements = append(job.newElements, njob) for _, xmln := range xmlsg.ProcessingNodes { _, validNodeType := freesp.GetNodeTypeByName(xmln.NType) if !validNodeType { fmt.Printf("parseSignalGraph error: node type %s not registered.\n", xmln.NType) return } njob = NewElementJobNew(context, eNode) njob.input[iNodeName] = xmln.NName njob.input[iNodeTypeSelect] = xmln.NType pj := PasteJobNew() pj.newElements = append(pj.newElements, njob) job.children = append(job.children, pj) } for _, xmln := range xmlsg.InputNodes { if len(xmln.OutPort) == 0 { fmt.Printf("parseSignalGraph error: input node has no outports.\n") return } njob = NewElementJobNew(context, eInputNode) njob.input[iInputNodeName] = xmln.NName njob.input[iInputTypeSelect] = xmln.OutPort[0].PType // TODO pj := PasteJobNew() pj.newElements = append(pj.newElements, njob) job.children = append(job.children, pj) } for _, xmln := range xmlsg.OutputNodes { if len(xmln.InPort) == 0 { fmt.Printf("parseSignalGraph error: output node has no inports.\n") return } njob = NewElementJobNew(context, eOutputNode) njob.input[iOutputNodeName] = xmln.NName njob.input[iOutputTypeSelect] = xmln.InPort[0].PType // TODO pj := PasteJobNew() pj.newElements = append(pj.newElements, njob) job.children = append(job.children, pj) } ok = true return }
func parseNode(text, context string, graph bh.SignalGraphTypeIf) (job *PasteJob, ok bool) { xmln := backend.XmlNode{} _, xmlerr := xmln.Read([]byte(text)) if xmlerr != nil { return } nodes := graph.Nodes() for true { valid := true for _, reg := range nodes { if reg.Name() == xmln.NName { valid = false } } if valid { break } xmln.NName = createNextNameCandidate(xmln.NName) } _, validType := freesp.GetNodeTypeByName(xmln.NType) var njob *NewElementJob switch { case validType: njob = NewElementJobNew(context, eNode) njob.input[iNodeName] = xmln.NName njob.input[iNodeTypeSelect] = xmln.NType case len(xmln.InPort) == 0: if len(xmln.OutPort) == 0 { fmt.Printf("parseNode error: no ports.\n") return } njob = NewElementJobNew(context, eInputNode) njob.input[iInputNodeName] = xmln.NName njob.input[iInputTypeSelect] = xmln.OutPort[0].PType // TODO case len(xmln.OutPort) == 0: njob = NewElementJobNew(context, eOutputNode) njob.input[iOutputNodeName] = xmln.NName njob.input[iOutputTypeSelect] = xmln.InPort[0].PType // TODO default: if !validType { fmt.Printf("parseNode error: node type %s not registered.\n", xmln.NType) return } // TODO: Create node type?? njob = NewElementJobNew(context, eNode) njob.input[iNodeName] = xmln.NName njob.input[iNodeTypeSelect] = xmln.NType } job = PasteJobNew() job.context = context job.newElements = append(job.newElements, njob) ok = true return }
func OutputNodeNew(name string, stypeName string, context bh.SignalGraphTypeIf) (ret *node, err error) { st, ok := freesp.GetSignalTypeByName(stypeName) if !ok { err = fmt.Errorf("InputNodeNew error: signaltype %s not defined", stypeName) return } ntName := createOutputNodeTypeName(stypeName) nt, ok := freesp.GetNodeTypeByName(ntName) if !ok { nt = NodeTypeNew(ntName, "") nt.(*nodeType).addInPort("", st) freesp.RegisterNodeType(nt) } return NodeNew(name, nt, context) }
func (t *signalGraphType) createNodeFromXml(xmln backend.XmlNode) (nd *node) { nName := xmln.NName ntName := xmln.NType if len(ntName) == 0 { ntName = createNodeTypeName(xmln) } nt, ok := freesp.GetNodeTypeByName(ntName) if !ok { nt = createNodeTypeFromXmlNode(xmln, ntName) } var err error nd, err = NodeNew(nName, nt, t) if err != nil { log.Fatal("signalGraphType.createNodeFromXml: TODO: error handling") } return }
func (l *library) AddNodeType(t bh.NodeTypeIf) error { nType, ok := freesp.GetNodeTypeByName(t.TypeName()) if ok { log.Printf(`library.AddNodeType: warning: adding existing node type definition %s (taking the existing one)`, t.TypeName()) } else { nType = t.(*nodeType) freesp.RegisterNodeType(nType) log.Println("library.AddNodeType: registered ", t.TypeName()) } for _, nt := range l.nodeTypes.NodeTypes() { if nt.TypeName() == t.TypeName() { return fmt.Errorf(`adding duplicate node type definition %s (ignored)`, t.TypeName()) } } l.nodeTypes.Append(nType) return nil }
func (g *signalGraphType) addOutputNodeFromPortType(p bh.PortTypeIf) { st := p.SignalType() ntName := createOutputNodeTypeName(st.TypeName()) nt, ok := freesp.GetNodeTypeByName(ntName) if !ok { nt = NodeTypeNew(ntName, "") nt.(*nodeType).addInPort("", st) freesp.RegisterNodeType(nt) } if len(nt.(*nodeType).inPorts.PortTypes()) == 0 { log.Fatal("signalGraphType.addOutputNodeFromNamedPortType: invalid output node type") } n, err := NodeNew(fmt.Sprintf("out-%s", p.Name()), nt, g) if err != nil { log.Fatal("signalGraphType.addOutputNodeFromPortType: TODO: error handling") } n.portlink = p err = g.addNode(n) if err != nil { log.Fatal("signalGraphType.addOutputNodeFromNamedPortType: AddNode failed:", err) } }
func (l *library) RemoveSignalType(st bh.SignalTypeIf) { for _, ntName := range freesp.GetRegisteredNodeTypes() { nt, ok := freesp.GetNodeTypeByName(ntName) if !ok { log.Panicf("library.RemoveSignalType internal error: node type %s\n", ntName) } for _, p := range nt.InPorts() { if p.SignalType().TypeName() == st.TypeName() { log.Printf(`library.RemoveSignalType warning: bh.SignalTypeIf %v is still in use\n`, st) return } } for _, p := range nt.OutPorts() { if p.SignalType().TypeName() == st.TypeName() { log.Printf(`library.RemoveSignalType warning: bh.SignalTypeIf %v is still in use\n`, st) return } } } SignalTypeDestroy(st) l.signalTypes.Remove(st) }
func parseNodeType(text, context string) (job *PasteJob, ok bool) { xmlnt := backend.XmlNodeType{} _, xmlerr := xmlnt.Read([]byte(text)) if xmlerr != nil { return } for true { _, exist := freesp.GetNodeTypeByName(xmlnt.TypeName) if !exist { break } xmlnt.TypeName = createNextNameCandidate(xmlnt.TypeName) } job = PasteJobNew() job.context = context ntjob := NewElementJobNew(context, eNodeType) ntjob.input[iTypeName] = xmlnt.TypeName job.newElements = append(job.newElements, ntjob) for _, p := range xmlnt.InPort { pj := PasteJobNew() j := NewElementJobNew("", ePortType) j.input[iPortName] = p.PName j.input[iSignalTypeSelect] = p.PType j.input[iDirection] = direction2string[gr.InPort] pj.newElements = append(pj.newElements, j) job.children = append(job.children, pj) } for _, p := range xmlnt.OutPort { pj := PasteJobNew() j := NewElementJobNew("", ePortType) j.input[iPortName] = p.PName j.input[iSignalTypeSelect] = p.PType j.input[iDirection] = direction2string[gr.OutPort] pj.newElements = append(pj.newElements, j) job.children = append(job.children, pj) } for _, impl := range xmlnt.Implementation { pj := PasteJobNew() j := NewElementJobNew("", eImplementation) j.input[iImplName] = impl.Name if impl.SignalGraph == nil { j.input[iImplementationType] = implType2string[bh.NodeTypeElement] } else { j.input[iImplementationType] = implType2string[bh.NodeTypeGraph] // nodes: (no need for i/o nodes linked to ports...) // TODO: how to set position? Info is in XML, but not in job... // Add IO nodes, handle them specifically ?? // TODO: Check names of IO nodes! We have a strong name scheming. Make consistent renaming (edges!) for _, n := range impl.SignalGraph[0].ProcessingNodes { nj := NewElementJobNew("", eNode) nj.input[iNodeName] = n.NName _, validNodeType := freesp.GetNodeTypeByName(n.NType) if !validNodeType { fmt.Printf("parseNodeType error: referenced node type %s not registered.\n", n.NType) return } nj.input[iNodeTypeSelect] = n.NType //nj.extra = fmt.Sprintf("%d|%d", n.Hint.X, n.Hint.Y) // TODO: SetModePosition ... //fmt.Printf("parseNodeType: fill hint of implementation graph node: %s\n", nj.extra) njob := PasteJobNew() njob.newElements = append(njob.newElements, nj) pj.children = append(pj.children, njob) } for _, e := range impl.SignalGraph[0].Connections { // TODO: put validity check of edges somewhere else... var fromPort *backend.XmlOutPort var toPort *backend.XmlInPort var p1, p2 bh.PortTypeIf for _, n := range impl.SignalGraph[0].InputNodes { if n.NName == e.From { for _, p := range n.OutPort { if p.PName == e.FromPort { fromPort = &p break } } break } } for _, n := range impl.SignalGraph[0].ProcessingNodes { if n.NName == e.From { nType, good := freesp.GetNodeTypeByName(n.NType) if !good { fmt.Printf("parseNodeType error: node type %s not registered.\n", n.NType) return } for _, p := range nType.OutPorts() { if p.Name() == e.FromPort { p1 = p break } } break } } for _, n := range impl.SignalGraph[0].ProcessingNodes { if n.NName == e.To { nType, good := freesp.GetNodeTypeByName(n.NType) if !good { fmt.Printf("parseNodeType error: node type %s not registered.\n", n.NType) return } for _, p := range nType.InPorts() { if p.Name() == e.ToPort { p2 = p break } } break } } for _, n := range impl.SignalGraph[0].OutputNodes { if n.NName == e.To { for _, p := range n.InPort { if p.PName == e.ToPort { toPort = &p break } } break } } if (fromPort == nil && p1 == nil) || (toPort == nil && p2 == nil) { fmt.Printf("parseNodeType error: invalid edge %v in implementation.\n", e) return } nj := NewElementJobNew("", eConnection) nj.input[iPortSelect] = fmt.Sprintf("%s/%s", e.To, e.ToPort) nj.extra = fmt.Sprintf("%s/%s", e.From, e.FromPort) njob := PasteJobNew() njob.newElements = append(njob.newElements, nj) pj.children = append(pj.children, njob) } } pj.newElements = append(pj.newElements, j) job.children = append(job.children, pj) } ok = true return }
func (j *NewElementJob) CreateObject(fts *models.FilesTreeStore) (ret tr.TreeElementIf, err error) { var parentObject tr.TreeElementIf parentObject, err = fts.GetObjectById(j.parentId) if err != nil { log.Fatal("NewElementJob.CreateObject error: referenced parentObject run away...") } switch j.elemType { case eNode, eInputNode, eOutputNode: var context bh.SignalGraphTypeIf switch parentObject.(type) { case bh.NodeIf: context = parentObject.(bh.NodeIf).Context() j.parentId = getParentId(j.parentId) case bh.SignalGraphIf: context = parentObject.(bh.SignalGraphIf).ItsType() case bh.SignalGraphTypeIf: context = parentObject.(bh.SignalGraphTypeIf) case bh.ImplementationIf: if parentObject.(bh.ImplementationIf).ImplementationType() == bh.NodeTypeGraph { context = parentObject.(bh.ImplementationIf).Graph() } else { log.Fatal("NewElementJob.CreateObject(eNode) error: parent implementation is no graph...") } default: log.Fatal("NewElementJob.CreateObject(eNode) error: referenced parentObject wrong type...") } if j.elemType == eNode { ntype, ok := freesp.GetNodeTypeByName(j.input[iNodeTypeSelect]) if !ok { log.Fatal("NewElementJob.CreateObject(eNode) error: referenced parentObject type wrong...") } ret, err = behaviour.NodeNew(j.input[iNodeName], ntype, context) } else if j.elemType == eInputNode { ret, err = behaviour.InputNodeNew(j.input[iInputNodeName], j.input[iInputTypeSelect], context) } else { ret, err = behaviour.OutputNodeNew(j.input[iOutputNodeName], j.input[iOutputTypeSelect], context) } if len(j.extra) > 0 { coords := strings.Split(j.extra, "|") var x, y int fmt.Sscanf(coords[0], "%d", &x) fmt.Sscanf(coords[1], "%d", &y) //pos := image.Point{x, y} //log.Printf("NewElementJob.CreateObject(eNode) setting position %s: %v\n", j.extra, pos) //ret.(bh.NodeIf).SetPosition(pos) // TODO: SetModePosition... } case eNodeType: var context string switch parentObject.(type) { case bh.NodeTypeIf: context = parentObject.(bh.NodeTypeIf).DefinedAt() j.parentId = getParentId(j.parentId) case bh.SignalTypeIf: j.parentId = getParentId(j.parentId) parentObject, err = fts.GetObjectById(j.parentId) context = parentObject.(bh.LibraryIf).Filename() case bh.LibraryIf: context = parentObject.(bh.LibraryIf).Filename() default: log.Fatal("NewElementJob.CreateObject(eNodeType) error: referenced parentObject wrong type...") } ret = behaviour.NodeTypeNew(j.input[iTypeName], context) case eConnection: switch parentObject.(type) { case bh.PortIf: case bh.SignalGraphTypeIf: fromTo := strings.Split(j.extra, "/") var n bh.NodeIf for _, n = range parentObject.(bh.SignalGraphTypeIf).Nodes() { if n.Name() == fromTo[0] { for _, parentObject = range n.OutPorts() { if parentObject.(bh.PortIf).Name() == fromTo[1] { break } } break } } if parentObject == nil { log.Fatalf("NewElementJob.CreateObject(eNodeType) error: no valid FROM port for edge job %v\n", j) } _ = parentObject.(bh.PortIf) case bh.ImplementationIf: fromTo := strings.Split(j.extra, "/") var n bh.NodeIf for _, n = range parentObject.(bh.ImplementationIf).Graph().Nodes() { if n.Name() == fromTo[0] { for _, parentObject = range n.OutPorts() { if parentObject.(bh.PortIf).Name() == fromTo[1] { break } } break } } if parentObject == nil { log.Fatalf("NewElementJob.CreateObject(eNodeType) error: no valid FROM port for edge job %v\n", j) } _ = parentObject.(bh.PortIf) default: log.Fatalf("NewElementJob.CreateObject(eConnection) error: referenced parentObject wrong type %T\n", parentObject) } ports := getMatchingPorts(fts, parentObject) for _, p := range ports { s := fmt.Sprintf("%s/%s", p.Node().Name(), p.Name()) if j.input[iPortSelect] == s { var from, to bh.PortIf if p.Direction() == gr.InPort { from = parentObject.(bh.PortIf) to = p } else { from = p to = parentObject.(bh.PortIf) } ret = behaviour.ConnectionNew(from, to) break } } case ePortType: switch parentObject.(type) { case bh.PortTypeIf: j.parentId = getParentId(j.parentId) case bh.NodeTypeIf: default: log.Fatal("NewElementJob.CreateObject(ePortType) error: referenced parentObject wrong type...") } _, ok := freesp.GetSignalTypeByName(j.input[iSignalTypeSelect]) if !ok { err = fmt.Errorf("NewElementJob.CreateObject(ePortType) error: referenced signal type wrong...") return } ret = behaviour.PortTypeNew(j.input[iPortName], j.input[iSignalTypeSelect], string2direction[j.input[iDirection]]) case eSignalType: switch parentObject.(type) { case bh.SignalTypeIf: j.parentId = getParentId(j.parentId) case bh.NodeTypeIf: j.parentId = getParentId(j.parentId) case bh.LibraryIf: default: log.Fatalf("NewElementJob.CreateObject(eSignalType) error: referenced parentObject wrong type %T\n", parentObject) } parentObject, err = fts.GetObjectById(j.parentId) if err != nil { log.Fatalf("NewElementJob.CreateObject(eSignalType) error: parent library object not found\n") } name := j.input[iSignalTypeName] cType := j.input[iCType] channelId := j.input[iChannelId] scope := string2scope[j.input[iScope]] mode := string2mode[j.input[iSignalMode]] ret, err = behaviour.SignalTypeNew(name, cType, channelId, scope, mode, parentObject.(bh.LibraryIf).Filename()) if err != nil { log.Printf("NewElementJob.CreateObject(eSignalType) error: SignalTypeNew failed: %s\n", err) return } case eImplementation: switch parentObject.(type) { case bh.ImplementationIf: j.parentId = getParentId(j.parentId) case bh.NodeTypeIf: default: log.Fatalf("NewElementJob.CreateObject(eSignalType) error: referenced parentObject wrong type %T\n", parentObject) } implType := string2implType[j.input[iImplementationType]] ret = behaviour.ImplementationNew(j.input[iImplName], implType, &global) case eArch: switch parentObject.(type) { case pf.ArchIf: j.parentId = getParentId(j.parentId) parentObject = parentObject.(pf.ArchIf).Platform() case pf.PlatformIf: default: log.Fatalf("NewElementJob.CreateObject(eArch) error: referenced parentObject wrong type %T\n", parentObject) } ret = platform.ArchNew(j.input[iArchName], parentObject.(pf.PlatformIf)) case eIOType: var p pf.PlatformIf switch parentObject.(type) { case pf.IOTypeIf: j.parentId = getParentId(j.parentId) p = parentObject.(pf.IOTypeIf).Platform() case pf.ArchIf: p = parentObject.(pf.ArchIf).Platform() default: log.Fatalf("NewElementJob.CreateObject(eIOType) error: referenced parentObject wrong type %T\n", parentObject) } ret, err = platform.IOTypeNew(j.input[iIOTypeName], gr.IOMode(j.input[iIOModeSelect]), p) case eProcess: switch parentObject.(type) { case pf.ProcessIf: j.parentId = getParentId(j.parentId) parentObject = parentObject.(pf.ProcessIf).Arch() case pf.ArchIf: default: log.Fatalf("NewElementJob.CreateObject(eProcess) error: referenced parentObject wrong type %T\n", parentObject) } ret = platform.ProcessNew(j.input[iProcessName], parentObject.(pf.ArchIf)) case eChannel: switch parentObject.(type) { case pf.ChannelIf: j.parentId = getParentId(j.parentId) parentObject = parentObject.(pf.ChannelIf).Process() case pf.ProcessIf: default: log.Fatalf("NewElementJob.CreateObject(eChannel) error: referenced parentObject wrong type %T\n", parentObject) } processes := getOtherProcesses(fts, parentObject) var p pf.ProcessIf for _, p = range processes { s := fmt.Sprintf("%s/%s", p.Arch().Name(), p.Name()) if s == j.input[iChannelLinkSelect] { break } } if p == nil { log.Fatalf("NewElementJob.CreateObject(eChannel) error: can't find chosen process\n", j.input[iChannelLinkSelect]) } ioType, ok := freesp.GetIOTypeByName(j.input[iIOTypeSelect]) if !ok { log.Fatalf("NewElementJob.CreateObject(eChannel) error: can't find chosen ioType\n", j.input[iIOTypeSelect]) } ret = platform.ChannelNew(string2direction[j.input[iChannelDirection]], ioType, parentObject.(pf.ProcessIf), j.input[iChannelLinkSelect]) default: log.Fatal("NewElementJob.CreateObject error: invalid elemType ", j.elemType) } return }