rts-sim-module/repository/link.go

188 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"errors"
"fmt"
"joylink.club/rtsssimulation/repository/model/proto"
)
type Link struct {
Identity
length int64
aRelation *LinkNodePort
bRelation *LinkNodePort
aKm *proto.Kilometer
bKm *proto.Kilometer
//Link关联的模型包含LinkNode
devicePositions []*DeviceLinkPosition
}
var _ Identity = &Link{}
func NewLink(id string) *Link {
return &Link{
Identity: identity{id, proto.DeviceType_DeviceType_Link},
}
}
func (l *Link) PortNum() int {
return 2
}
func (l *Link) bindDevicePort(port proto.Port, devicePort DevicePort) error {
linkNodePort, isLinkNodePort := devicePort.(*LinkNodePort)
if !isLinkNodePort {
return errors.New(fmt.Sprintf("Link不能与[%s]类型的设备关联", devicePort.Device().Type()))
}
switch port {
case proto.Port_A:
l.aRelation = linkNodePort
case proto.Port_B:
l.bRelation = linkNodePort
default:
return errors.New(fmt.Sprintf("Link没有端口[%s]", port))
}
return nil
}
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
}
}
func (l *Link) bindDevicesLinkPositions(dlps ...*DeviceLinkPosition) {
for _, dlp := range dlps {
l.devicePositions = append(l.devicePositions, dlp)
}
}
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
}
// LinkPosition link位置
type LinkPosition struct {
link *Link
offset int64
}
// DeviceLinkPosition device在link上的位置
type DeviceLinkPosition struct {
device Identity
position LinkPosition
}
// SlopeLinkSegment Slope在Link上的区间
type SlopeLinkSegment struct {
slope *Slope
start *LinkPosition
end *LinkPosition
}
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
}
// 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
}
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
}