예제 #1
0
파일: nodetype.go 프로젝트: axel-freesp/sge
func (t *nodeType) AddToTree(tree tr.TreeIf, cursor tr.Cursor) {
	var prop tr.Property
	parentId := tree.Parent(cursor)
	parent := tree.Object(parentId)
	switch parent.(type) {
	case bh.LibraryIf:
		prop = freesp.PropertyNew(true, true, true)
	case bh.NodeIf:
		prop = freesp.PropertyNew(false, false, false)
	default:
		log.Fatalf("nodeType.AddToTree error: invalid parent type %T\n", parent)
	}
	err := tree.AddEntry(cursor, tr.SymbolNodeType, t.TypeName(), t, prop)
	if err != nil {
		log.Fatalf("nodeType.AddToTree error: AddEntry failed: %s\n", err)
	}
	for _, impl := range t.Implementation() {
		child := tree.Append(cursor)
		impl.AddToTree(tree, child)
	}
	for _, pt := range t.InPorts() {
		child := tree.Append(cursor)
		pt.AddToTree(tree, child)
	}
	for _, pt := range t.OutPorts() {
		child := tree.Append(cursor)
		pt.AddToTree(tree, child)
	}
}
예제 #2
0
파일: nodetype.go 프로젝트: axel-freesp/sge
func (t *nodeType) RemoveObject(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)
	del := t.treeRemoveObject(tree, cursor)
	for _, d := range del {
		removed = append(removed, d)
	}
	del = t.treeRemoveInstObject(tree, cursor)
	for _, d := range del {
		removed = append(removed, d)
	}
	prefix, index := tree.Remove(cursor)
	removed = append(removed, tr.IdWithObject{prefix, index, obj})

	switch obj.(type) {
	case bh.ImplementationIf:
		impl := obj.(bh.ImplementationIf)
		// Remove obj in freesp model
		t.RemoveImplementation(impl)

	case bh.PortTypeIf:
		nt := obj.(bh.PortTypeIf)
		t.RemoveNamedPortType(nt)

	default:
		log.Fatalf("nodeType.RemoveObject error: invalid type %T\n", obj)
	}
	return
}
예제 #3
0
파일: node.go 프로젝트: axel-freesp/sge
func (n *node) RemoveObject(tree tr.TreeIf, cursor tr.Cursor) (removed []tr.IdWithObject) {
	parentId := tree.Parent(cursor)
	if n != tree.Object(parentId) {
		log.Fatal("node.RemoveObject error: not removing child of mine.")
	}
	nt := n.ItsType()
	obj := tree.Object(cursor)
	switch obj.(type) {
	case bh.PortIf:
		p := obj.(bh.PortIf)
		for index, c := range p.Connections() {
			conn := p.Connection(c)
			removed = append(removed, tr.IdWithObject{cursor.Path, index, conn})
		}
		var list portTypeList
		if p.Direction() == gr.InPort {
			list = nt.(*nodeType).inPorts
		} else {
			list = nt.(*nodeType).outPorts
		}
		_, ok, index := list.Find(p.Name())
		if !ok {
			log.Println("node.RemoveObject: saving removed port", p)
			removed = append(removed, tr.IdWithObject{parentId.Path, index, obj})
		}
		tree.Remove(cursor)

	default:
		log.Fatal("bh.NodeIf.RemoveObject error: invalid type %T", obj)
	}
	return
}
예제 #4
0
파일: port.go 프로젝트: axel-freesp/sge
func (p *port) AddToTree(tree tr.TreeIf, cursor tr.Cursor) {
	var prop tr.Property
	parentId := tree.Parent(cursor)
	if tree.Property(parentId).IsReadOnly() {
		prop = freesp.PropertyNew(false, false, false)
	} else {
		prop = freesp.PropertyNew(true, false, false)
	}
	var kind tr.Symbol
	if p.Direction() == gr.InPort {
		kind = tr.SymbolInputPort
	} else {
		kind = tr.SymbolOutputPort
	}
	err := tree.AddEntry(cursor, kind, p.Name(), p, prop)
	if err != nil {
		log.Fatalf("port.AddToTree: FilesTreeStore.AddEntry() failed: %s\n", err)
	}
	child := tree.Append(cursor)
	t := p.SignalType()
	t.AddToTree(tree, child)
	for _, c := range p.Connections() {
		child = tree.Append(cursor)
		p.Connection(c).AddToTree(tree, child)
	}
	return
}
예제 #5
0
파일: process.go 프로젝트: axel-freesp/sge
func (p *process) RemoveObject(tree tr.TreeIf, cursor tr.Cursor) (removed []tr.IdWithObject) {
	parent := tree.Parent(cursor)
	if p != tree.Object(parent) {
		log.Fatal("process.RemoveObject error: not removing child of mine.")
	}
	obj := tree.Object(cursor)
	switch obj.(type) {
	case pf.ChannelIf:
		c := obj.(pf.ChannelIf)
		cc := c.Link()
		pp := cc.Process()
		ppCursor := tree.Cursor(pp) // TODO. better search over platform...
		ccCursor := tree.CursorAt(ppCursor, cc)
		var l *channelList
		var ll *channelList
		if c.Direction() == gr.InPort {
			l = &p.inChannels
			ll = &pp.(*process).outChannels
		} else {
			l = &p.outChannels
			ll = &pp.(*process).inChannels
		}
		l.Remove(c)
		ll.Remove(cc)
		tree.Remove(ccCursor)
		prefix, index := tree.Remove(cursor)
		removed = append(removed, tr.IdWithObject{prefix, index, c})

	default:
		log.Fatalf("Port.RemoveObject error: invalid type %T: %v\n", obj, obj)
	}
	return
}
예제 #6
0
파일: port.go 프로젝트: axel-freesp/sge
func (p *port) treeAddNewObject(tree tr.TreeIf, cursor tr.Cursor, conn bh.ConnectionIf, otherPort bh.PortIf) (newCursor tr.Cursor) {
	newCursor = tree.Insert(cursor)
	conn.AddToTree(tree, newCursor)
	contextCursor := tree.Parent(tree.Parent(cursor))
	cCursor := tree.CursorAt(contextCursor, otherPort)
	cChild := tree.Append(cCursor)
	conn.AddToTree(tree, cChild)
	return
}
예제 #7
0
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
}
예제 #8
0
func (t *signalGraphType) RemoveObject(tree tr.TreeIf, cursor tr.Cursor) (removed []tr.IdWithObject) {
	obj := tree.Object(cursor)
	switch obj.(type) {
	case bh.NodeIf:
		n := obj.(bh.NodeIf)
		// Remove all connections first
		for _, p := range n.OutPorts() {
			for _, c := range p.Connections() {
				conn := p.Connection(c)
				cCursor := tree.CursorAt(cursor, conn)
				del := p.RemoveObject(tree, cCursor)
				for _, d := range del {
					removed = append(removed, d)
				}
			}
		}
		for _, p := range n.InPorts() {
			for _, c := range p.Connections() {
				conn := p.Connection(c)
				cCursor := tree.CursorAt(cursor, conn)
				del := p.RemoveObject(tree, cCursor)
				for _, d := range del {
					removed = append(removed, d)
				}
			}
		}
		parentCursor := tree.Parent(cursor)
		parent := tree.Object(parentCursor)
		switch parent.(type) {
		case bh.SignalGraphIf:
		case bh.ImplementationIf:
			// propagate new node to all instances of embracing type
			pCursor := tree.Parent(parentCursor)
			nt := tree.Object(pCursor)
			for _, nn := range nt.(bh.NodeTypeIf).Instances() {
				nCursor := tree.Cursor(nn)
				tCursor := tree.CursorAt(nCursor, parent)
				tree.Remove(tree.CursorAt(tCursor, n))
			}

		default:
			log.Fatalf("signalGraphType.RemoveObject error: wrong parent type %t: %v\n", parent, parent)
		}
		prefix, index := tree.Remove(cursor)
		removed = append(removed, tr.IdWithObject{prefix, index, obj})
		t.RemoveNode(n)

	default:
		log.Fatalf("signalGraphType.RemoveObject error: wrong type %t: %v", obj, obj)
	}
	return
}
예제 #9
0
파일: port.go 프로젝트: axel-freesp/sge
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
}
예제 #10
0
파일: nodetype.go 프로젝트: axel-freesp/sge
// 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
}
예제 #11
0
파일: library.go 프로젝트: axel-freesp/sge
func (l *library) RemoveObject(tree tr.TreeIf, cursor tr.Cursor) (removed []tr.IdWithObject) {
	parent := tree.Parent(cursor)
	if l != tree.Object(parent) {
		log.Fatal("library.RemoveObject error: not removing child of mine.")
	}
	obj := tree.Object(cursor)
	switch obj.(type) {
	case bh.SignalTypeIf:
		st := tree.Object(cursor).(bh.SignalTypeIf)
		for _, nt := range l.NodeTypes() {
			for _, p := range nt.InPorts() {
				if p.SignalType().TypeName() == st.TypeName() {
					log.Printf(`library.RemoveObject 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.RemoveObject warning:
						bh.SignalTypeIf %v is still in use\n`, st)
					return
				}
			}
		}
		prefix, index := tree.Remove(cursor)
		removed = append(removed, tr.IdWithObject{prefix, index, obj})
		l.RemoveSignalType(st)

	case bh.NodeTypeIf:
		nt := tree.Object(cursor).(bh.NodeTypeIf)
		log.Printf("library.RemoveObject: nt=%v\n", nt)
		if len(nt.Instances()) > 0 {
			log.Printf(`library.RemoveObject warning: The following nodes
				are still instances of bh.NodeTypeIf %s:\n`, nt.TypeName())
			for _, n := range nt.Instances() {
				log.Printf("	%s\n", n.Name())
			}
			return
		}
		prefix, index := tree.Remove(cursor)
		removed = append(removed, tr.IdWithObject{prefix, index, obj})
		l.RemoveNodeType(nt)

	default:
		log.Fatalf("library.RemoveObject error: invalid type %T\n", obj)
	}
	return
}
예제 #12
0
func (t *signalType) AddToTree(tree tr.TreeIf, cursor tr.Cursor) {
	var prop tr.Property
	parentId := tree.Parent(cursor)
	parent := tree.Object(parentId)
	switch parent.(type) {
	case bh.LibraryIf:
		prop = freesp.PropertyNew(true, true, true)
	case bh.PortIf, bh.PortTypeIf:
		prop = freesp.PropertyNew(false, false, false)
	default:
		log.Fatalf("signalType.AddToTree error: invalid parent type %T\n", parent)
	}
	err := tree.AddEntry(cursor, tr.SymbolSignalType, t.TypeName(), t, prop)
	if err != nil {
		log.Fatalf("signalType.AddToTree error: AddEntry failed: %s\n", err)
	}
}
예제 #13
0
파일: porttype.go 프로젝트: axel-freesp/sge
func (p *portType) AddToTree(tree tr.TreeIf, cursor tr.Cursor) {
	var prop tr.Property
	parentId := tree.Parent(cursor)
	if tree.Property(parentId).IsReadOnly() {
		prop = freesp.PropertyNew(false, false, false)
	} else {
		prop = freesp.PropertyNew(true, true, true)
	}
	var kind tr.Symbol
	if p.Direction() == gr.InPort {
		kind = tr.SymbolInputPortType
	} else {
		kind = tr.SymbolOutputPortType
	}
	err := tree.AddEntry(cursor, kind, p.Name(), p, prop)
	if err != nil {
		log.Fatal("bh.PortTypeIf.AddToTree: FilesTreeStore.AddEntry() failed: %s\n", err)
	}
	child := tree.Append(cursor)
	p.SignalType().AddToTree(tree, child)
}
예제 #14
0
파일: port.go 프로젝트: axel-freesp/sge
func (p *port) treeRemoveObject(tree tr.TreeIf, cursor tr.Cursor, conn bh.ConnectionIf, otherPort bh.PortIf) (removed []tr.IdWithObject) {
	contextCursor := tree.Parent(tree.Parent(tree.Parent(cursor)))
	pCursor := tree.CursorAt(contextCursor, otherPort)
	otherCursor := tree.CursorAt(pCursor, conn)
	prefix, index := tree.Remove(cursor)
	removed = append(removed, tr.IdWithObject{prefix, index, conn})
	tree.Remove(otherCursor)
	return
}
예제 #15
0
파일: port.go 프로젝트: axel-freesp/sge
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
}
예제 #16
0
파일: arch.go 프로젝트: axel-freesp/sge
func (a *arch) RemoveObject(tree tr.TreeIf, cursor tr.Cursor) (removed []tr.IdWithObject) {
	parent := tree.Parent(cursor)
	if a != tree.Object(parent) {
		log.Printf("arch.RemoveObject error: not removing child of mine.")
		return
	}
	obj := tree.Object(cursor)
	switch obj.(type) {
	case pf.IOTypeIf:
		t := obj.(pf.IOTypeIf)
		_, ok := a.iotypes.Find(t.Name())
		if ok {
			a.iotypes.Remove(t)
		} else {
			log.Printf("arch.RemoveObject error: iotype to be removed not found.\n")
		}
		prefix, index := tree.Remove(cursor)
		removed = append(removed, tr.IdWithObject{prefix, index, t})

	case pf.ProcessIf:
		p := obj.(pf.ProcessIf)
		if p.Arch() != a {
			log.Printf("arch.RemoveObject error: process to be removed is no child of mine.")
		}
		_, ok := a.processes.Find(p.Name())
		if ok {
			a.processes.Remove(p)
		} else {
			log.Printf("arch.RemoveObject error: process to be removed not found.\n")
		}
		for _, c := range p.InChannels() {
			cc := c.Link()
			pp := cc.Process()
			ppCursor := tree.Cursor(pp) // TODO: better search over platform...
			ccCursor := tree.CursorAt(ppCursor, cc)
			//log.Printf("arch.RemoveObject: remove %v\n", cc)
			pp.(*process).outChannels.Remove(cc)
			prefix, index := tree.Remove(ccCursor)
			removed = append(removed, tr.IdWithObject{prefix, index, cc})
		}
		for _, c := range p.InChannels() {
			p.(*process).inChannels.Remove(c)
		}
		for _, c := range p.OutChannels() {
			cc := c.Link()
			pp := cc.Process()
			ppCursor := tree.Cursor(pp) // TODO: better search over platform...
			ccCursor := tree.CursorAt(ppCursor, cc)
			//log.Printf("arch.RemoveObject: remove %v\n", cc)
			pp.(*process).inChannels.Remove(cc)
			prefix, index := tree.Remove(ccCursor)
			removed = append(removed, tr.IdWithObject{prefix, index, cc})
		}
		for _, c := range p.OutChannels() {
			p.(*process).outChannels.Remove(c)
		}
		prefix, index := tree.Remove(cursor)
		removed = append(removed, tr.IdWithObject{prefix, index, p})
		//log.Printf("arch.RemoveObject: successfully removed process %v\n", p)

	default:
		log.Fatalf("arch.AddNewObject error: invalid type %T\n", obj)
	}
	return
}
예제 #17
0
파일: node.go 프로젝트: axel-freesp/sge
func isParentReadOnly(tree tr.TreeIf, cursor tr.Cursor) bool {
	parentId := tree.Parent(cursor)
	return tree.Property(parentId).IsReadOnly()
}
예제 #18
0
파일: nodetype.go 프로젝트: axel-freesp/sge
func (t *nodeType) treeRemoveObject(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:
		impl := obj.(bh.ImplementationIf)
		if impl.ImplementationType() == bh.NodeTypeGraph {
			// TODO: This is redundant with implementation.go
			// Simply remove all nodes? Do not traverse a modifying list...
			// Removed Input- and Output nodes are NOT stored (they are
			// created automatically when adding the implementation graph).
			// Return all removed edges ...
			for _, n := range impl.Graph().Nodes() {
				nCursor := tree.Cursor(n)
				for _, p := range n.OutPorts() {
					pCursor := tree.CursorAt(nCursor, p)
					for index, c := range p.Connections() {
						conn := p.Connection(c)
						removed = append(removed, tr.IdWithObject{pCursor.Path, index, conn})
					}
				}
			}
			// ... and processing nodes
			for _, n := range impl.Graph().ProcessingNodes() {
				nCursor := tree.Cursor(n)
				gCursor := tree.Parent(nCursor)
				nIndex := gCursor.Position
				removed = append(removed, tr.IdWithObject{nCursor.Path, nIndex, n})
			}
		}

	case bh.PortTypeIf:
		nt := obj.(bh.PortTypeIf)
		for _, impl := range t.Implementation() {
			if impl.ImplementationType() == bh.NodeTypeGraph {
				// Remove and store all edges connected to the nodes linked to the outer ports
				g := impl.Graph().(*signalGraphType)
				var n bh.NodeIf
				if nt.Direction() == gr.InPort {
					n = g.findInputNodeFromPortType(nt)
				} else {
					n = g.findOutputNodeFromPortType(nt)
				}
				if n == nil {
					log.Fatalf("nodeType.RemoveObject error: invalid implementation...\n")
				}
				nCursor := tree.CursorAt(parentId, n)
				for _, p := range n.InPorts() {
					pCursor := tree.CursorAt(nCursor, p)
					for _, c := range p.Connections() {
						conn := p.Connection(c)
						removed = append(removed, tr.IdWithObject{pCursor.Path, -1, conn})
					}
				}
				for _, p := range n.OutPorts() {
					pCursor := tree.CursorAt(nCursor, p)
					for _, c := range p.Connections() {
						conn := p.Connection(c)
						removed = append(removed, tr.IdWithObject{pCursor.Path, -1, conn})
					}
				}
				// Remove (but dont store) the nodes linked to the outer ports:
				tree.Remove(nCursor)
			}
		}

	default:
		log.Fatalf("nodeType.RemoveObject error: invalid type %T\n", obj)
	}
	return
}