diff --git a/components/common.go b/components/common.go index 4a9fe2c..dffae36 100644 --- a/components/common.go +++ b/components/common.go @@ -14,8 +14,11 @@ var ModelStorageRefComponent = ecs.NewComponentType[cstate.ModelStorageRef]() // 身份组件 var DeviceIdentityComponent = ecs.NewComponentType[cstate.DeviceIdentity]() -// 持有实体标签的组件 -var EntityTagHandlerComponent = ecs.NewComponentType[cstate.EntityTagHandler]() +// 存储屏蔽门标签组件 +var PsdTagHandlerComponent = ecs.NewComponentType[cstate.EntityTagHandler]() + +// 存储继电器标签组件 +var RelayTagHandlerComponent = ecs.NewComponentType[cstate.EntityTagHandler]() // 可移动设备组件 var MovableDeviceStateComponent = ecs.NewComponentType[cstate.MovableDeviceState]() @@ -49,3 +52,6 @@ var TowPositionButtonStateComponent = ecs.NewComponentType[cstate.TowPositionBut // 继电器状态组件 var RelayStateComponent = ecs.NewComponentType[cstate.RelayState]() + +// 紧急停车按钮状态组件 +var EmpStateComponent = ecs.NewComponentType[cstate.EmpState]() diff --git a/components/cstate/status.pb.go b/components/cstate/status.pb.go index ca1397f..c237e1f 100644 --- a/components/cstate/status.pb.go +++ b/components/cstate/status.pb.go @@ -1014,6 +1014,56 @@ func (x *RelayState) GetActive() bool { return false } +// 紧急停车按钮状态 +// 没有区段继电器,有采集继电器 +type EmpState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 紧急停车按钮是否被按下 + Pressed bool `protobuf:"varint,1,opt,name=pressed,proto3" json:"pressed,omitempty"` +} + +func (x *EmpState) Reset() { + *x = EmpState{} + if protoimpl.UnsafeEnabled { + mi := &file_status_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EmpState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmpState) ProtoMessage() {} + +func (x *EmpState) ProtoReflect() protoreflect.Message { + mi := &file_status_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmpState.ProtoReflect.Descriptor instead. +func (*EmpState) Descriptor() ([]byte, []int) { + return file_status_proto_rawDescGZIP(), []int{14} +} + +func (x *EmpState) GetPressed() bool { + if x != nil { + return x.Pressed + } + return false +} + // 按钮状态 type ButtonState struct { state protoimpl.MessageState @@ -1027,7 +1077,7 @@ type ButtonState struct { func (x *ButtonState) Reset() { *x = ButtonState{} if protoimpl.UnsafeEnabled { - mi := &file_status_proto_msgTypes[14] + mi := &file_status_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1040,7 +1090,7 @@ func (x *ButtonState) String() string { func (*ButtonState) ProtoMessage() {} func (x *ButtonState) ProtoReflect() protoreflect.Message { - mi := &file_status_proto_msgTypes[14] + mi := &file_status_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1053,7 +1103,7 @@ func (x *ButtonState) ProtoReflect() protoreflect.Message { // Deprecated: Use ButtonState.ProtoReflect.Descriptor instead. func (*ButtonState) Descriptor() ([]byte, []int) { - return file_status_proto_rawDescGZIP(), []int{14} + return file_status_proto_rawDescGZIP(), []int{15} } func (x *ButtonState) GetPressDown() bool { @@ -1082,7 +1132,7 @@ type ButtonPressOperating struct { func (x *ButtonPressOperating) Reset() { *x = ButtonPressOperating{} if protoimpl.UnsafeEnabled { - mi := &file_status_proto_msgTypes[15] + mi := &file_status_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1095,7 +1145,7 @@ func (x *ButtonPressOperating) String() string { func (*ButtonPressOperating) ProtoMessage() {} func (x *ButtonPressOperating) ProtoReflect() protoreflect.Message { - mi := &file_status_proto_msgTypes[15] + mi := &file_status_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1108,7 +1158,7 @@ func (x *ButtonPressOperating) ProtoReflect() protoreflect.Message { // Deprecated: Use ButtonPressOperating.ProtoReflect.Descriptor instead. func (*ButtonPressOperating) Descriptor() ([]byte, []int) { - return file_status_proto_rawDescGZIP(), []int{15} + return file_status_proto_rawDescGZIP(), []int{16} } func (x *ButtonPressOperating) GetStart() bool { @@ -1154,7 +1204,7 @@ type ButtonConfirmOperating struct { func (x *ButtonConfirmOperating) Reset() { *x = ButtonConfirmOperating{} if protoimpl.UnsafeEnabled { - mi := &file_status_proto_msgTypes[16] + mi := &file_status_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1167,7 +1217,7 @@ func (x *ButtonConfirmOperating) String() string { func (*ButtonConfirmOperating) ProtoMessage() {} func (x *ButtonConfirmOperating) ProtoReflect() protoreflect.Message { - mi := &file_status_proto_msgTypes[16] + mi := &file_status_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1180,7 +1230,7 @@ func (x *ButtonConfirmOperating) ProtoReflect() protoreflect.Message { // Deprecated: Use ButtonConfirmOperating.ProtoReflect.Descriptor instead. func (*ButtonConfirmOperating) Descriptor() ([]byte, []int) { - return file_status_proto_rawDescGZIP(), []int{16} + return file_status_proto_rawDescGZIP(), []int{17} } func (x *ButtonConfirmOperating) GetConfirm() bool { @@ -1274,36 +1324,38 @@ var file_status_proto_rawDesc = []byte{ 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x32, 0x22, 0x24, 0x0a, 0x0a, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x2b, 0x0a, 0x0b, 0x42, 0x75, - 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x44, 0x6f, 0x77, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, - 0x65, 0x73, 0x73, 0x44, 0x6f, 0x77, 0x6e, 0x22, 0x84, 0x01, 0x0a, 0x14, 0x42, 0x75, 0x74, 0x74, - 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0b, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x22, 0x4a, - 0x0a, 0x16, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x4f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x2a, 0x81, 0x01, 0x0a, 0x0c, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x41, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x06, 0x0a, 0x02, 0x4e, - 0x6f, 0x10, 0x00, 0x12, 0x05, 0x0a, 0x01, 0x52, 0x10, 0x01, 0x12, 0x05, 0x0a, 0x01, 0x47, 0x10, - 0x02, 0x12, 0x05, 0x0a, 0x01, 0x59, 0x10, 0x03, 0x12, 0x05, 0x0a, 0x01, 0x57, 0x10, 0x04, 0x12, - 0x05, 0x0a, 0x01, 0x42, 0x10, 0x05, 0x12, 0x06, 0x0a, 0x02, 0x52, 0x59, 0x10, 0x06, 0x12, 0x06, - 0x0a, 0x02, 0x52, 0x57, 0x10, 0x07, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x47, 0x10, 0x08, 0x12, 0x06, - 0x0a, 0x02, 0x47, 0x59, 0x10, 0x09, 0x12, 0x06, 0x0a, 0x02, 0x59, 0x59, 0x10, 0x0a, 0x12, 0x06, - 0x0a, 0x02, 0x52, 0x46, 0x10, 0x0b, 0x12, 0x06, 0x0a, 0x02, 0x59, 0x46, 0x10, 0x0c, 0x12, 0x06, - 0x0a, 0x02, 0x47, 0x46, 0x10, 0x0d, 0x12, 0x06, 0x0a, 0x02, 0x57, 0x46, 0x10, 0x0e, 0x2a, 0x35, - 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x45, 0x6e, 0x75, - 0x6d, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x45, 0x41, 0x44, 0x5f, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, - 0x06, 0x48, 0x45, 0x41, 0x44, 0x5f, 0x41, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x45, 0x41, - 0x44, 0x5f, 0x42, 0x10, 0x02, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x63, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x24, 0x0a, 0x08, 0x45, 0x6d, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, + 0x22, 0x2b, 0x0a, 0x0b, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x73, 0x73, 0x44, 0x6f, 0x77, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x65, 0x73, 0x73, 0x44, 0x6f, 0x77, 0x6e, 0x22, 0x84, 0x01, + 0x0a, 0x14, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x77, 0x6e, + 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x72, 0x6d, 0x22, 0x4a, 0x0a, 0x16, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x2a, 0x81, 0x01, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x41, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x12, 0x06, 0x0a, 0x02, 0x4e, 0x6f, 0x10, 0x00, 0x12, 0x05, 0x0a, 0x01, 0x52, 0x10, 0x01, + 0x12, 0x05, 0x0a, 0x01, 0x47, 0x10, 0x02, 0x12, 0x05, 0x0a, 0x01, 0x59, 0x10, 0x03, 0x12, 0x05, + 0x0a, 0x01, 0x57, 0x10, 0x04, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x05, 0x12, 0x06, 0x0a, 0x02, + 0x52, 0x59, 0x10, 0x06, 0x12, 0x06, 0x0a, 0x02, 0x52, 0x57, 0x10, 0x07, 0x12, 0x06, 0x0a, 0x02, + 0x47, 0x47, 0x10, 0x08, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x59, 0x10, 0x09, 0x12, 0x06, 0x0a, 0x02, + 0x59, 0x59, 0x10, 0x0a, 0x12, 0x06, 0x0a, 0x02, 0x52, 0x46, 0x10, 0x0b, 0x12, 0x06, 0x0a, 0x02, + 0x59, 0x46, 0x10, 0x0c, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x46, 0x10, 0x0d, 0x12, 0x06, 0x0a, 0x02, + 0x57, 0x46, 0x10, 0x0e, 0x2a, 0x35, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x45, 0x41, 0x44, 0x5f, + 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x45, 0x41, 0x44, 0x5f, 0x41, 0x10, 0x01, 0x12, + 0x0a, 0x0a, 0x06, 0x48, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x10, 0x02, 0x42, 0x0a, 0x5a, 0x08, 0x2e, + 0x2f, 0x63, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1319,7 +1371,7 @@ func file_status_proto_rawDescGZIP() []byte { } var file_status_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_status_proto_goTypes = []interface{}{ (SignalAspect)(0), // 0: cstate.SignalAspect (TrainActiveEnum)(0), // 1: cstate.TrainActiveEnum @@ -1337,9 +1389,10 @@ var file_status_proto_goTypes = []interface{}{ (*TrainState)(nil), // 13: cstate.TrainState (*TowPositionButtonState)(nil), // 14: cstate.TowPositionButtonState (*RelayState)(nil), // 15: cstate.RelayState - (*ButtonState)(nil), // 16: cstate.ButtonState - (*ButtonPressOperating)(nil), // 17: cstate.ButtonPressOperating - (*ButtonConfirmOperating)(nil), // 18: cstate.ButtonConfirmOperating + (*EmpState)(nil), // 16: cstate.EmpState + (*ButtonState)(nil), // 17: cstate.ButtonState + (*ButtonPressOperating)(nil), // 18: cstate.ButtonPressOperating + (*ButtonConfirmOperating)(nil), // 19: cstate.ButtonConfirmOperating } var file_status_proto_depIdxs = []int32{ 0, // 0: cstate.SignalState.display:type_name -> cstate.SignalAspect @@ -1529,7 +1582,7 @@ func file_status_proto_init() { } } file_status_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ButtonState); i { + switch v := v.(*EmpState); i { case 0: return &v.state case 1: @@ -1541,7 +1594,7 @@ func file_status_proto_init() { } } file_status_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ButtonPressOperating); i { + switch v := v.(*ButtonState); i { case 0: return &v.state case 1: @@ -1553,6 +1606,18 @@ func file_status_proto_init() { } } file_status_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ButtonPressOperating); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_status_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ButtonConfirmOperating); i { case 0: return &v.state @@ -1571,7 +1636,7 @@ func file_status_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_status_proto_rawDesc, NumEnums: 2, - NumMessages: 17, + NumMessages: 18, NumExtensions: 0, NumServices: 0, }, diff --git a/creator/init_simulation.go b/creator/init_simulation.go index e296e16..a7d6ba1 100644 --- a/creator/init_simulation.go +++ b/creator/init_simulation.go @@ -83,7 +83,9 @@ func foreachModels(modelManager umi.IModelManager, deviceType umi.DeviceType, ea } } -//////////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////////// +// 设备继电器标签,即标记继电器属于哪个设备的 +type DeviceRelayTag struct{} // 创建模型仓库引用实体 func CreateModelStorageRefEntity(w ecs.World) *ecs.Entry { @@ -97,12 +99,16 @@ func CreateWorldTimeEntity(w ecs.World) *ecs.Entry { // 创建道岔实体 func CreateSwitchEntity(w ecs.World) *ecs.Entry { - return w.Create(components.DeviceIdentityComponent, components.SwitchRelayStateComponent, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent) + e := w.Create(components.DeviceIdentityComponent, components.SwitchRelayStateComponent, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent, components.RelayTagHandlerComponent) + components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: ecs.NewComponentType[DeviceRelayTag]()}) + return e } // 创建信号机实体 func CreateSignalEntity(w ecs.World) *ecs.Entry { - return w.Create(components.DeviceIdentityComponent, components.SignalStateComponent) + e := w.Create(components.DeviceIdentityComponent, components.SignalStateComponent, components.RelayTagHandlerComponent) + components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: ecs.NewComponentType[DeviceRelayTag]()}) + return e } // 创建物理区段实体 @@ -115,14 +121,15 @@ type PsdCellTag struct{} // 创建站台单侧屏蔽门实体 func CreatePsdEntity(w ecs.World) *ecs.Entry { - e := w.Create(components.DeviceIdentityComponent, components.PsdStateComponent, components.EntityTagHandlerComponent) - components.EntityTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: ecs.NewComponentType[PsdCellTag]()}) + e := w.Create(components.DeviceIdentityComponent, components.PsdStateComponent, components.PsdTagHandlerComponent, components.RelayTagHandlerComponent) + components.PsdTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: ecs.NewComponentType[PsdCellTag]()}) + components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: ecs.NewComponentType[DeviceRelayTag]()}) return e } // 创建屏蔽门cell实体 func CreatePsdCellEntity(w ecs.World, psdEntry *ecs.Entry) *ecs.Entry { - return w.Create(components.DeviceIdentityComponent, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent, components.EntityTagHandlerComponent.Get(psdEntry).Tag) + return w.Create(components.DeviceIdentityComponent, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent, components.PsdTagHandlerComponent.Get(psdEntry).Tag) } // 创建应答器实体 @@ -141,6 +148,14 @@ func CreateTowPosButtonEntity(w ecs.World) *ecs.Entry { } // 创建继电器实体 -func CreateRelayEntity(w ecs.World) *ecs.Entry { - return w.Create(components.DeviceIdentityComponent, components.RelayStateComponent) +// deviceEntry: 被继电器控制的设备 +func CreateRelayEntity(w ecs.World, deviceEntry *ecs.Entry) *ecs.Entry { + return w.Create(components.DeviceIdentityComponent, components.RelayStateComponent, components.RelayTagHandlerComponent.Get(deviceEntry).Tag) +} + +// 创建紧急停车按钮实体 +func CreateEmpEntity(w ecs.World) *ecs.Entry { + e := w.Create(components.DeviceIdentityComponent, components.EmpStateComponent, components.RelayTagHandlerComponent) + components.RelayTagHandlerComponent.Set(e, &cstate.EntityTagHandler{Tag: ecs.NewComponentType[DeviceRelayTag]()}) + return e } diff --git a/operate/emp_operation.go b/operate/emp_operation.go new file mode 100644 index 0000000..8acb132 --- /dev/null +++ b/operate/emp_operation.go @@ -0,0 +1,42 @@ +package operate + +import ( + "fmt" + + "github.com/yohamta/donburi/filter" + "joylink.club/ecs" + "joylink.club/rtsssimulation/components" + "joylink.club/rtsssimulation/system" +) + +// 紧急停车按钮查询 +var empQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.EmpStateComponent)) + +func findEmpEntry(world ecs.World, empId string) (*ecs.Entry, error) { + empEntry := system.QueryEntityById(world, empQuery, empId) + if empEntry == nil { + return nil, fmt.Errorf("紧急停车按钮[%s]实体不存在", empId) + } else { + return empEntry, nil + } +} + +// 激活紧急停车按钮 +func FireEmpPressed(world ecs.World, empId string) error { + entry, err := findEmpEntry(world, empId) + if err != nil { + return err + } + components.EmpStateComponent.Get(entry).Pressed = true + return nil +} + +// 复位紧急停车按钮 +func FireEmpReset(world ecs.World, empId string) error { + entry, err := findEmpEntry(world, empId) + if err != nil { + return err + } + components.EmpStateComponent.Get(entry).Pressed = false + return nil +} diff --git a/operate/psd_operation.go b/operate/psd_operation.go index e8d820e..009fc84 100644 --- a/operate/psd_operation.go +++ b/operate/psd_operation.go @@ -48,7 +48,7 @@ func FirePsdOperation(world ecs.World, psdId string, closeOpt bool) error { return err } //屏蔽门标签 - psdTag := components.EntityTagHandlerComponent.Get(psdEntry).Tag + psdTag := components.PsdTagHandlerComponent.Get(psdEntry).Tag psdCellQuery := ecs.NewQuery(filter.Contains(psdTag)) var errPercent error = nil psdCellQuery.Each(world, func(psdCellEntry *ecs.Entry) { @@ -76,7 +76,7 @@ func FirePsdCellOperation(world ecs.World, psdId string, psdCellId string, close return err } //屏蔽门标签 - psdTag := components.EntityTagHandlerComponent.Get(psdEntry).Tag + psdTag := components.PsdTagHandlerComponent.Get(psdEntry).Tag psdCellQuery := ecs.NewQuery(filter.Contains(psdTag)) psdCellEntry := system.QueryEntityById(world, psdCellQuery, psdCellId) if psdCellEntry == nil { diff --git a/proto/src/component/status.proto b/proto/src/component/status.proto index 37f92bc..5e3e471 100644 --- a/proto/src/component/status.proto +++ b/proto/src/component/status.proto @@ -188,6 +188,15 @@ message RelayState{ /////////////////////////////////////////////////////////////////////// +// 紧急停车按钮状态 +// 没有区段继电器,有采集继电器 +message EmpState{ + //紧急停车按钮是否被按下 + bool pressed = 1; +} + +/////////////////////////////////////////////////////////////////////// + // 按钮状态 message ButtonState { // 是否按下 diff --git a/system/debug_system.go b/system/debug_system.go index 87c0152..9688ebe 100644 --- a/system/debug_system.go +++ b/system/debug_system.go @@ -67,11 +67,11 @@ func debugTowPosButton(w ecs.World) { // 屏蔽门状态 func debugPsd(w ecs.World) { - psdQuery := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.PsdStateComponent, components.EntityTagHandlerComponent)) + psdQuery := ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.PsdStateComponent, components.PsdTagHandlerComponent)) psdQuery.Each(w, func(e *ecs.Entry) { psdId := components.DeviceIdentityComponent.Get(e).Id psdState := components.PsdStateComponent.Get(e) - psdTag := components.EntityTagHandlerComponent.Get(e).Tag + psdTag := components.PsdTagHandlerComponent.Get(e).Tag fmt.Printf("屏蔽门[%s] ,全关=%t ,全开=%t ,互锁解除=%t > ", psdId, psdState.AllClosed, psdState.AllOpened, psdState.InterlockReleased) // psdCellQuery := ecs.NewQuery(filter.Contains(psdTag)) diff --git a/system/psd_system.go b/system/psd_system.go index 0aae36d..4f6edda 100644 --- a/system/psd_system.go +++ b/system/psd_system.go @@ -7,7 +7,7 @@ import ( "joylink.club/rtsssimulation/components/cstate" ) -var PsdQuery = ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.PsdStateComponent, components.EntityTagHandlerComponent)) +var PsdQuery = ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.PsdStateComponent, components.PsdTagHandlerComponent)) const ( //屏蔽门完全关闭 @@ -27,7 +27,7 @@ func NewPsdSystem() *PsdSystem { // world 执行 func (me *PsdSystem) Update(world ecs.World) { PsdQuery.Each(world, func(psdEntry *ecs.Entry) { - psdTag := components.EntityTagHandlerComponent.Get(psdEntry).Tag + psdTag := components.PsdTagHandlerComponent.Get(psdEntry).Tag psdCellQuery, ok := me.cellsQuery[psdTag] if !ok { psdCellQuery = ecs.NewQuery(filter.Contains(psdTag, components.PercentageDeviceStateComponent, components.MovableDeviceStateComponent)) diff --git a/system/signal_relay_system.go b/system/signal_relay_system.go new file mode 100644 index 0000000..d761749 --- /dev/null +++ b/system/signal_relay_system.go @@ -0,0 +1,45 @@ +package system + +import ( + "github.com/yohamta/donburi/filter" + "joylink.club/ecs" + "joylink.club/rtsssimulation/components" + "joylink.club/rtsssimulation/umi" +) + +// 信号机继电器系统 +type SignalRelaySystem struct { + //继电器系统基类 + relaySystem + //信号机查询 + query *ecs.Query +} + +func NewSignalReplaySystem() *SignalRelaySystem { + return &SignalRelaySystem{ + relaySystem: relaySystem{relayQuery: make(map[string]*ecs.Query)}, + query: ecs.NewQuery(filter.Contains(components.DeviceIdentityComponent, components.SignalStateComponent)), + } +} + +// world 执行 +func (me *SignalRelaySystem) Update(world ecs.World) { + //迭代所有信号机 + me.query.Each(world, func(signalEntry *ecs.Entry) { + //key-继电器作用名,value-继电器实体 + usageRelayMapper := make(map[string]*ecs.Entry) + //迭代一个信号机关联的所有继电器 + me.getDeviceRelayQuery(signalEntry).Each(world, func(signalRelayEntry *ecs.Entry) { + relayId := components.DeviceIdentityComponent.Get(signalRelayEntry).Id + relayModel := (WorldModelStorage(world).FindById(relayId)).(umi.IRelayModel) + usageRelayMapper[relayModel.UsageName()] = signalRelayEntry + }) + //根据具体业务逻辑处理继电器 + me.dealWithRelays(world, signalEntry, usageRelayMapper) + }) +} + +// 根据具体业务逻辑处理继电器 +func (me *SignalRelaySystem) dealWithRelays(world ecs.World, signalEntry *ecs.Entry, relays map[string]*ecs.Entry) { + +} diff --git a/system/system.go b/system/system.go index 47465ba..18433df 100644 --- a/system/system.go +++ b/system/system.go @@ -33,8 +33,8 @@ func simpleRecover() { recover() } -/////////////////////////////////////////////////////////////////////////// - +// ///////////////////////////////////////////////////////////////////////// +// 模型仓库查询 var worldModelStorageQuery *ecs.Query = ecs.NewQuery(filter.Contains(components.ModelStorageRefComponent)) func WorldModelStorage(world ecs.World) umi.IModelManager { @@ -45,3 +45,21 @@ func WorldModelStorage(world ecs.World) umi.IModelManager { return nil } } + +// ////////////////////////////////////////////////////////////////////////// +// 继电器系统 +type relaySystem struct { + // key-设备id + relayQuery map[string]*ecs.Query +} + +// 获取设备的相关继电器的查询 +func (me *relaySystem) getDeviceRelayQuery(deviceEntry *ecs.Entry) *ecs.Query { + id := components.DeviceIdentityComponent.Get(deviceEntry).Id + query, ok := me.relayQuery[id] + if !ok { + query = ecs.NewQuery(filter.Contains(components.RelayTagHandlerComponent.Get(deviceEntry).Tag)) + me.relayQuery[id] = query + } + return query +} diff --git a/umi/model_umi.go b/umi/model_umi.go index 15863fd..b2695cc 100644 --- a/umi/model_umi.go +++ b/umi/model_umi.go @@ -109,9 +109,18 @@ type IPsdModel interface { AllDeviceCells() []IDeviceModel } +//////////////////////////////////////////////////////////// + // 继电器模型 // 继电器按作用分类:驱动继电器、采集继电器 type IRelayModel interface { //该继电器管理的设备 ManagedDevice() IDeviceModel + //true-驱动继电器;false-采集继电器 + IsDriver() bool + //继电器作用名称,同一个设备的继电器的作用名称不能重复 + //如DJ-12、DDJ-83 + UsageName() string } + +/////////////////////////////////////////////////////////////