基于道岔电路功能探索ECS架构对实体引用的场景下合理的代码结构

This commit is contained in:
walker 2023-09-22 18:33:01 +08:00
parent b7bec3ee43
commit 4031539095
7 changed files with 195 additions and 0 deletions

26
component/common.go Normal file
View File

@ -0,0 +1,26 @@
package component
import "joylink.club/ecs"
// 两位置转换组件
type TwoPositionTransform struct {
Pos int // 当前位置百分比,[0, 10000],两位小数
Speed int
}
var TwoPositionTransformType = ecs.NewComponentType[TwoPositionTransform]()
// 仅有两状态的组件
type BitState struct {
Val bool
}
var BitStateType = ecs.NewComponentType[BitState]()
// 倒数组件
type CountDown struct {
Val int // 当前值
Dv int // 每次递减的值
}
var CountDownType = ecs.NewComponentType[CountDown]()

18
component/relay.go Normal file
View File

@ -0,0 +1,18 @@
package component
import "joylink.club/ecs"
// 无极继电器和偏极继电器稳态为落下,也就是后接点(8组采集接点中的1,3接点1为中接点)吸气为前接点1,2接点
// 有极继电器是定位反位双稳态(有永久磁钢),前接点为定位,后接点为反位
// 有极继电器对于道岔中的2DQJ励磁接点12接通为反位34接通为定位
// 定义继电器状态时false表示落下/反位/后接点true表示吸起/定位/前接点
// 继电器标签
var RelayTag = ecs.NewTag()
// 继电器控制请求组件
type RelayActionRequest struct {
Xq bool // true吸起
}
var RelayActionRequestType = ecs.NewComponentType[RelayActionRequest]()

26
component/turnout.go Normal file
View File

@ -0,0 +1,26 @@
package component
import "joylink.club/ecs"
// 道岔标签
var TurnoutTag = ecs.NewTag()
// ZDJ9单机电路元器件
type Zdj9_1_Electronic struct {
TDC_YCJ *ecs.Entry // 运行操作继电器
TDC_DCJ *ecs.Entry // 定操继电器
TDC_FCJ *ecs.Entry // 反操继电器
TDFJ_BB *ecs.Entry // 道岔表示变压器
TDFJ_1DQJ *ecs.Entry // 一启动继电器
TDFJ_BHJ *ecs.Entry // 保护继电器
TDFJ_2DQJ *ecs.Entry // 二启动继电器
TDFJ_1DQJF *ecs.Entry // 一启动复示继电器
TDFJ_DBJ *ecs.Entry // 定位表示继电器
TDFJ_FBJ *ecs.Entry // 反位表示继电器
TDFJ_R1 *ecs.Entry // 电阻
}
// ZDJ9单机电路元器件组件类型
var Zdj9_1_ElectronicType = ecs.NewComponentType[Zdj9_1_Electronic]()

6
consts/constant.go Normal file
View File

@ -0,0 +1,6 @@
package consts
const (
PosMin = 0
PosMax = 10000
)

View File

@ -0,0 +1,53 @@
// /ZDJ9单机转辙机电路系统
package circuit_sys
import (
"fmt"
"unsafe"
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
)
// 系统定义
type ZDJ9_1 struct {
query *ecs.Query
}
func NewZdj9_1() *ZDJ9_1 {
return &ZDJ9_1{
query: ecs.NewQuery(filter.Contains(component.Zdj9_1_ElectronicType)),
}
}
func (zdj9 *ZDJ9_1) Update(w ecs.World) {
fmt.Println("ZDJ9单机牵引控制电路更新")
zdj9.query.Each(w, func(entry *ecs.Entry) {
elec := component.Zdj9_1_ElectronicType.Get(entry)
// TDFJ_1DQJ励磁电路
exciteTDFJ_1DQJ(elec)
// TDFJ_1DQJ监控电路
})
}
// TDFJ_1DQJ励磁电路逻辑
func exciteTDFJ_1DQJ(elec *component.Zdj9_1_Electronic) {
// 暂时先实现非应急按钮操作
tdfj_1dqj := component.BitStateType.Get(elec.TDFJ_1DQJ)
if tdfj_1dqj.Val { // 已经吸起,结束
return
}
if elec.TDFJ_1DQJ.HasComponent(component.RelayActionRequestType) { // 如果正在吸起,结束
return
}
ycj := component.BitStateType.Get(elec.TDC_YCJ)
dcj := component.BitStateType.Get(elec.TDC_DCJ)
fcj := component.BitStateType.Get(elec.TDC_FCJ)
tdfj_2dqj := component.BitStateType.Get(elec.TDFJ_2DQJ)
if ycj.Val { // 允许操作继电器已经吸起
if (tdfj_2dqj.Val && fcj.Val) || (tdfj_2dqj.Val && dcj.Val) { // 电路导通,添加吸起请求
elec.TDFJ_1DQJ.AddComponent(component.RelayActionRequestType, unsafe.Pointer(&component.RelayActionRequest{Xq: true}))
}
}
}

View File

@ -0,0 +1,33 @@
package device_sys
import (
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
)
type RelaySys struct {
query *ecs.Query
}
func NewRelaySys() *RelaySys {
return &RelaySys{
query: ecs.NewQuery(filter.Contains(component.RelayTag, component.RelayActionRequestType, component.BitStateType)),
}
}
func (rs *RelaySys) Update(w ecs.World) {
rs.query.Each(w, func(entry *ecs.Entry) {
// 查询实体是哪种继电器类型,根据继电器类型处理继电器吸起落下逻辑(暂时先简化直接处理)
req := component.RelayActionRequestType.Get(entry)
state := component.BitStateType.Get(entry)
if req.Xq {
state.Val = true
} else {
state.Val = false
}
if req.Xq == state.Val { // 执行完毕,删除请求组件
entry.RemoveComponent(component.RelayActionRequestType)
}
})
}

View File

@ -0,0 +1,33 @@
package physics_sys
import (
"github.com/yohamta/donburi/filter"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/consts"
)
type TwoPositionMovementSys struct {
query *ecs.Query
}
func NewTwoPositionMovementSys() *TwoPositionMovementSys {
return &TwoPositionMovementSys{
query: ecs.NewQuery(filter.Contains(component.TwoPositionTransformType)),
}
}
// 更新位置
func (tp *TwoPositionMovementSys) Update(w ecs.World) {
tp.query.Each(w, func(entry *ecs.Entry) {
position := component.TwoPositionTransformType.Get(entry)
if position.Speed != 0 {
position.Pos += position.Speed
if position.Pos < consts.PosMin {
position.Pos = consts.PosMin
} else if position.Pos > consts.PosMax {
position.Pos = consts.PosMax
}
}
})
}