diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/ATSMessageCollectAndDispatcher.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/ATSMessageCollectAndDispatcher.java index e314f2997..9c04db9b7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/ATSMessageCollectAndDispatcher.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/ATSMessageCollectAndDispatcher.java @@ -21,6 +21,7 @@ import club.joylink.rtss.vo.client.WebSocketMessageType; import club.joylink.rtss.vo.client.factory.SocketMessageFactory; import club.joylink.rtss.websocket.StompMessageService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @@ -33,14 +34,14 @@ import java.util.stream.Collectors; @Component public class ATSMessageCollectAndDispatcher { - @Autowired - private Joylink3DMessageService joylink3DMessageService; + @Autowired + private Joylink3DMessageService joylink3DMessageService; - @Autowired - private StompMessageService stompMessageService; + @Autowired + private StompMessageService stompMessageService; - @Autowired - private ApplicationContext applicationContext; + @Autowired + private ApplicationContext applicationContext; // public void run(Simulation simulation) { //// long start = System.currentTimeMillis(); @@ -62,222 +63,223 @@ public class ATSMessageCollectAndDispatcher { //// System.out.println(String.format("收集并发送设备状态用时: [%s ms]", (end - start))); // } - /** - * 收集仿真所有设备状态并发送给仿真用户 - */ - public void collectAllAndSend(Simulation simulation) { - List deviceStatuses = collectAll(simulation); - // 构建并发送设备状态消息 - SocketMessageVO> deviceStatusMessage = - SocketMessageFactory.buildSimulationDeviceStatusesMessage(simulation.getId(), deviceStatuses); - Set sessions = simulation.getSimulationUserIds(); - stompMessageService.sendToUser(sessions, deviceStatusMessage); - } + /** + * 收集仿真所有设备状态并发送给仿真用户 + */ + public void collectAllAndSend(Simulation simulation) { + List deviceStatuses = collectAll(simulation); + // 构建并发送设备状态消息 + SocketMessageVO> deviceStatusMessage = + SocketMessageFactory.buildSimulationDeviceStatusesMessage(simulation.getId(), deviceStatuses); + Set sessions = simulation.getSimulationUserIds(); + stompMessageService.sendToUser(sessions, deviceStatusMessage); + } - /** - * 收集仿真所有设备状态 - */ - public List collectAll(Simulation simulation) { - List totalList = new ArrayList<>(); - SimulationDataRepository repository = simulation.getRepository(); - Map deviceMap = repository.getDeviceMap(); - deviceMap.values().forEach(device -> { - DeviceStatus deviceStatus = repository.findStatusByCode(device.getCode()); - if (Objects.isNull(deviceStatus)) { - deviceStatus = buildDeviceStatus(device); - if (Objects.nonNull(deviceStatus)) { - repository.addDeviceInfo(deviceStatus); - totalList.add(deviceStatus.convert2VO(device)); - } - } else { - DeviceStatusVO statusVO = buildDeviceStatusVO(device); - if (deviceStatus.compareAndChange(device, statusVO)) { - totalList.add(statusVO); - } - } - }); - // 列车状态 - List trainList = repository.getSuperviseTrainList(); - trainList.forEach(train -> { - TrainStatus trainStatus = repository.findStatusByCode(train.getGroupNumber(), TrainStatus.class); - if (Objects.isNull(trainStatus)) { + /** + * 收集仿真所有设备状态 + */ + public List collectAll(Simulation simulation) { + List totalList = new ArrayList<>(); + SimulationDataRepository repository = simulation.getRepository(); + Map deviceMap = repository.getDeviceMap(); + deviceMap.values().forEach(device -> { + DeviceStatus deviceStatus = repository.findStatusByCode(device.getCode()); + if (Objects.isNull(deviceStatus)) { + deviceStatus = buildDeviceStatus(device); + if (Objects.nonNull(deviceStatus)) { + repository.addDeviceInfo(deviceStatus); + totalList.add(deviceStatus.convert2VO(device)); + } + } else { + DeviceStatusVO statusVO = buildDeviceStatusVO(device); + if (deviceStatus.compareAndChange(device, statusVO)) { + totalList.add(statusVO); + } + } + }); + // 列车状态 + List trainList = repository.getSuperviseTrainList(); + trainList.forEach(train -> { + TrainStatus trainStatus = repository.findStatusByCode(train.getGroupNumber(), TrainStatus.class); + if (Objects.isNull(trainStatus)) { // if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){ - if(Objects.equals(simulation.getProject(),MapPrdTypeEnum.YJDDZH.name())){ - trainStatus = new YJDDZHTrainStatus(train); - }else{ - trainStatus = new TrainStatus(train); - } - repository.addDeviceInfo(trainStatus); - totalList.add(trainStatus.convert2VO(train)); - } else { - DeviceStatusVO statusVO; + if (Objects.equals(simulation.getProject(), MapPrdTypeEnum.YJDDZH.name())) { + trainStatus = new YJDDZHTrainStatus(train); + } else { + trainStatus = new TrainStatus(train); + } + repository.addDeviceInfo(trainStatus); + totalList.add(trainStatus.convert2VO(train)); + } else { + DeviceStatusVO statusVO; // if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){ - if(Objects.equals(simulation.getProject(),MapPrdTypeEnum.YJDDZH.name())){ - statusVO = new YJDDZHTrainStatusVO(train); - }else{ - statusVO = new TrainStatusVO(train); - } - if (trainStatus.compareAndChange(train, statusVO)) { - totalList.add(statusVO); - } - } - }); - // 回库删除的列车状态 - List inboundTrainList = new ArrayList<>(); - List trainStatusList = repository.getTrainStatusList(); - if (!CollectionUtils.isEmpty(trainStatusList)) { - for (TrainStatus trainStatus : trainStatusList) { - TrainInfo trainInfo = repository.findSupervisedTrainByGroup(trainStatus.getGroupNumber()); - if (Objects.isNull(trainInfo)) { - totalList.add(TrainStatusVO.buildDispose(trainStatus.getGroupNumber())); - inboundTrainList.add(trainStatus); - repository.deleteDeviceStatus(trainStatus.getCode()); - } - } + if (Objects.equals(simulation.getProject(), MapPrdTypeEnum.YJDDZH.name())) { + statusVO = new YJDDZHTrainStatusVO(train); + } else { +// statusVO = new TrainStatusVO(train); + statusVO = new TrainStatusVO(trainStatus); } - joylink3DMessageService.handleTrainInbound(simulation, inboundTrainList); - return totalList; - } - - private DeviceStatus buildDeviceStatus(MapElement device) { - DeviceStatus status = null; - switch (device.getDeviceType()) { - case SECTION: - status = new SectionStatus((Section) device); - break; - case SWITCH: - status = new SwitchStatus((Switch) device); - break; - case SIGNAL: - status = new SignalStatus((Signal) device); - break; - case STATION: - status = new StationStatus((Station) device); - break; - case STAND: - status = new StandStatus((Stand) device); - break; - case PSD: - status = new PSDStatus((PSD) device); - break; - case ZC: - status = new ZCStatus((ZC) device); - break; - case ROUTE: - status = new RouteStatus((Route) device); - break; - case OVERLAP: { - status = new OverlapStatus((RouteOverlap) device); - break; - } - case CYCLE: - status = new CycleStatus((Cycle) device); - break; - case DIRECTION_ROD: - status = new DirectionRodStatus((DirectionRod) device); - break; - case CATENARY: - status = new CatenaryStatus((Catenary) device); - break; - - case STATION_DIRECTION: - status = new StationDirectionStatus((StationDirection) device); - break; + if (trainStatus.compareAndChange(train, statusVO)) { + totalList.add(statusVO); } - return status; - } - - private DeviceStatusVO buildDeviceStatusVO(MapElement device) { - DeviceStatusVO status = null; - switch (device.getDeviceType()) { - case SECTION: - status = new SectionStatusVO((Section) device); - break; - case SWITCH: - status = new SwitchStatusVO((Switch) device); - break; - case SIGNAL: - status = new SignalStatusVO((Signal) device); - break; - case STATION: - status = new StationStatusVO((Station) device); - break; - case STAND: - status = new StandStatusVO((Stand) device); - break; - case PSD: - status = new PSDStatusVO((PSD) device); - break; - case ZC: - status = new ZCStatusVO((ZC) device); - break; - case ROUTE: - status = new RouteStatusVO((Route) device); - break; - case OVERLAP: { - status = new OverlapStatusVO((RouteOverlap) device); - break; - } - case CYCLE: - status = new CycleStatusVO((Cycle) device); - break; - case DIRECTION_ROD: - status = new DirectionRodStatusVO((DirectionRod) device); - break; - case CATENARY: - status = new CatenaryStatusVO((Catenary) device); - break; - - case STATION_DIRECTION: - status = new StationDirectionStatusVO((StationDirection) device); - break; + } + }); + // 回库删除的列车状态 + List inboundTrainList = new ArrayList<>(); + List trainStatusList = repository.getTrainStatusList(); + if (!CollectionUtils.isEmpty(trainStatusList)) { + for (TrainStatus trainStatus : trainStatusList) { + TrainInfo trainInfo = repository.findSupervisedTrainByGroup(trainStatus.getGroupNumber()); + if (Objects.isNull(trainInfo)) { + totalList.add(TrainStatusVO.buildDispose(trainStatus.getGroupNumber())); + inboundTrainList.add(trainStatus); + repository.deleteDeviceStatus(trainStatus.getCode()); } - return status; + } } + joylink3DMessageService.handleTrainInbound(simulation, inboundTrainList); + return totalList; + } - /** - * 列车运行数据 - */ - public void sendTrainRunData(Simulation simulation, RealRun realRun) { - stompMessageService.sendToUser(simulation.getSimulationUserIds(), - SocketMessageFactory.build(WebSocketMessageType.Simulation_RunFact, - simulation.getId(), Arrays.asList(realRun))); - } + private DeviceStatus buildDeviceStatus(MapElement device) { + DeviceStatus status = null; + switch (device.getDeviceType()) { + case SECTION: + status = new SectionStatus((Section) device); + break; + case SWITCH: + status = new SwitchStatus((Switch) device); + break; + case SIGNAL: + status = new SignalStatus((Signal) device); + break; + case STATION: + status = new StationStatus((Station) device); + break; + case STAND: + status = new StandStatus((Stand) device); + break; + case PSD: + status = new PSDStatus((PSD) device); + break; + case ZC: + status = new ZCStatus((ZC) device); + break; + case ROUTE: + status = new RouteStatus((Route) device); + break; + case OVERLAP: { + status = new OverlapStatus((RouteOverlap) device); + break; + } + case CYCLE: + status = new CycleStatus((Cycle) device); + break; + case DIRECTION_ROD: + status = new DirectionRodStatus((DirectionRod) device); + break; + case CATENARY: + status = new CatenaryStatus((Catenary) device); + break; - /** - * 仿真设备操作消息 - */ - public void handlerOperateMessage(Simulation simulation, OperationMessage operationMessage) { - SocketMessageVO socketMessageVO = - SocketMessageFactory.build(WebSocketMessageType.Simulation_ApplyHandle, simulation.getId(), operationMessage); - Set humanMembers = operationMessage.getTargetMembers().stream().filter(m -> !m.isRobot()).collect(Collectors.toSet()); - //当在场景实训设计中,并且无真人成员时,将数据暂存,等待后续角色有人扮演时再发送 - if (simulation.isInSceneTraining() && CollectionUtils.isEmpty(humanMembers)) { - for (SimulationMember targetMember : operationMessage.getTargetMembers()) { - targetMember.getUnreceivedMessages().offer(socketMessageVO); - } - return; - } - if (CollectionUtils.isEmpty(humanMembers)) { - //目标都是机器人,选择一个机器人发送事件处理 - applicationContext.publishEvent(new SimulationOperationMessageEvent(this, simulation, operationMessage)); - return; - } - //目标成员有真人,推送对应真人处理 - stompMessageService.sendToUser(humanMembers.stream().map(SimulationMember::getUserId).collect(Collectors.toSet()), socketMessageVO); + case STATION_DIRECTION: + status = new StationDirectionStatus((StationDirection) device); + break; } + return status; + } - /** - * 同步仿真系统时间给客户端 - */ - public void syncTime(Simulation simulation) { - Set sessions = simulation.getSimulationUserIds(); - SocketMessageVO timeSyncMessage = SocketMessageFactory.buildSimulationTimeSyncMessage(simulation); - stompMessageService.sendToUser(sessions, timeSyncMessage); - } + private DeviceStatusVO buildDeviceStatusVO(MapElement device) { + DeviceStatusVO status = null; + switch (device.getDeviceType()) { + case SECTION: + status = new SectionStatusVO((Section) device); + break; + case SWITCH: + status = new SwitchStatusVO((Switch) device); + break; + case SIGNAL: + status = new SignalStatusVO((Signal) device); + break; + case STATION: + status = new StationStatusVO((Station) device); + break; + case STAND: + status = new StandStatusVO((Stand) device); + break; + case PSD: + status = new PSDStatusVO((PSD) device); + break; + case ZC: + status = new ZCStatusVO((ZC) device); + break; + case ROUTE: + status = new RouteStatusVO((Route) device); + break; + case OVERLAP: { + status = new OverlapStatusVO((RouteOverlap) device); + break; + } + case CYCLE: + status = new CycleStatusVO((Cycle) device); + break; + case DIRECTION_ROD: + status = new DirectionRodStatusVO((DirectionRod) device); + break; + case CATENARY: + status = new CatenaryStatusVO((Catenary) device); + break; - public void addJobs(Simulation simulation) { - simulation.addJob(SimulationModule.SYNC_TIME.name(), () -> syncTime(simulation), SimulationConstants.SYNC_TIME_RATE); - simulation.addFixedRateJob(SimulationModule.MESSAGE.name(), () -> collectAllAndSend(simulation), SimulationConstants.SEND_CLIENT_RATE); + case STATION_DIRECTION: + status = new StationDirectionStatusVO((StationDirection) device); + break; } + return status; + } + + /** + * 列车运行数据 + */ + public void sendTrainRunData(Simulation simulation, RealRun realRun) { + stompMessageService.sendToUser(simulation.getSimulationUserIds(), + SocketMessageFactory.build(WebSocketMessageType.Simulation_RunFact, + simulation.getId(), Arrays.asList(realRun))); + } + + /** + * 仿真设备操作消息 + */ + public void handlerOperateMessage(Simulation simulation, OperationMessage operationMessage) { + SocketMessageVO socketMessageVO = + SocketMessageFactory.build(WebSocketMessageType.Simulation_ApplyHandle, simulation.getId(), operationMessage); + Set humanMembers = operationMessage.getTargetMembers().stream().filter(m -> !m.isRobot()).collect(Collectors.toSet()); + //当在场景实训设计中,并且无真人成员时,将数据暂存,等待后续角色有人扮演时再发送 + if (simulation.isInSceneTraining() && CollectionUtils.isEmpty(humanMembers)) { + for (SimulationMember targetMember : operationMessage.getTargetMembers()) { + targetMember.getUnreceivedMessages().offer(socketMessageVO); + } + return; + } + if (CollectionUtils.isEmpty(humanMembers)) { + //目标都是机器人,选择一个机器人发送事件处理 + applicationContext.publishEvent(new SimulationOperationMessageEvent(this, simulation, operationMessage)); + return; + } + //目标成员有真人,推送对应真人处理 + stompMessageService.sendToUser(humanMembers.stream().map(SimulationMember::getUserId).collect(Collectors.toSet()), socketMessageVO); + } + + /** + * 同步仿真系统时间给客户端 + */ + public void syncTime(Simulation simulation) { + Set sessions = simulation.getSimulationUserIds(); + SocketMessageVO timeSyncMessage = SocketMessageFactory.buildSimulationTimeSyncMessage(simulation); + stompMessageService.sendToUser(sessions, timeSyncMessage); + } + + public void addJobs(Simulation simulation) { + simulation.addJob(SimulationModule.SYNC_TIME.name(), () -> syncTime(simulation), SimulationConstants.SYNC_TIME_RATE); + simulation.addFixedRateJob(SimulationModule.MESSAGE.name(), () -> collectAllAndSend(simulation), SimulationConstants.SEND_CLIENT_RATE); + } }