2023-09-06 16:20:36 +08:00
|
|
|
|
package repository
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"joylink.club/rtsssimulation/repository/model/proto"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Link struct {
|
|
|
|
|
Identity
|
|
|
|
|
|
|
|
|
|
length int64
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
aRelation *TurnoutPort
|
|
|
|
|
bRelation *TurnoutPort
|
2023-09-14 15:06:51 +08:00
|
|
|
|
|
|
|
|
|
aKm *proto.Kilometer
|
|
|
|
|
bKm *proto.Kilometer
|
2023-09-06 16:20:36 +08:00
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
//Link上的模型((非区段边界)检测点、应答器、信号机、区段(为了位置换算方便))
|
|
|
|
|
devices []Identity
|
|
|
|
|
|
|
|
|
|
////Link关联的模型,包含LinkNode
|
|
|
|
|
//devicePositions []*DeviceLinkPosition
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var _ Identity = &Link{}
|
|
|
|
|
|
|
|
|
|
func NewLink(id string) *Link {
|
2023-09-14 15:06:51 +08:00
|
|
|
|
return &Link{
|
|
|
|
|
Identity: identity{id, proto.DeviceType_DeviceType_Link},
|
|
|
|
|
}
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
func (l *Link) Length() int64 {
|
|
|
|
|
return l.length
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *Link) ARelation() *TurnoutPort {
|
|
|
|
|
return l.aRelation
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *Link) BRelation() *TurnoutPort {
|
|
|
|
|
return l.bRelation
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *Link) Devices() []Identity {
|
|
|
|
|
return l.devices
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
func (l *Link) PortNum() int {
|
|
|
|
|
return 2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *Link) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
2023-09-20 15:14:38 +08:00
|
|
|
|
turnoutPort, isTurnoutPort := devicePort.(*TurnoutPort)
|
|
|
|
|
if !isTurnoutPort {
|
2023-09-06 16:20:36 +08:00
|
|
|
|
return errors.New(fmt.Sprintf("Link不能与[%s]类型的设备关联", devicePort.Device().Type()))
|
|
|
|
|
}
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
2023-09-20 15:14:38 +08:00
|
|
|
|
l.aRelation = turnoutPort
|
2023-09-06 16:20:36 +08:00
|
|
|
|
case proto.Port_B:
|
2023-09-20 15:14:38 +08:00
|
|
|
|
l.bRelation = turnoutPort
|
2023-09-06 16:20:36 +08:00
|
|
|
|
default:
|
|
|
|
|
return errors.New(fmt.Sprintf("Link没有端口[%s]", port))
|
|
|
|
|
}
|
2023-09-20 15:14:38 +08:00
|
|
|
|
l.bindKm(turnoutPort.turnout.km, port)
|
2023-09-06 16:20:36 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-14 15:06:51 +08:00
|
|
|
|
func (l *Link) bindKm(km *proto.Kilometer, port proto.Port) {
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
l.aKm = km
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
l.bKm = km
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
func (l *Link) bindDevices(devices ...Identity) {
|
|
|
|
|
for _, device := range devices {
|
|
|
|
|
l.devices = append(l.devices, device)
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-14 15:06:51 +08:00
|
|
|
|
func (l *Link) findEndKm() *proto.Kilometer {
|
|
|
|
|
if l.aRelation == nil {
|
|
|
|
|
return l.aKm
|
|
|
|
|
} else if l.bRelation == nil {
|
|
|
|
|
return l.bKm
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找Link轨道尽头端的偏移量
|
|
|
|
|
// 如果该link未连接轨道尽头,返回false
|
|
|
|
|
func (l *Link) findEndOffset() (int64, bool) {
|
|
|
|
|
if l.aRelation == nil {
|
|
|
|
|
return 0, true
|
|
|
|
|
}
|
|
|
|
|
if l.bRelation == nil {
|
|
|
|
|
return l.length, true
|
|
|
|
|
}
|
|
|
|
|
return 0, false
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
// LinkPosition link位置
|
|
|
|
|
type LinkPosition struct {
|
|
|
|
|
link *Link
|
|
|
|
|
offset int64
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
func (l *LinkPosition) Link() *Link {
|
|
|
|
|
return l.link
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
func (l *LinkPosition) Offset() int64 {
|
|
|
|
|
return l.offset
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// link端口
|
|
|
|
|
type LinkPort struct {
|
|
|
|
|
link *Link
|
|
|
|
|
port proto.Port
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewLinkPort(link *Link, port proto.Port) LinkPort {
|
|
|
|
|
return LinkPort{
|
|
|
|
|
link: link,
|
|
|
|
|
port: port,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *LinkPort) Port() proto.Port {
|
|
|
|
|
return l.port
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *LinkPort) Device() PortedDevice {
|
|
|
|
|
return l.link
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
//// DeviceLinkPosition device在link上的位置
|
|
|
|
|
//type DeviceLinkPosition struct {
|
|
|
|
|
// device Identity
|
|
|
|
|
// position LinkPosition
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// SlopeLinkSegment Slope在Link上的区间
|
|
|
|
|
//type SlopeLinkSegment struct {
|
|
|
|
|
// slope *Slope
|
|
|
|
|
// start *LinkPosition
|
|
|
|
|
// end *LinkPosition
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (s *SlopeLinkSegment) Slope() *Slope {
|
|
|
|
|
// return s.slope
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (s *SlopeLinkSegment) Start() *LinkPosition {
|
|
|
|
|
// return s.start
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (s *SlopeLinkSegment) End() *LinkPosition {
|
|
|
|
|
// return s.end
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//type SectionalCurvatureLinkSegment struct {
|
|
|
|
|
// sectionalCurvature *SectionalCurvature
|
|
|
|
|
// start *LinkPosition
|
|
|
|
|
// end *LinkPosition
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// LinkNode link节点
|
|
|
|
|
//type LinkNode struct {
|
|
|
|
|
// Identity
|
|
|
|
|
// turnout *Turnout
|
|
|
|
|
// aRelation LinkPort
|
|
|
|
|
// bRelation LinkPort
|
|
|
|
|
// cRelation LinkPort
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (ln LinkNode) Id() string {
|
|
|
|
|
// return ln.turnout.Id()
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (ln LinkNode) PortNum() int {
|
|
|
|
|
// return 3
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (ln LinkNode) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
|
|
|
|
// linkPort, isLinkPort := devicePort.(*LinkPort)
|
|
|
|
|
// if !isLinkPort {
|
|
|
|
|
// return errors.New(fmt.Sprintf("Link节点不能与[%s]类型的设备关联", devicePort.Device().Type()))
|
|
|
|
|
// }
|
|
|
|
|
// switch port {
|
|
|
|
|
// case proto.Port_A:
|
|
|
|
|
// ln.aRelation = *linkPort
|
|
|
|
|
// case proto.Port_B:
|
|
|
|
|
// ln.bRelation = *linkPort
|
|
|
|
|
// case proto.Port_C:
|
|
|
|
|
// ln.cRelation = *linkPort
|
|
|
|
|
// default:
|
|
|
|
|
// return errors.New(fmt.Sprintf("Link节点没有端口[%s]", port))
|
|
|
|
|
// }
|
|
|
|
|
// return nil
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//type LinkNodePort struct {
|
|
|
|
|
// node *LinkNode
|
|
|
|
|
// port proto.Port
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func NewLinkNodePort(node *LinkNode, port proto.Port) *LinkNodePort {
|
|
|
|
|
// return &LinkNodePort{
|
|
|
|
|
// node: node,
|
|
|
|
|
// port: port,
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (lp *LinkNodePort) Port() proto.Port {
|
|
|
|
|
// return lp.port
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//func (lp *LinkNodePort) Device() PortedDevice {
|
|
|
|
|
// return lp.node
|
|
|
|
|
//}
|