/// <summary> /// Filter routes by options, does not check "BlockEnabled" option. /// See FilterByBlockEnabled() /// </summary> /// <param name="routeList"></param> /// <param name="sideToLeave"></param> /// <param name="locData"></param> /// <returns></returns> public RouteList FilterByAllowedOptions( RouteList routeList, SideMarker sideToLeave, Locomotives.Data locData) { var res = new RouteList(); foreach (var it in routeList) { var targetBlock = it.Blocks[1]; var targetBlockIdentifier = targetBlock.identifier; if (string.IsNullOrEmpty(targetBlockIdentifier)) { continue; } var targetFbData = GetFeedbackDataOf(targetBlockIdentifier, sideToLeave); if (targetFbData == null) { continue; } // // the most interesting part of this method // if (IsLocAllowedForTargetBlock(locData, targetFbData)) { res.Add(it); } } return(res); }
/// <summary> /// Filter routes by target block enabled stated, /// only use routes where target blocks are enabled. /// </summary> /// <param name="routeList"></param> /// <param name="sideToLeave"></param> /// <param name="locData"></param> /// <returns></returns> public RouteList FilterByBlockEnabled( RouteList routeList, SideMarker sideToLeave, Locomotives.Data locData) { var res = new RouteList(); foreach (var it in routeList) { var targetBlock = it.Blocks[1]; var targetBlockIdentifier = targetBlock.identifier; if (string.IsNullOrEmpty(targetBlockIdentifier)) { continue; } var targetFbData = GetFeedbackDataOf(targetBlockIdentifier, sideToLeave); if (targetFbData == null) { continue; } // // when the target block is disabled, do not use for routing // if (targetFbData.Settings != null && targetFbData.Settings.ContainsKey("BlockEnabled")) { var blockEnabled = targetFbData.Settings["BlockEnabled"]; if (!blockEnabled) { continue; } } res.Add(it); } return(res); }
/// <summary> /// Filters the routes where the current locomotive /// is not allowed to enter the block. /// </summary> /// <param name="routeList"></param> /// <param name="locDataEcos"></param> /// <param name="locData"></param> /// <param name="feedbacks"></param> /// <returns></returns> public static RouteList FilterBy( this RouteList routeList, Locomotive locDataEcos, Locomotives.Data locData, FeedbacksData feedbacks ) { var res = new RouteList(); foreach (var it in routeList) { var targetBlock = it.Blocks[1]; var targetBlockIdentifier = targetBlock.identifier; var targetEnterSide = targetBlock.side; var targetBlockData = feedbacks.GetByBlockId(targetBlockIdentifier, targetEnterSide); if (targetBlockData == null) { continue; } // // check if the target block denies entering by the current locomotive // var useIsDenied = false; foreach (var itLoc in targetBlockData.DeniedLocomotives) { useIsDenied = itLoc.Id.Equals(locDataEcos.Name, StringComparison.Ordinal); if (useIsDenied) { break; } } if (useIsDenied) { continue; } // // check if the locomotive type is not allowed to enter the target block // targetBlockData.Settings ??= GetDefaultSettings(); if (targetBlockData.Settings.Count == 0) { continue; } var enterIsAllowed = false; foreach (var itLocSetting in locData.Settings) { var name = itLocSetting.Key; var state = itLocSetting.Value; if (targetBlockData.Settings.ContainsKey(name)) { enterIsAllowed = state == targetBlockData.Settings[name]; if (enterIsAllowed) { break; } } } if (!enterIsAllowed) { continue; } res.Add(it); } return(res); }
/// <summary> /// in case there is no route to leave on the sideToLeave /// probably the trains' direction must change, if change /// is allowed: /// (1) check for a new route on the opposide sideToLeave /// (2) if one or more route available, check if the train is allowed to change the direction (as well the block) [no check if cleaningPriority:=true] /// (3) change the direction /// (4) change the sideToLeave /// (5) ...start the additional route selection routines /// </summary> /// <param name="routeList"></param> /// <param name="occBlock"></param> /// <param name="sideToLeave"></param> /// <param name="originalSideEntered"></param> /// <param name="locDataEcos"></param> /// <param name="locData"></param> /// <param name="routesOnOpposide"></param> /// <param name="cleaningPriority"></param> /// <returns></returns> public bool CheckOpposide( RouteList routeList, Occ.OccBlock occBlock, SideMarker sideToLeave, SideMarker originalSideEntered, Locomotive locDataEcos, Locomotives.Data locData, out RouteList routesOnOpposide, bool cleaningPriority = false) { routesOnOpposide = new RouteList(); string step4enterBlockSide; var occFromBlock = occBlock.FromBlock; if (string.IsNullOrEmpty(occFromBlock)) { return(false); } LogInfo($"The side to leave {sideToLeave} does not have any route to take."); if (sideToLeave == SideMarker.Minus) { step4enterBlockSide = "'-' Side"; sideToLeave = SideMarker.Plus; } else { step4enterBlockSide = "'+' Side"; sideToLeave = SideMarker.Minus; } #region (1) // // (1) // routesOnOpposide = routeList.GetRoutesWithFromBlock(occFromBlock, sideToLeave, true); if (routesOnOpposide.Count == 0) { LogInfo($"The other side to leave {sideToLeave} does not have any route to take."); LogInfo($"No route to take from {occFromBlock} for Locomotive({locDataEcos.Name ?? "-"})."); return(false); } #endregion (1) #region (2) // // (2) // if (cleaningPriority == false) { if (locData.Settings.ContainsKey("OptionDirection")) { var locState = locData.Settings["OptionDirection"]; if (!locState) { LogInfo($"Locomotive({locDataEcos.Name}) is not allowed to change the direction."); return(false); } } var fbData = GetFeedbackDataOf(occBlock.FromBlock, originalSideEntered); if (fbData == null) { LogInfo($"No feedback data available for block {occBlock.FromBlock}."); return(false); } if (fbData.Settings.ContainsKey("OptionDirection")) { var blockState = fbData.Settings["OptionDirection"]; if (!blockState) { LogInfo($"Block({fbData.BlockId}) does not allow to change the direction."); return(false); } } } #endregion (2) #region (3) // // (3) // var currentDirection = locDataEcos.Direction; var newDirection = currentDirection == 1 ? 0 : 1; if (_ctx.IsSimulationMode()) { locDataEcos.ChangeDirectionSimulation(newDirection == 1); _ctx.SaveAll(); _ctx?._sniffer?.TriggerDataProviderModifiedForSimulation(); } else { locDataEcos.ChangeDirection(newDirection == 1); _ctx?._sniffer?.SendCommandsToEcosStation(); } #endregion (3) #region (4) // // (4) // // EnterBlockSide = "'+' Side" // EnterBlockSide = "'-' Side" if (string.IsNullOrEmpty(step4enterBlockSide)) { LogInfo($"Invalid enterBlockSide value for Locomotive({locDataEcos.Name})."); return(false); } locData.EnterBlockSide = step4enterBlockSide; SaveLocomotivesAndPromote(); SaveOccAndPromote(); #endregion (4) return(routesOnOpposide.Count > 0); }