重构model抽象结构

This commit is contained in:
soul-walker 2024-06-27 19:59:13 +08:00
parent 58754c2b04
commit 8264941969
6 changed files with 191 additions and 176 deletions

View File

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"log"
"joylink.club/rtss-core/example/data_proto" "joylink.club/rtss-core/example/data_proto"
modelimpl "joylink.club/rtss-core/example/model_impl" modelimpl "joylink.club/rtss-core/example/model_impl"
@ -33,7 +34,7 @@ func main() {
continue continue
} }
dataMapping.SectionDataMap[section.Common.Id] = section dataMapping.SectionDataMap[section.Common.Id] = section
uid := getSectionUid(section, belongStation) uid := getSectionUid(section, belongStation, dataMapping.GetLineInfo())
dataMapping.AddIdMapping(repository.NewIdMapping(section.Common.Id, uid)) dataMapping.AddIdMapping(repository.NewIdMapping(section.Common.Id, uid))
sectionModel := model.NewSection(uid) sectionModel := model.NewSection(uid)
repo1.SectionMap[uid] = &modelimpl.Section{SectionImpl: sectionModel} repo1.SectionMap[uid] = &modelimpl.Section{SectionImpl: sectionModel}
@ -47,7 +48,7 @@ func main() {
continue continue
} }
dataMapping.TurnoutDataMap[turnout.Common.Id] = turnout dataMapping.TurnoutDataMap[turnout.Common.Id] = turnout
uid := getTurnoutUid(turnout, belongStation) uid := getTurnoutUid(turnout, belongStation, dataMapping.GetLineInfo())
dataMapping.AddIdMapping(repository.NewIdMapping(turnout.Common.Id, uid)) dataMapping.AddIdMapping(repository.NewIdMapping(turnout.Common.Id, uid))
turnoutModel := model.NewTurnout(uid) turnoutModel := model.NewTurnout(uid)
repo1.TurnoutMap[uid] = &modelimpl.Turnout{TurnoutImpl: turnoutModel} repo1.TurnoutMap[uid] = &modelimpl.Turnout{TurnoutImpl: turnoutModel}
@ -57,10 +58,34 @@ func main() {
buildSectionRelationships(dataMapping, repo1) buildSectionRelationships(dataMapping, repo1)
// 构建道岔关系 // 构建道岔关系
buildTurnoutRelationships(dataMapping, repo1) buildTurnoutRelationships(dataMapping, repo1)
// 检查通道连接关系 // 检查区段、道岔通道连接关系
err := repo1.CheckPipeLink() err := repo1.CheckPipeLink()
if err != nil { if err != nil {
fmt.Println(err) log.Println(err)
} else {
log.Println("区段、道岔连接关系检查通过")
}
// 构建link/linknode
buildLinkNode(repo1)
}
func buildLinkNode(repo1 *repository.Repository) {
passedSectionMap := make(map[string]struct{})
for _, turnout := range repo1.TurnoutMap {
walkToNextTurnout(turnout, model.PipePortA, passedSectionMap)
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
}
for {
if plink.Pipe.IsThreePorts() {
return plink.Pipe.(*modelimpl.Turnout), plink.Port
}
} }
} }
@ -148,10 +173,10 @@ func convertPort(port data_proto.RelatedRef_DevicePort) model.PipePort {
panic(fmt.Errorf("未知的数据关联端口类型: %v", port)) panic(fmt.Errorf("未知的数据关联端口类型: %v", port))
} }
func getSectionUid(section *data_proto.Section, belongStation *data_proto.Station) string { func getSectionUid(section *data_proto.Section, belongStation *data_proto.Station, lineInfo string) string {
return belongStation.Code + "-" + section.Code return fmt.Sprintf("%s/%s/%s", lineInfo, belongStation.Code, section.Code)
} }
func getTurnoutUid(turnout *data_proto.Turnout, belongStation *data_proto.Station) string { func getTurnoutUid(turnout *data_proto.Turnout, belongStation *data_proto.Station, lineInfo string) string {
return belongStation.Code + "-" + turnout.Code return fmt.Sprintf("%s/%s/%s", lineInfo, belongStation.Code, turnout.Code)
} }

View File

@ -2,6 +2,7 @@ package repository
import ( import (
"errors" "errors"
"fmt"
"joylink.club/rtss-core/example/data_proto" "joylink.club/rtss-core/example/data_proto"
modelimpl "joylink.club/rtss-core/example/model_impl" modelimpl "joylink.club/rtss-core/example/model_impl"
@ -37,6 +38,11 @@ func (d *DataMapping) AddIdMapping(idMapping *IdMapping) {
d.UidMappingMap[idMapping.Uid] = idMapping d.UidMappingMap[idMapping.Uid] = idMapping
} }
func (d *DataMapping) GetLineInfo() string {
lineInfo := d.RtssGraphicStorage.UniqueIdPrefix
return fmt.Sprintf("%s%s", lineInfo.City, lineInfo.LineId)
}
func NewDataMapping(id string, storage *data_proto.RtssGraphicStorage) *DataMapping { func NewDataMapping(id string, storage *data_proto.RtssGraphicStorage) *DataMapping {
return &DataMapping{ return &DataMapping{
id: id, id: id,

View File

@ -19,71 +19,36 @@ var _ Link = (*LinkImpl)(nil)
var _ LinkNode = (*LinkNodeImpl)(nil) var _ LinkNode = (*LinkNodeImpl)(nil)
type LinkImpl struct { type LinkImpl struct {
uid string *TwoPortsPipeElement
paLinkNode *PipeLink
pbLinkNode *PipeLink
} }
type LinkNodeImpl struct { type LinkNodeImpl struct {
turnout Turnout turnout Turnout
paPipeLink *PipeLink *ThreePortsPipeElement
pbPipeLink *PipeLink
pcPipeLink *PipeLink
} }
func NewLink(nodea LinkNode, nodeb LinkNode) Link { func NewLink(nodea LinkNode, nodeb LinkNode) Link {
uid := buildLinkUid(nodea, nodeb) uid := buildLinkUid(nodea, nodeb)
return &LinkImpl{ return &LinkImpl{
uid: uid, TwoPortsPipeElement: &TwoPortsPipeElement{
uid: uid,
},
} }
} }
func NewLinkNode(turnout Turnout) LinkNode { func NewLinkNode(turnout Turnout) LinkNode {
return &LinkNodeImpl{ return &LinkNodeImpl{
turnout: turnout, turnout: turnout,
ThreePortsPipeElement: &ThreePortsPipeElement{
uid: turnout.Uid(),
},
} }
} }
func (l *LinkImpl) Uid() string {
return l.uid
}
func (l *LinkImpl) Ports() []PipePort {
return twoPorts
}
func (l *LinkImpl) GetLinkedElement(port PipePort) *PipeLink {
if port == PipePortA {
return l.paLinkNode
} else if port == PipePortB {
return l.pbLinkNode
}
return nil
}
func (n *LinkNodeImpl) Uid() string {
return n.turnout.Uid()
}
func (n *LinkNodeImpl) Turnout() Turnout { func (n *LinkNodeImpl) Turnout() Turnout {
return n.turnout return n.turnout
} }
func (n *LinkNodeImpl) Ports() []PipePort {
return threePorts
}
func (n *LinkNodeImpl) GetLinkedElement(port PipePort) *PipeLink {
if port == PipePortA {
return n.paPipeLink
} else if port == PipePortB {
return n.pbPipeLink
} else if port == PipePortC {
return n.pcPipeLink
}
return nil
}
func buildLinkUid(nodea LinkNode, nodeb LinkNode) string { func buildLinkUid(nodea LinkNode, nodeb LinkNode) string {
if nodea == nil && nodeb == nil { if nodea == nil && nodeb == nil {
panic("构造link Uid错误: nodea和nodeb不能同时为空") panic("构造link Uid错误: nodea和nodeb不能同时为空")

View File

@ -1,5 +1,9 @@
package model package model
import (
"fmt"
)
type RtssModel interface { type RtssModel interface {
// RtssModel unique id // RtssModel unique id
Uid() string Uid() string
@ -49,20 +53,60 @@ type PipeElement interface {
RtssModel RtssModel
// 获取通道端口 // 获取通道端口
Ports() []PipePort Ports() []PipePort
IsTwoPorts() bool
IsThreePorts() bool
// 获取指定端口连接的通道连接关系 // 获取指定端口连接的通道连接关系
GetLinkedElement(port PipePort) *PipeLink GetLinkedElement(port PipePort) *PipeLink
} }
func checkPipePortLink(pe PipeElement, port PipePort, pipeLink *PipeLink) error {
if pipeLink == nil {
return nil
}
plink := pipeLink.Pipe.GetLinkedElement(pipeLink.Port)
if plink == nil {
return fmt.Errorf("通道端口{uid=%s, port=%s}关联通道端口{uid=%s, port=%s},但关联通道的对应端口却未关联通道端口", pe.Uid(), port, pipeLink.Pipe.Uid(), pipeLink.Port)
} else if plink.Pipe.Uid() != pe.Uid() || plink.Port != port {
return fmt.Errorf("通道端口{uid=%s, port=%s}关联通道端口{uid=%s, port=%s},但关联通道的对应端口却关联了其他通道端口: {uid=%s, port=%s}", pe.Uid(), port, pipeLink.Pipe.Uid(), pipeLink.Port,
plink.Pipe.Uid(), plink.Port)
}
return nil
}
var _ PipeElement = (*TwoPortsPipeElement)(nil)
// 两端口的线性通道元素
type TwoPortsPipeElement struct { type TwoPortsPipeElement struct {
uid string uid string
paPipeLink *PipeLink paPipeLink *PipeLink
pbPipeLink *PipeLink pbPipeLink *PipeLink
} }
func (t *TwoPortsPipeElement) Uid() string {
return t.uid
}
func (t *TwoPortsPipeElement) Ports() []PipePort { func (t *TwoPortsPipeElement) Ports() []PipePort {
return twoPorts return twoPorts
} }
func (t *TwoPortsPipeElement) IsTwoPorts() bool {
return true
}
func (t *TwoPortsPipeElement) IsThreePorts() bool {
return false
}
func (s *TwoPortsPipeElement) GetLinkedElement(port PipePort) *PipeLink {
if port == PipePortA {
return s.paPipeLink
} else if port == PipePortB {
return s.pbPipeLink
}
return nil
}
func (t *TwoPortsPipeElement) OppositePipeLink(port PipePort) PipeLink { func (t *TwoPortsPipeElement) OppositePipeLink(port PipePort) PipeLink {
if port == PipePortA { if port == PipePortA {
return *t.pbPipeLink return *t.pbPipeLink
@ -70,8 +114,98 @@ func (t *TwoPortsPipeElement) OppositePipeLink(port PipePort) PipeLink {
return *t.paPipeLink return *t.paPipeLink
} }
type ThreePortsPipeElement struct{} func (s *TwoPortsPipeElement) SetLinkedElement(port PipePort, pipeLink *PipeLink) error {
if port == PipePortA {
if s.paPipeLink != nil {
return fmt.Errorf("区段uid=%s端口A已经设置关联元素: {uid=%s, port=%s}", s.uid, s.paPipeLink.Pipe.Uid(), s.paPipeLink.Port)
}
s.paPipeLink = pipeLink
} else if port == PipePortB {
if s.pbPipeLink != nil {
return fmt.Errorf("区段uid=%s端口B已经设置关联元素: {uid=%s, port=%s}", s.uid, s.pbPipeLink.Pipe.Uid(), s.pbPipeLink.Port)
}
s.pbPipeLink = pipeLink
} else {
return fmt.Errorf("区段uid=%s设置关联元素端口错误,不支持C端口", s.uid)
}
return nil
}
func (s *TwoPortsPipeElement) CheckPipeLink() error {
err := checkPipePortLink(s, PipePortA, s.paPipeLink)
if err != nil {
return err
}
err = checkPipePortLink(s, PipePortB, s.pbPipeLink)
return err
}
var _ PipeElement = (*ThreePortsPipeElement)(nil)
// 三端口的通道元素
type ThreePortsPipeElement struct {
uid string
paPipeLink *PipeLink
pbPipeLink *PipeLink
pcPipeLink *PipeLink
}
func (t *ThreePortsPipeElement) Uid() string {
return t.uid
}
func (t *ThreePortsPipeElement) Ports() []PipePort { func (t *ThreePortsPipeElement) Ports() []PipePort {
return threePorts return threePorts
} }
func (t *ThreePortsPipeElement) IsTwoPorts() bool {
return false
}
func (t *ThreePortsPipeElement) IsThreePorts() bool {
return true
}
func (t *ThreePortsPipeElement) GetLinkedElement(port PipePort) *PipeLink {
if port == PipePortA {
return t.paPipeLink
} else if port == PipePortB {
return t.pbPipeLink
} else if port == PipePortC {
return t.pcPipeLink
}
return nil
}
func (t *ThreePortsPipeElement) SetLinkedElement(port PipePort, pipeLink *PipeLink) error {
if port == PipePortA {
if t.paPipeLink != nil {
return fmt.Errorf("道岔uid=%s端口A已经设置关联元素: {uid=%s, port=%s}", t.uid, t.paPipeLink.Pipe.Uid(), t.paPipeLink.Port)
}
t.paPipeLink = pipeLink
} else if port == PipePortB {
if t.pbPipeLink != nil {
return fmt.Errorf("道岔uid=%s端口B已经设置关联元素: {uid=%s, port=%s}", t.uid, t.pbPipeLink.Pipe.Uid(), t.pbPipeLink.Port)
}
t.pbPipeLink = pipeLink
} else if port == PipePortC {
if t.pcPipeLink != nil {
return fmt.Errorf("道岔uid=%s端口C已经设置关联元素: {uid=%s, port=%s}", t.uid, t.pcPipeLink.Pipe.Uid(), t.pcPipeLink.Port)
}
t.pcPipeLink = pipeLink
}
return nil
}
func (t *ThreePortsPipeElement) CheckPipeLink() error {
err := checkPipePortLink(t, PipePortA, t.paPipeLink)
if err != nil {
return err
}
err = checkPipePortLink(t, PipePortB, t.pbPipeLink)
if err != nil {
return err
}
err = checkPipePortLink(t, PipePortC, t.pcPipeLink)
return err
}

View File

@ -1,67 +1,20 @@
package model package model
import (
"fmt"
)
// 区段 // 区段
type Section interface { type Section interface {
PipeElement PipeElement
} }
type SectionImpl struct { type SectionImpl struct {
uid string *TwoPortsPipeElement
paPipeLink *PipeLink
pbPipeLink *PipeLink
} }
var _ Section = (*SectionImpl)(nil) var _ Section = (*SectionImpl)(nil)
func NewSection(uid string) *SectionImpl { func NewSection(uid string) *SectionImpl {
return &SectionImpl{ return &SectionImpl{
uid: uid, TwoPortsPipeElement: &TwoPortsPipeElement{
uid: uid,
},
} }
} }
func (s *SectionImpl) SetLinkedElement(port PipePort, pipeLink *PipeLink) error {
if port == PipePortA {
if s.paPipeLink != nil {
return fmt.Errorf("区段uid=%s端口A已经设置关联元素: {uid=%s, port=%s}", s.uid, s.paPipeLink.Pipe.Uid(), s.paPipeLink.Port)
}
s.paPipeLink = pipeLink
} else if port == PipePortB {
if s.pbPipeLink != nil {
return fmt.Errorf("区段uid=%s端口B已经设置关联元素: {uid=%s, port=%s}", s.uid, s.pbPipeLink.Pipe.Uid(), s.pbPipeLink.Port)
}
s.pbPipeLink = pipeLink
} else {
return fmt.Errorf("区段uid=%s设置关联元素端口错误,不支持C端口", s.uid)
}
return nil
}
func (s *SectionImpl) CheckPipeLink() error {
err := checkPipePortLink(s, PipePortA, s.paPipeLink)
if err != nil {
return err
}
err = checkPipePortLink(s, PipePortB, s.pbPipeLink)
return err
}
func (s *SectionImpl) Uid() string {
return s.uid
}
func (s *SectionImpl) Ports() []PipePort {
return twoPorts
}
func (s *SectionImpl) GetLinkedElement(port PipePort) *PipeLink {
if port == PipePortA {
return s.paPipeLink
} else if port == PipePortB {
return s.pbPipeLink
}
return nil
}

View File

@ -1,7 +1,6 @@
package model package model
import ( import (
"fmt"
"strings" "strings"
) )
@ -13,10 +12,7 @@ type Turnout interface {
var _ Turnout = (*TurnoutImpl)(nil) var _ Turnout = (*TurnoutImpl)(nil)
type TurnoutImpl struct { type TurnoutImpl struct {
uid string *ThreePortsPipeElement
paPipeLink *PipeLink
pbPipeLink *PipeLink
pcPipeLink *PipeLink
} }
func NewTurnout(uid string) *TurnoutImpl { func NewTurnout(uid string) *TurnoutImpl {
@ -24,72 +20,8 @@ func NewTurnout(uid string) *TurnoutImpl {
panic("Turnout uid is empty") panic("Turnout uid is empty")
} }
return &TurnoutImpl{ return &TurnoutImpl{
uid: uid, ThreePortsPipeElement: &ThreePortsPipeElement{
uid: uid,
},
} }
} }
func (t *TurnoutImpl) SetLinkedElement(port PipePort, pipeLink *PipeLink) error {
if port == PipePortA {
if t.paPipeLink != nil {
return fmt.Errorf("道岔uid=%s端口A已经设置关联元素: {uid=%s, port=%s}", t.uid, t.paPipeLink.Pipe.Uid(), t.paPipeLink.Port)
}
t.paPipeLink = pipeLink
} else if port == PipePortB {
if t.pbPipeLink != nil {
return fmt.Errorf("道岔uid=%s端口B已经设置关联元素: {uid=%s, port=%s}", t.uid, t.pbPipeLink.Pipe.Uid(), t.pbPipeLink.Port)
}
t.pbPipeLink = pipeLink
} else if port == PipePortC {
if t.pcPipeLink != nil {
return fmt.Errorf("道岔uid=%s端口C已经设置关联元素: {uid=%s, port=%s}", t.uid, t.pcPipeLink.Pipe.Uid(), t.pcPipeLink.Port)
}
t.pcPipeLink = pipeLink
}
return nil
}
func (t *TurnoutImpl) CheckPipeLink() error {
err := checkPipePortLink(t, PipePortA, t.paPipeLink)
if err != nil {
return err
}
err = checkPipePortLink(t, PipePortB, t.pbPipeLink)
if err != nil {
return err
}
err = checkPipePortLink(t, PipePortC, t.pcPipeLink)
return err
}
func checkPipePortLink(pe PipeElement, port PipePort, pipeLink *PipeLink) error {
if pipeLink == nil {
return nil
}
plink := pipeLink.Pipe.GetLinkedElement(pipeLink.Port)
if plink == nil {
return fmt.Errorf("通道端口{uid=%s, port=%s}关联通道端口{uid=%s, port=%s},但关联通道的对应端口却未关联通道端口", pe.Uid(), port, pipeLink.Pipe.Uid(), pipeLink.Port)
} else if plink.Pipe.Uid() != pe.Uid() || plink.Port != port {
return fmt.Errorf("通道端口{uid=%s, port=%s}关联通道端口{uid=%s, port=%s},但关联通道的对应端口却关联了其他通道端口: {uid=%s, port=%s}", pe.Uid(), port, pipeLink.Pipe.Uid(), pipeLink.Port,
plink.Pipe.Uid(), plink.Port)
}
return nil
}
func (t *TurnoutImpl) Uid() string {
return t.uid
}
func (t *TurnoutImpl) Ports() []PipePort {
return threePorts
}
func (t *TurnoutImpl) GetLinkedElement(port PipePort) *PipeLink {
if port == PipePortA {
return t.paPipeLink
} else if port == PipePortB {
return t.pbPipeLink
} else if port == PipePortC {
return t.pcPipeLink
}
return nil
}