func (p *port) Connection(c bh.PortIf) bh.ConnectionIf { _, ok, index := p.connected.Find(c.Node().Name(), c.Name()) if !ok { log.Fatalf("port.bh.ConnectionIf error: port %v not in connected list of port %v\n", c, p) } return p.conn[index] }
func (t *signalGraphType) AddNewObject(tree tr.TreeIf, cursor tr.Cursor, obj tr.TreeElementIf) (newCursor tr.Cursor, err error) { switch obj.(type) { case bh.NodeIf: // TODO: Check if IO node and exists: copy position only and return n := obj.(bh.NodeIf) err = t.AddNode(n) if err != nil { err = fmt.Errorf("signalGraphType.AddNewObject error: %s", err) nt := n.ItsType().(*nodeType) if nt != nil { ok, _ := nt.instances.Find(n) if ok { nt.instances.Remove(n) } } return } newCursor = t.treeAddNewObject(tree, cursor, n) parent := tree.Object(cursor) switch parent.(type) { case bh.SignalGraphIf: case bh.ImplementationIf: // propagate new node to all instances of embracing type pCursor := tree.Parent(cursor) nt := tree.Object(pCursor) for _, nn := range nt.(bh.NodeTypeIf).Instances() { nCursor := tree.Cursor(nn) tCursor := tree.CursorAt(nCursor, parent) tCursor.Position = cursor.Position t.treeAddNewObject(tree, tCursor, n) } default: log.Fatalf("signalGraphType.AddNewObject error: wrong parent type %T: %v\n", parent, parent) } case bh.ConnectionIf: conn := obj.(bh.ConnectionIf) var n bh.NodeIf var p bh.PortIf for _, n = range t.Nodes() { if n.Name() == conn.From().Node().Name() { nCursor := tree.CursorAt(cursor, n) for _, p = range n.OutPorts() { if conn.From().Name() == p.Name() { pCursor := tree.CursorAt(nCursor, p) return p.AddNewObject(tree, pCursor, obj) } } } } default: log.Fatalf("signalGraphType.AddNewObject error: wrong type %t: %v\n", obj, obj) } return }
func (p *port) RemoveConnection(c bh.PortIf) { _, ok, index := p.connected.Find(c.Node().Name(), c.Name()) if !ok { log.Fatalf("port.bh.ConnectionIf error: port %v not in connected list of port %v\n", c, p) } p.connected.Remove(c) for index++; index < len(p.conn); index++ { p.conn[index-1] = p.conn[index] } p.conn = p.conn[:len(p.conn)-1] }
func (p *port) RemoveObject(tree tr.TreeIf, cursor tr.Cursor) (removed []tr.IdWithObject) { parent := tree.Parent(cursor) if p != tree.Object(parent) { log.Fatal("port.RemoveObject error: not removing child of mine.") } obj := tree.Object(cursor) switch obj.(type) { case bh.ConnectionIf: conn := obj.(bh.ConnectionIf) var thisPort, otherPort bh.PortIf if p.Direction() == gr.InPort { otherPort = conn.From() thisPort = conn.To() if p != thisPort { log.Fatal("port.RemoveObject error: invalid connection ", conn) } } else { otherPort = conn.To() thisPort = conn.From() if p != thisPort { log.Fatal("port.RemoveObject error: invalid connection ", conn) } } contextCursor := tree.Parent(tree.Parent(tree.Parent(cursor))) removed = p.treeRemoveObject(tree, cursor, conn, otherPort) context := tree.Object(contextCursor) switch context.(type) { case bh.SignalGraphIf: case bh.ImplementationIf: // propagate removed edge to all instances of embracing type nt := tree.Object(tree.Parent(contextCursor)) for _, nn := range nt.(bh.NodeTypeIf).Instances() { nCursor := tree.Cursor(nn) tCursor := tree.CursorAt(nCursor, context) pCursor := tree.CursorAt(tCursor, p) cCursor := tree.CursorAt(pCursor, conn) p.treeRemoveObject(tree, cCursor, conn, otherPort) } default: log.Fatalf("port.RemoveObject error: wrong context type %T: %v\n", context, context) } p.RemoveConnection(otherPort) otherPort.RemoveConnection(p) default: log.Fatalf("bh.PortIf.RemoveObject error: invalid type %T: %v\n", obj, obj) } return }
// Remove object mirrored in all instance node type func (t *nodeType) treeRemoveInstObject(tree tr.TreeIf, cursor tr.Cursor) (removed []tr.IdWithObject) { parentId := tree.Parent(cursor) if t != tree.Object(parentId) { log.Fatal("nodeType.RemoveObject error: not removing child of mine.") } obj := tree.Object(cursor) switch obj.(type) { case bh.ImplementationIf: for _, n := range t.Instances() { nCursor := tree.Cursor(n) tCursor := tree.CursorAt(nCursor, t) iCursor := tree.CursorAt(tCursor, obj) iCursor.Position = cursor.Position tree.Remove(iCursor) } case bh.PortTypeIf: nt := obj.(bh.PortTypeIf) for _, n := range t.Instances() { var p bh.PortIf var list []bh.PortIf nCursor := tree.Cursor(n) if nt.Direction() == gr.InPort { list = n.InPorts() } else { list = n.OutPorts() } for _, p = range list { if p.Name() == nt.Name() { break } } _ = p.(*port) pCursor := tree.CursorAt(nCursor, p) prefix, index := tree.Remove(pCursor) removed = append(removed, tr.IdWithObject{prefix, index, p}) tCursor := tree.CursorAt(nCursor, obj) del := t.treeRemoveObject(tree, tCursor) for _, d := range del { removed = append(removed, d) } tree.Remove(tCursor) } default: log.Fatalf("nodeType.RemoveObject error: invalid type %T\n", obj) } return }
func (t *nodeType) treeInstObject(tree tr.TreeIf, cursor tr.Cursor, obj tr.TreeElementIf) (newCursor tr.Cursor) { switch obj.(type) { case bh.ImplementationIf: impl := obj.(bh.ImplementationIf) // update all instance nodes in the tree with new implementation for _, n := range t.Instances() { nCursor := tree.Cursor(n) tCursor := tree.CursorAt(nCursor, t) tCursor.Position = len(t.Implementation()) - 1 newICursor := tree.Insert(tCursor) impl.AddToTree(tree, newICursor) } case bh.PortTypeIf: pt := obj.(bh.PortTypeIf) // update all instance nodes in the tree with new port for _, n := range t.Instances() { var p bh.PortIf var ok bool if pt.Direction() == gr.InPort { p, ok, _ = n.(*node).inPort.Find(n.Name(), pt.Name()) } else { p, ok, _ = n.(*node).outPort.Find(n.Name(), pt.Name()) } if !ok { log.Fatalf("nodeType.treeInstObject error: port %s not found.\n", pt.Name()) } nCursor := tree.Cursor(n) // Insert new port at the same position as in the type: // Need to deal with implementations in type VS type in node if cursor.Position >= 0 { nCursor.Position = cursor.Position - len(t.Implementation()) + 1 } newNCursor := tree.Insert(nCursor) p.AddToTree(tree, newNCursor) // Update mirrored type in node: tCursor := tree.CursorAt(nCursor, t) tCursor.Position = cursor.Position t.treeNewObject(tree, tCursor, obj) } default: log.Fatalf("nodeType.AddNewObject error: invalid type %T\n", obj) } return }
// For connection only: lookup matching ports to connect. func getMatchingPorts(fts *models.FilesTreeStore, object tr.TreeElementIf) (ret []bh.PortIf) { var thisPort bh.PortIf switch object.(type) { case bh.PortIf: thisPort = object.(bh.PortIf) case bh.ConnectionIf: log.Fatal("getMatchingPorts error: expecting Port, not Connection") default: log.Fatal("getMatchingPorts error: expecting Port") } thisNode := thisPort.Node() graph := thisNode.Context() for _, n := range graph.Nodes() { var ports []bh.PortIf if thisPort.Direction() == gr.InPort { ports = n.OutPorts() } else { ports = n.InPorts() } for _, p := range ports { if p.SignalType().TypeName() == thisPort.SignalType().TypeName() { ret = append(ret, p) } } } return }
func (l *portList) Remove(p bh.PortIf) { var i int for i = range l.ports { if p.Node().Name() == l.ports[i].Node().Name() && p.Name() == l.ports[i].Name() { break } } if i >= len(l.ports) { for _, v := range l.ports { log.Printf("portList.RemovePort have bh.PortIf %v\n", v) } log.Fatalf("portList.RemovePort error: bh.PortIf %v not in this list\n", p) } for i++; i < len(l.ports); i++ { l.ports[i-1] = l.ports[i] } l.ports = l.ports[:len(l.ports)-1] }
func PortNew(box image.Rectangle, userObj bh.PortIf) *Port { var config DrawConfig if userObj.Direction() == gr.InPort { config = DrawConfig{ColorInit(ColorOption(InputPort)), ColorInit(ColorOption(HighlightInPort)), ColorInit(ColorOption(SelectInPort)), ColorInit(ColorOption(BoxFrame)), Color{}, image.Point{}} } else { config = DrawConfig{ColorInit(ColorOption(OutputPort)), ColorInit(ColorOption(HighlightOutPort)), ColorInit(ColorOption(SelectOutPort)), ColorInit(ColorOption(BoxFrame)), Color{}, image.Point{}} } return &Port{SelectableBoxInit(box, config), userObj} }
func (p *port) AddNewObject(tree tr.TreeIf, cursor tr.Cursor, obj tr.TreeElementIf) (newCursor tr.Cursor, err error) { switch obj.(type) { case bh.ConnectionIf: conn := obj.(bh.ConnectionIf) var thisPort, otherPort bh.PortIf if p.Direction() == gr.InPort { otherPort = conn.From() thisPort = conn.To() } else { otherPort = conn.To() thisPort = conn.From() } if p != thisPort { log.Println("p =", p) log.Println("thisPort =", thisPort) log.Fatal("port.AddNewObject error: invalid connection ", conn) } sgt := thisPort.Node().Context() if sgt != otherPort.Node().Context() { log.Fatal("port.AddNewObject error: nodes have different context: ", conn) } contextCursor := tree.Parent(tree.Parent(cursor)) thisPort.AddConnection(conn) newCursor = p.treeAddNewObject(tree, cursor, conn, otherPort) context := tree.Object(contextCursor) switch context.(type) { case bh.SignalGraphIf: case bh.ImplementationIf: // propagate new edge to all instances of embracing type nt := tree.Object(tree.Parent(contextCursor)) for _, nn := range nt.(bh.NodeTypeIf).Instances() { nCursor := tree.Cursor(nn) tCursor := tree.CursorAt(nCursor, context) pCursor := tree.CursorAt(tCursor, p) pCursor.Position = cursor.Position p.treeAddNewObject(tree, pCursor, conn, otherPort) } default: log.Fatalf("port.AddNewObject error: wrong context type %T: %v\n", context, context) } default: log.Fatalf("port.AddNewObject error: invalid type %T: %v\n", obj, obj) } return }
func portConnect(port1 bh.PortIf, c *connection) error { p1 := port1.(*port) var port2 bh.PortIf var p2 *port if c.from.(*port) == p1 { port2 = c.to } else if c.to.(*port) == p1 { port2 = c.from } p2 = port2.(*port) if port1.SignalType().TypeName() != port2.SignalType().TypeName() { return fmt.Errorf("type mismatch") } if port1.Direction() == port2.Direction() { return fmt.Errorf("direction mismatch") } p1.connected.Append(port2.(*port)) p1.conn = append(p1.conn, c) p2.connected.Append(port1.(*port)) p2.conn = append(p2.conn, c) return nil }
func updateConnections(p bh.PortIf, fts *models.FilesTreeStore) { nodeCursor := fts.Cursor(p.Node()) portCursor := fts.CursorAt(nodeCursor, p) for _, c := range p.Connections() { conn := p.Connection(c) connCursor := fts.CursorAt(portCursor, conn) otherNode := c.Node() otherNodeCursor := fts.Cursor(otherNode) otherPortCursor := fts.CursorAt(otherNodeCursor, c) otherConnCursor := fts.CursorAt(otherPortCursor, conn) connText := fmt.Sprintf("%s/%s -> %s/%s", conn.From().Node().Name(), conn.From().Name(), conn.To().Node().Name(), conn.To().Name()) fts.SetValueById(connCursor.Path, connText) fts.SetValueById(otherConnCursor.Path, connText) } }
func (n *Node) SelectPort(port bh.PortIf) { var index int if port.Direction() == gr.InPort { index = n.InPortIndex(port.Name()) } else { index = n.OutPortIndex(port.Name()) if index >= 0 { index += n.NumInPorts() } } for i, p := range n.ports { if i == index { p.Select() } else { p.Deselect() } } n.selectedPort = index }
func CreateXmlOutPort(p bh.PortIf) (xmlp *backend.XmlOutPort) { xmlp = backend.XmlOutPortNew(p.Name(), p.SignalType().TypeName()) xmlp.Entry = freesp.CreateXmlModePosition(p).Entry return }