道岔、联锁驱采卡实体构建重构

This commit is contained in:
walker 2024-01-16 18:08:06 +08:00
parent 9401b15142
commit 16dbc3e93e
15 changed files with 349 additions and 88 deletions

View File

@ -3,8 +3,48 @@ package component
import ( import (
"joylink.club/ecs" "joylink.club/ecs"
"joylink.club/rtsssimulation/component/component_data" "joylink.club/rtsssimulation/component/component_data"
"joylink.club/rtsssimulation/component/relation"
"joylink.club/rtsssimulation/modelrepo/model"
) )
var ( var (
CiSysRAMType = ecs.NewComponentType[component_data.CiSysRAM]() CiSysRAMType = ecs.NewComponentType[component_data.CiSysRAM]()
// 联锁驱采码表模型关系组件类型
CiQckModelRelaType = relation.CiQckModelRelaType
// 联锁驱动、采集状态表
CiQckStateType = ecs.NewComponentType[CiQckState]()
) )
type CiQckState struct {
*component_data.CiQcState
qbits []bool
cbits []bool
}
func NewCiQckState(qcb model.CiQcb) *CiQckState {
qbits := len(qcb.QD())
cbits := len(qcb.CJ())
qbytes := qbits / 8
if qbits%8 > 0 {
qbytes++
}
cbytes := cbits / 8
if cbits%8 > 0 {
cbytes++
}
s := &CiQckState{
CiQcState: &component_data.CiQcState{
Qbs: make([]byte, qbytes),
Cbs: make([]byte, cbytes),
},
qbits: make([]bool, qbits),
cbits: make([]bool, cbits),
}
return s
}
// 获取驱动位状态
func (s *CiQckState) GetQbitOf(i int) bool {
return s.qbits[i]
}

24
component/relation/ci.go Normal file
View File

@ -0,0 +1,24 @@
package relation
import (
"joylink.club/ecs"
"joylink.club/rtsssimulation/modelrepo/model"
)
var (
CiQckModelRelaType = ecs.NewComponentType[CiQckModelRela]()
)
type CiQckModelRela struct {
// 所属集中站
Station model.EcStation
// 驱采码表
M model.CiQcb
}
func NewCiQckModelRela(station model.EcStation) *CiQckModelRela {
return &CiQckModelRela{
Station: station,
M: station.GetCiQcb(),
}
}

View File

@ -18,5 +18,5 @@ type RelayModelRela struct {
} }
type DbqModelRela struct { type DbqModelRela struct {
M model.DBQ M model.Dbq
} }

View File

@ -85,6 +85,9 @@ type Zdj9TwoElectronic struct {
TDFJ2_DBQ *ecs.Entry // 断相保护器 TDFJ2_DBQ *ecs.Entry // 断相保护器
TDFJ2_DBJ *ecs.Entry // 定位表示继电器 TDFJ2_DBJ *ecs.Entry // 定位表示继电器
TDFJ2_FBJ *ecs.Entry // 反位表示继电器 TDFJ2_FBJ *ecs.Entry // 反位表示继电器
// 联锁驱采卡
CiQck *ecs.Entry // 联锁驱采卡
} }
// 检查空引用,返回空引用字段名称 // 检查空引用,返回空引用字段名称
@ -156,6 +159,10 @@ func (te *Zdj9TwoElectronic) CheckNilReference() []string {
if te.TDFJ2_FBJ == nil { if te.TDFJ2_FBJ == nil {
nils = append(nils, "TDFJ2_FBJ") nils = append(nils, "TDFJ2_FBJ")
} }
if te.CiQck == nil {
nils = append(nils, "CiQck")
}
return nils return nils
} }

View File

@ -27,6 +27,19 @@ func (idx *EntityUidIndex) Get(uid string) *ecs.Entry {
return idx.entityMap[uid] return idx.entityMap[uid]
} }
func (idx *EntityUidIndex) Has(uid string) bool {
idx.mu.RLock()
defer idx.mu.RUnlock()
_, ok := idx.entityMap[uid]
return ok
}
func (idx *EntityUidIndex) Remove(uid string) {
idx.mu.Lock()
defer idx.mu.Unlock()
delete(idx.entityMap, uid)
}
func loadUidEntityIndex(w ecs.World) { func loadUidEntityIndex(w ecs.World) {
entry := w.Entry(w.Create(EntityUidIndexType)) entry := w.Entry(w.Create(EntityUidIndexType))
EntityUidIndexType.Set(entry, &EntityUidIndex{ EntityUidIndexType.Set(entry, &EntityUidIndex{

38
entity/ci_qck.go Normal file
View File

@ -0,0 +1,38 @@
package entity
import (
"fmt"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/component/relation"
"joylink.club/rtsssimulation/component/singleton"
"joylink.club/rtsssimulation/modelrepo/model"
)
// 加载联锁驱采卡实体
func loadCiQck(w ecs.World, station model.EcStation) (*ecs.Entry, error) {
// 检查驱采表相关继电器是否存在
qcb := station.GetCiQcb()
if qcb == nil {
return nil, nil
}
uidIdx := singleton.GetEntityUidIndex(w)
for _, v := range qcb.QD() {
if !uidIdx.Has(v) {
return nil, fmt.Errorf("加载联锁驱采卡实体失败,车站'%s'的驱采表指定的驱动继电器'%s'不存在", station.Name(), v)
}
}
for _, cc := range qcb.CJ() {
for _, ccp := range cc.CjPos() {
if !uidIdx.Has(ccp.RelayId()) {
return nil, fmt.Errorf("加载联锁驱采卡实体失败,车站'%s'的驱采表指定的采集继电器'%s'不存在", station.Name(), ccp.RelayId())
}
}
}
// 加载联锁驱采卡实体
entry := w.Entry(w.Create(component.CiQckModelRelaType, component.CiQckStateType))
component.CiQckModelRelaType.Set(entry, relation.NewCiQckModelRela(station))
component.CiQckStateType.Set(entry, component.NewCiQckState(qcb))
return entry, nil
}

View File

@ -11,7 +11,7 @@ import (
// 电子元件相关实体创建 // 电子元件相关实体创建
// 创建断相保护器实体 // 创建断相保护器实体
func NewDBQ(w ecs.World, dbq model.DBQ) *ecs.Entry { func NewDbq(w ecs.World, dbq model.Dbq) *ecs.Entry {
uid := dbq.Uid().Id() uid := dbq.Uid().Id()
re := w.Entry(w.Create(component.DBQTag, component.UidType, component.DbqModelRelaType, component.DbqStateType, component.CounterType)) re := w.Entry(w.Create(component.DBQTag, component.UidType, component.DbqModelRelaType, component.DbqStateType, component.CounterType))
component.UidType.Set(re, &component.Uid{Id: uid}) component.UidType.Set(re, &component.Uid{Id: uid})

View File

@ -12,18 +12,28 @@ func Loading(w ecs.World, repo modelrepo.Repo) error {
singleton.LoadSingletons(w, repo) singleton.LoadSingletons(w, repo)
for _, s := range repo.GetEcses() { for _, s := range repo.GetEcses() {
// 加载道岔 // 加载道岔
loadTurnouts(w, s.GetTurnouts()) loadPoints(w, s.GetTurnouts())
// 加载继电器 // 加载继电器
loadRelays(w, s.GetRelays()) loadRelays(w, s.GetRelays())
// 加载断相保护器 // 加载断相保护器
loadDbqs(w, s.GetDbqs()) loadDbqs(w, s.GetDbqs())
// 加载联锁驱采卡
qckEntry, err := loadCiQck(w, s)
if err != nil {
return err
}
// 加载道岔电路和联锁驱采卡实体关联组件
err = buildEcStationPointsEccRela(w, s, qckEntry)
if err != nil {
return err
}
} }
return nil return nil
} }
func loadDbqs(w ecs.World, dbqs []model.DBQ) { func loadDbqs(w ecs.World, dbqs []model.Dbq) {
for _, d := range dbqs { for _, d := range dbqs {
NewDBQ(w, d) NewDbq(w, d)
} }
} }
@ -33,7 +43,7 @@ func loadRelays(w ecs.World, relays []model.Relay) {
} }
} }
func loadTurnouts(w ecs.World, points []model.Points) { func loadPoints(w ecs.World, points []model.Points) {
for _, p := range points { for _, p := range points {
NewPoints(w, p) NewPoints(w, p)
} }

View File

@ -2,6 +2,7 @@ package entity
import ( import (
"fmt" "fmt"
"unsafe"
"joylink.club/ecs" "joylink.club/ecs"
"joylink.club/rtsssimulation/component" "joylink.club/rtsssimulation/component"
@ -36,3 +37,140 @@ func NewPoints(w ecs.World, p model.Points) *ecs.Entry {
singleton.GetEntityUidIndex(w).Add(id, pe) singleton.GetEntityUidIndex(w).Add(id, pe)
return pe return pe
} }
const (
ZDJ9_2_CT_TDC = "TDC"
ZDJ9_2_TDC_DCJ = "DCJ"
ZDJ9_2_TDC_FCJ = "FCJ"
ZDJ9_2_TDC_YCJ = "YCJ"
ZDJ9_2_TDC_ZDBJ = "ZDBJ"
ZDJ9_2_TDC_ZFBJ = "ZFBJ"
ZDJ9_2_CT_TDFJ1 = "TDFJ1"
ZDJ9_2_TDFJ1_1DQJ = "1DQJ"
ZDJ9_2_TDFJ1_1DQJF = "1DQJF"
ZDJ9_2_TDFJ1_2DQJ = "2DQJ"
ZDJ9_2_TDFJ1_BHJ = "BHJ"
ZDJ9_2_TDFJ1_DBJ = "DBJ"
ZDJ9_2_TDFJ1_FBJ = "FBJ"
ZDJ9_2_TDFJ1_QDJ = "QDJ"
ZDJ9_2_TDFJ1_ZBHJ = "ZBHJ"
ZDJ9_2_TDFJ1_DBQ = "DBQ"
ZDJ9_2_CT_TDFJ2 = "TDFJ2"
ZDJ9_2_TDFJ2_1DQJ = "1DQJ"
ZDJ9_2_TDFJ2_1DQJF = "1DQJF"
ZDJ9_2_TDFJ2_2DQJ = "2DQJ"
ZDJ9_2_TDFJ2_BHJ = "BHJ"
ZDJ9_2_TDFJ2_DBJ = "DBJ"
ZDJ9_2_TDFJ2_FBJ = "FBJ"
ZDJ9_2_TDFJ2_DBQ = "DBQ"
)
// 构建道岔电子元件关系
func buildEcStationPointsEccRela(w ecs.World, s model.EcStation, qckEntry *ecs.Entry) error {
deccs := s.GetCiDeccs()
eui := singleton.GetEntityUidIndex(w)
for _, decc := range deccs {
if decc.IsPoints() {
pe := eui.Get(decc.Duid())
if pe == nil {
return fmt.Errorf("车站'%s'不存在道岔'%s'", s.Name(), decc.Duid())
}
eccs := decc.Eccs()
pm := component.PointsModelRelaType.Get(pe).M
if pm.IsZdj9_1() {
return fmt.Errorf("ZDJ9单机牵引电路未实现")
} else if pm.IsZdj9_2() { // ZDJ9双机牵引电路元件引用组件构建
pelec := &relation.Zdj9TwoElectronic{CiQck: qckEntry}
for _, ecc := range eccs {
switch ecc.Code() {
case ZDJ9_2_CT_TDC:
for _, ec := range ecc.Ecs() {
ee := eui.Get(ec.Uid().Id())
if ee == nil {
return fmt.Errorf("车站'%s'不存在电子元件'%s'", s.Name(), ec.Uid().Id())
}
switch ec.Code() {
case ZDJ9_2_TDC_DCJ:
pelec.TDC_DCJ = ee
case ZDJ9_2_TDC_FCJ:
pelec.TDC_FCJ = ee
case ZDJ9_2_TDC_YCJ:
pelec.TDC_YCJ = ee
case ZDJ9_2_TDC_ZDBJ:
pelec.TDC_ZDBJ = ee
case ZDJ9_2_TDC_ZFBJ:
pelec.TDC_ZFBJ = ee
default:
return fmt.Errorf("组合类型'%s'内未知的ZDJ9双机电路元器件编号: '%s'", ZDJ9_2_CT_TDC, ec.Code())
}
}
case ZDJ9_2_CT_TDFJ1:
for _, ec := range ecc.Ecs() {
ee := eui.Get(ec.Uid().Id())
if ee == nil {
return fmt.Errorf("车站'%s'不存在电子元件'%s'", s.Name(), ec.Uid().Id())
}
switch ec.Code() {
case ZDJ9_2_TDFJ1_1DQJ:
pelec.TDFJ1_1DQJ = ee
case ZDJ9_2_TDFJ1_1DQJF:
pelec.TDFJ1_1DQJF = ee
case ZDJ9_2_TDFJ1_2DQJ:
pelec.TDFJ1_2DQJ = ee
case ZDJ9_2_TDFJ1_BHJ:
pelec.TDFJ1_BHJ = ee
case ZDJ9_2_TDFJ1_DBJ:
pelec.TDFJ1_DBJ = ee
case ZDJ9_2_TDFJ1_FBJ:
pelec.TDFJ1_FBJ = ee
case ZDJ9_2_TDFJ1_DBQ:
pelec.TDFJ1_DBQ = ee
case ZDJ9_2_TDFJ1_QDJ:
pelec.TDFJ1_QDJ = ee
case ZDJ9_2_TDFJ1_ZBHJ:
pelec.TDFJ1_ZBHJ = ee
default:
return fmt.Errorf("组合类型'%s'内未知的ZDJ9双机电路元器件编号: '%s'", ZDJ9_2_CT_TDFJ1, ec.Code())
}
}
case ZDJ9_2_CT_TDFJ2:
for _, ec := range ecc.Ecs() {
ee := eui.Get(ec.Uid().Id())
if ee == nil {
return fmt.Errorf("车站'%s'不存在电子元件'%s'", s.Name(), ec.Uid().Id())
}
switch ec.Code() {
case ZDJ9_2_TDFJ2_1DQJ:
pelec.TDFJ2_1DQJ = ee
case ZDJ9_2_TDFJ2_1DQJF:
pelec.TDFJ2_1DQJF = ee
case ZDJ9_2_TDFJ2_2DQJ:
pelec.TDFJ2_2DQJ = ee
case ZDJ9_2_TDFJ2_BHJ:
pelec.TDFJ2_BHJ = ee
case ZDJ9_2_TDFJ2_DBJ:
pelec.TDFJ2_DBJ = ee
case ZDJ9_2_TDFJ2_FBJ:
pelec.TDFJ2_FBJ = ee
case ZDJ9_2_TDFJ2_DBQ:
pelec.TDFJ2_DBQ = ee
default:
return fmt.Errorf("组合类型'%s'内未知的ZDJ9双机电路元器件编号: '%s'", ZDJ9_2_CT_TDFJ2, ec.Code())
}
}
default:
return fmt.Errorf("未知的ZDJ9双机电路元器件组合类型: '%s'", ecc.Code())
}
}
nils := pelec.CheckNilReference()
if len(nils) > 0 {
return fmt.Errorf("车站'%s'的道岔'%s'电路电子元件存在空引用: %v", s.Name(), pm.Uid().Id(), nils)
}
pe.AddComponent(component.Zdj9TwoElectronicType, unsafe.Pointer(pelec))
} else {
return fmt.Errorf("未知的道岔牵引类型")
}
}
}
return nil
}

View File

@ -1,6 +0,0 @@
package model
type DBQ interface {
Model
Code() string
}

View File

@ -1,22 +1,43 @@
package model package model
// 电子元件
type Ec interface {
Model
// 编号
Code() string
}
// 开关 // 开关
type PowerSwitch interface { type PowerSwitch interface {
Model Ec
// 编号
Code()
} }
// 信号状态表示灯 // 信号状态表示灯
type Lamp interface { type Lamp interface {
Model Ec
// 编号
Code()
} }
// 蜂鸣器/报警电铃 // 蜂鸣器/报警电铃
type Buzzer interface { type Buzzer interface {
Model Ec
// 编号 }
Code()
// 继电器
type Relay interface {
Ec
// 是否无极继电器
IsWj() bool
// 是否有极继电器
IsYj() bool
// 是否偏极继电器
IsPj() bool
// 是否缓放继电器
IsHf() bool
// 获取缓放时间,单位ms
GetHfTime() int
}
// 断相保护器
type Dbq interface {
Ec
} }

View File

@ -21,16 +21,6 @@ const (
TPort_C Points_Port = 3 TPort_C Points_Port = 3
) )
// 道岔牵引类型
type PointsTractionType int
const (
// ZDJ9单机牵引
PTT_ZDJ9_1 PointsTractionType = 1
// ZDJ9双机牵引
PTT_ZDJ9_2 PointsTractionType = 2
)
// 道岔 // 道岔
type Points interface { type Points interface {
Model Model
@ -40,8 +30,10 @@ type Points interface {
GetBLinkPort() *LinkPort GetBLinkPort() *LinkPort
// 获取C方向连接的link端口 // 获取C方向连接的link端口
GetCLinkPort() *LinkPort GetCLinkPort() *LinkPort
// 获取牵引类型 // 是否为ZDJ9单机牵引道岔
GetTractionType() PointsTractionType IsZdj9_1() bool
// 是否为ZDJ9双机牵引道岔
IsZdj9_2() bool
// 获取转辙机数量 // 获取转辙机数量
GetZzjCount() int GetZzjCount() int
} }

View File

@ -1,42 +0,0 @@
package model
// 继电器位置
type Relay_Position int
const (
// 继电器位置-后(表示落下/反位)
RelayPos_H Relay_Position = 0
// 继电器位置-前(表示吸起/定位)
RelayPos_Q Relay_Position = 1
)
// 继电器型号
type Relay_Model int
const (
RelayModel_JPXC_1000 Relay_Model = 1
RelayModel_JPXC_1700 Relay_Model = 2
RelayModel_JWJXC_480 Relay_Model = 3
RelayModel_JWJXC_H125_80 Relay_Model = 4
RelayModel_JWXC_1700 Relay_Model = 5
RelayModel_JWXC_H340 Relay_Model = 6
RelayModel_JYJXC_160_260 Relay_Model = 7
RelayModel_JZXC_H18 Relay_Model = 8
)
// 继电器
type Relay interface {
Model
Code() string
Model() Relay_Model
// 是否无极继电器
IsWj() bool
// 是否有极继电器
IsYj() bool
// 是否偏极继电器
IsPj() bool
// 是否缓放继电器
IsHf() bool
// 获取缓放时间,单位ms
GetHfTime() int
}

View File

@ -25,28 +25,49 @@ type EcStation interface {
// 获取所有继电器 // 获取所有继电器
GetRelays() []Relay GetRelays() []Relay
// 获取所有断相保护器 // 获取所有断相保护器
GetDbqs() []DBQ GetDbqs() []Dbq
// 获取联锁驱采表 // 获取联锁驱采表
GetCiQCTable() GetCiQcb() CiQcb
// 获取联锁设备电子元件组合
GetCiDeccs() []CiDecc
}
// 联锁设备电子元件组合
type CiDecc interface {
// 是否道岔设备组合
IsPoints() bool
// 是否信号机设备组合
IsSignal() bool
// 设备uid
Duid() string
// 电子元件组合
Eccs() []Ecc
}
type Ecc interface {
// 组合类型编号
Code() string
// 组合关联的电子元件id
Ecs() []Ec
} }
// 联锁驱采表 // 联锁驱采表
type CiQCTable interface { type CiQcb interface {
// 驱动码位表(每一位所驱动的继电器uid) // 驱动码位表(每一位所驱动的继电器uid)
QD() []string QD() []string
// 采集码位表(每一位所采集的继电器位置) // 采集码位表(每一位所采集的继电器位置)
CJ() []CiCJ CJ() []CiCj
} }
// 联锁采集 // 联锁采集
type CiCJ interface { type CiCj interface {
CjPos() []CiCJPos CjPos() []CiCjPos
} }
// 联锁采集继电器位置 // 联锁采集继电器位置
type CiCJPos interface { type CiCjPos interface {
// 继电器uid // 继电器uid
RelayId() string RelayId() string
// 继电器位置 // 继电器位置,true:前位/吸起/定位,false:后位/落下/反位
Pos() Relay_Position Pos() bool
} }

View File

@ -23,13 +23,18 @@ type Turnout struct {
cdLink *Link cdLink *Link
} }
// GetZzjCount implements model.Points. // IsZdj9_1 implements model.Points.
func (*Turnout) GetZzjCount() int { func (*Turnout) IsZdj9_1() bool {
panic("unimplemented") panic("unimplemented")
} }
// GetTractionType implements model.Turnout. // IsZdj9_2 implements model.Points.
func (t *Turnout) GetTractionType() model.PointsTractionType { func (*Turnout) IsZdj9_2() bool {
panic("unimplemented")
}
// GetZzjCount implements model.Points.
func (*Turnout) GetZzjCount() int {
panic("unimplemented") panic("unimplemented")
} }