link,linknode构建

This commit is contained in:
walker-sheng” 2024-07-01 19:49:24 +08:00
parent 8264941969
commit 9c0d3ba69a
4 changed files with 140 additions and 18 deletions

View File

@ -67,24 +67,68 @@ func main() {
}
// 构建link/linknode
buildLinkNode(repo1)
// 检查link/linknode
err = repo1.CheckPipeLink()
if err != nil {
log.Println(err)
} else {
log.Println("link/linknode连接关系检查通过")
}
}
func buildLinkNode(repo1 *repository.Repository) {
passedSectionMap := make(map[string]struct{})
for _, turnout := range repo1.TurnoutMap {
walkToNextTurnout(turnout, model.PipePortA, passedSectionMap)
walkOverTurnouts(turnout, repo1)
break // 从一个道岔遍历所有区段、道岔
}
}
func walkToNextTurnout(turnout *modelimpl.Turnout, port model.PipePort, passedSectionMap map[string]struct{}) (*modelimpl.Turnout, model.PipePort) {
plink := turnout.GetLinkedElement(port)
if plink == nil {
return nil, model.PipePortA
func walkOverTurnouts(turnout *modelimpl.Turnout, repo1 *repository.Repository) {
paNext := walkFromTurnoutPortToNextAndBuildLink(turnout, model.PipePortA, repo1)
if paNext != nil {
walkOverTurnouts(paNext, repo1)
}
pbNext := walkFromTurnoutPortToNextAndBuildLink(turnout, model.PipePortB, repo1)
if pbNext != nil {
walkOverTurnouts(pbNext, repo1)
}
pcNext := walkFromTurnoutPortToNextAndBuildLink(turnout, model.PipePortC, repo1)
if pcNext != nil {
walkOverTurnouts(pcNext, repo1)
}
}
func walkFromTurnoutPortToNextAndBuildLink(turnout *modelimpl.Turnout, port model.PipePort, repo1 *repository.Repository) *modelimpl.Turnout {
log.Println("walkFromTurnoutPortToNextAndBuildLink", turnout.Uid(), port)
ple := turnout.GetLinkedElement(port)
for {
if plink.Pipe.IsThreePorts() {
return plink.Pipe.(*modelimpl.Turnout), plink.Port
if ple == nil {
log.Println("ple is nil")
} else {
log.Println("ple", ple.Pipe.Uid(), ple.Port)
}
if ple == nil {
nodea, nodeb, link := model.NewLinkNodeAndLinkAndBuildLinkship(turnout, port, nil, model.PipePortA)
allExist := repo1.IsLinkNodeAllExistOrStore(nodea, nodeb)
if !allExist {
repo1.LinkMap[link.Uid()] = link
}
log.Println("已存在", link.Uid())
return nil
}
if ple.Pipe.IsThreePorts() {
nextTurnout := ple.Pipe.(*modelimpl.Turnout)
nextPort := ple.Port
nodea, nodeb, link := model.NewLinkNodeAndLinkAndBuildLinkship(turnout, port, nextTurnout, nextPort)
allExist := repo1.IsLinkNodeAllExistOrStore(nodea, nodeb)
if allExist {
log.Println("已存在", link.Uid())
return nil
}
repo1.LinkMap[link.Uid()] = link
return nextTurnout
} else {
ple = ple.Pipe.(*modelimpl.Section).OppositePipeLink(ple.Port)
}
}
}

View File

@ -3,6 +3,7 @@ package repository
import (
"errors"
"fmt"
"log"
"joylink.club/rtss-core/example/data_proto"
modelimpl "joylink.club/rtss-core/example/model_impl"
@ -62,6 +63,8 @@ type Repository struct {
StationMap map[string]*modelimpl.Station
SectionMap map[string]*modelimpl.Section
TurnoutMap map[string]*modelimpl.Turnout
LinkNodeMap map[string]*model.LinkNodeImpl
LinkMap map[string]*model.LinkImpl
}
var _ repo.Repo = &Repository{}
@ -74,9 +77,32 @@ func NewRepository(id string) *Repository {
StationMap: make(map[string]*modelimpl.Station),
SectionMap: make(map[string]*modelimpl.Section),
TurnoutMap: make(map[string]*modelimpl.Turnout),
LinkNodeMap: make(map[string]*model.LinkNodeImpl),
LinkMap: make(map[string]*model.LinkImpl),
}
}
func (r *Repository) IsLinkNodeAllExistOrStore(nodea *model.LinkNodeImpl, nodeb *model.LinkNodeImpl) bool {
if nodea == nil && nodeb == nil {
panic("linkNode存在检查参数异常: node不能都为空")
}
for _, link := range r.LinkMap {
exist := link.IsEquals(nodea, nodeb)
if exist {
return true
}
}
if nodea == nil {
r.LinkNodeMap[nodeb.Uid()] = nodeb
} else if nodeb == nil {
r.LinkNodeMap[nodea.Uid()] = nodea
} else {
r.LinkNodeMap[nodea.Uid()] = nodea
r.LinkNodeMap[nodeb.Uid()] = nodeb
}
return false
}
func (r *Repository) Id() string {
return r.id
}
@ -106,6 +132,21 @@ func (r *Repository) CheckPipeLink() error {
r.BuildErrorInfos = append(r.BuildErrorInfos, err)
}
}
log.Println("link数量: ", len(r.LinkMap))
for _, link := range r.LinkMap {
log.Println("检查link", link.Uid())
err := link.CheckPipeLink()
if err != nil {
r.BuildErrorInfos = append(r.BuildErrorInfos, err)
}
}
for _, linkNode := range r.LinkNodeMap {
log.Println("检查linkNode", linkNode.Uid())
err := linkNode.CheckPipeLink()
if err != nil {
r.BuildErrorInfos = append(r.BuildErrorInfos, err)
}
}
if len(r.BuildErrorInfos) > 0 {
return errors.Join(r.BuildErrorInfos...)
}

View File

@ -1,6 +1,8 @@
package model
import "io"
import (
"io"
)
type RR = io.Writer
@ -27,7 +29,35 @@ type LinkNodeImpl struct {
*ThreePortsPipeElement
}
func NewLink(nodea LinkNode, nodeb LinkNode) Link {
func NewLinkNodeAndLinkAndBuildLinkship(ta Turnout, tap PipePort, tb Turnout, tbp PipePort) (nodea *LinkNodeImpl, nodeb *LinkNodeImpl, link *LinkImpl) {
if ta == nil && tb == nil {
panic("构造LinkNode错误: 道岔不能都为空")
}
if ta == nil {
nodea = nil
nodeb = NewLinkNode(tb)
link = NewLink(nodea, nodeb)
link.SetLinkedElement(PipePortB, NewPipeLink(nodeb, tbp))
nodeb.SetLinkedElement(tbp, NewPipeLink(link, PipePortB))
} else if tb == nil {
nodea = NewLinkNode(ta)
nodeb = nil
link = NewLink(nodea, nodeb)
link.SetLinkedElement(PipePortA, NewPipeLink(nodea, tap))
nodea.SetLinkedElement(tap, NewPipeLink(link, PipePortA))
} else {
nodea = NewLinkNode(ta)
nodeb = NewLinkNode(tb)
link = NewLink(nodea, nodeb)
link.SetLinkedElement(PipePortA, NewPipeLink(nodea, tap))
link.SetLinkedElement(PipePortB, NewPipeLink(nodeb, tbp))
nodea.SetLinkedElement(tap, NewPipeLink(link, PipePortA))
nodeb.SetLinkedElement(tbp, NewPipeLink(link, PipePortB))
}
return
}
func NewLink(nodea *LinkNodeImpl, nodeb *LinkNodeImpl) *LinkImpl {
uid := buildLinkUid(nodea, nodeb)
return &LinkImpl{
TwoPortsPipeElement: &TwoPortsPipeElement{
@ -36,7 +66,10 @@ func NewLink(nodea LinkNode, nodeb LinkNode) Link {
}
}
func NewLinkNode(turnout Turnout) LinkNode {
func NewLinkNode(turnout Turnout) *LinkNodeImpl {
if turnout == nil {
panic("构造LinkNode错误: 道岔不能为空")
}
return &LinkNodeImpl{
turnout: turnout,
ThreePortsPipeElement: &ThreePortsPipeElement{
@ -45,19 +78,23 @@ func NewLinkNode(turnout Turnout) LinkNode {
}
}
func (l *LinkImpl) IsEquals(nodea *LinkNodeImpl, nodeb *LinkNodeImpl) bool {
return l.uid == buildLinkUid(nodea, nodeb) || l.uid == buildLinkUid(nodeb, nodea)
}
func (n *LinkNodeImpl) Turnout() Turnout {
return n.turnout
}
func buildLinkUid(nodea LinkNode, nodeb LinkNode) string {
func buildLinkUid(nodea *LinkNodeImpl, nodeb *LinkNodeImpl) string {
if nodea == nil && nodeb == nil {
panic("构造link Uid错误: nodea和nodeb不能同时为空")
}
if nodea == nil {
return "->" + nodeb.Turnout().Uid()
return "end" + "->" + nodeb.Turnout().Uid()
}
if nodeb == nil {
return nodea.Turnout().Uid() + "->"
return nodea.Turnout().Uid() + "->" + "end"
}
return nodea.Turnout().Uid() + "-" + nodeb.Turnout().Uid()
return nodea.Turnout().Uid() + "->" + nodeb.Turnout().Uid()
}

View File

@ -107,11 +107,11 @@ func (s *TwoPortsPipeElement) GetLinkedElement(port PipePort) *PipeLink {
return nil
}
func (t *TwoPortsPipeElement) OppositePipeLink(port PipePort) PipeLink {
func (t *TwoPortsPipeElement) OppositePipeLink(port PipePort) *PipeLink {
if port == PipePortA {
return *t.pbPipeLink
return t.pbPipeLink
}
return *t.paPipeLink
return t.paPipeLink
}
func (s *TwoPortsPipeElement) SetLinkedElement(port PipePort, pipeLink *PipeLink) error {