Esempio n. 1
0
        /// <summary>
        /// Gets the medium speed of the given loc on the given route.
        /// </summary>
        public static int GetMediumSpeed(this ILocState loc, IRouteState route)
        {
            var speed      = loc.MediumSpeed;
            var routeSpeed = route.Speed / 100.0;

            return(Math.Max((int)(speed * routeSpeed), loc.SlowSpeed));
        }
Esempio n. 2
0
 private void SelectNextState(IRouteState route)
 {
     if (lastSensor != null)
     {
         lastSensor.Active.Actual = false;
     }
     if (state == States.Initial)
     {
         var sensor = route.Sensors.FirstOrDefault(x => route.IsEnteringDestinationSensor(x, loc));
         if (sensor != null)
         {
             sensor.Active.Actual = true;
             lastSensor           = sensor;
             state = States.Enter;
             return;
         }
     }
     // Activate reached sensor
     {
         var sensor = route.Sensors.FirstOrDefault(x => route.IsReachedDestinationSensor(x, loc));
         if (sensor != null)
         {
             sensor.Active.Actual = true;
             lastSensor           = sensor;
             state = States.Initial;
         }
     }
 }
        /// <summary>
        /// Can the given route be taken by the given loc?
        /// </summary>
        /// <param name="route">The route being investigated</param>
        /// <param name="loc">The loc a route should be choosen for</param>
        /// <param name="locDirection">The direction the loc is facing in the From block of the given <see cref="route"/>.</param>
        /// <param name="avoidDirectionChanges">If true, the route is considered not available if a direction change is needed.</param>
        /// <param name="generationDelta">If larger than 0, look this number of generation less far in the future.</param>
        /// <returns>True if the route can be locked and no sensor in the route is active (outside current route).</returns>
        public override IRouteOption IsAvailableFor(IRouteState route, ILocState loc, Model.BlockSide locDirection, bool avoidDirectionChanges, int generationDelta)
        {
            // Perform standard testing first
            var result = base.IsAvailableFor(route, loc, locDirection, avoidDirectionChanges, generationDelta);

            if (!result.IsPossible)
            {
                return(result);
            }

            // If last resort, we're ok when critical section is empty.
            if (generationDelta > 0)
            {
                if (route.CriticalSection.IsEmpty)
                {
                    return(result);
                }
            }

            // Now test future possibilities of the entire railway to detect possible deadlocks.
            var genSet = new FutureAlternativeSet(this, route, loc);

            if (!genSet.Test(generationDelta))
            {
                // Not Ok
                return(new RouteOption(route, RouteImpossibleReason.DeadLock));
            }
            return(result);
        }
Esempio n. 4
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public RouteOption(IRouteState route, bool isPossible, RouteImpossibleReason reason, string extra)
 {
     this.route      = route;
     this.isPossible = isPossible;
     this.reason     = reason;
     this.extra      = extra;
 }
Esempio n. 5
0
        /// <summary>
        /// Find the route that is the reverse of the given route.
        /// </summary>
        /// <returns>Null if not found</returns>
        public static IRouteState GetReverse(this IRouteState route)
        {
            var from    = route.To;
            var to      = route.From;
            var railway = route.RailwayState;

            if ((from == null) || (to == null) || (railway == null))
            {
                return(null);
            }

            var reverseRoutes = railway.RouteStates.Where(x => (x.From == from) && (x.To == to));

            foreach (var iterator in reverseRoutes)
            {
                // From side should match
                if (route.FromBlockSide != iterator.ToBlockSide)
                {
                    // No match
                    continue;
                }
                // To side should match
                if (route.ToBlockSide != iterator.FromBlockSide)
                {
                    // No match
                    continue;
                }
                // We found it
                return(iterator);
            }
            // Not found
            return(null);
        }
            /// <summary>
            /// Default ctor
            /// </summary>
            public FutureAlternativeSet(LiveRouteAvailabilityTester live, IRouteState route, ILocState loc)
            {
                this.testLoc   = loc;
                minGenerations = live.railwayState.BlockStates.Count;
                var tester = new FutureRouteAvailabilityTester(live.railwayState);

                tester.TakeRoute(route, loc);
                alternatives.Add(new FutureAlternative(tester, 0));
                autoLocs = live.railwayState.LocStates.Where(x => x.ControlledAutomatically.Actual && (x.CurrentBlock.Actual != null)).ToList();
            }
Esempio n. 7
0
 /// <summary>
 /// Add the given route to the end of this sequence.
 /// </summary>
 public void Add(IRouteState route)
 {
     if (sequence.Count > 0)
     {
         // Route must start from destination of last route
         if (sequence[sequence.Count - 1].To != route.From)
         {
             throw new ArgumentException("Route does not connect to existing sequence.");
         }
     }
     sequence.Add(route);
 }
Esempio n. 8
0
        /// <summary>
        /// Default ctor
        /// </summary>
        internal RouteStateForLoc(ILocState loc, IRouteState route)
        {
            this.loc   = loc;
            this.route = route;

            foreach (var @event in route.Events)
            {
                var behavior = @event.Behaviors.FirstOrDefault(x => x.AppliesTo(loc));
                if (behavior != null)
                {
                    behaviors[@event.Sensor] = behavior;
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Is any of the sensors of the given route active?
        /// Sensors that are also in the current route of the given loc are ignored.
        /// </summary>
        protected virtual bool IsAnySensorActive(IRouteState route, ILocState loc)
        {
            var activeSensors = route.Sensors.Where(x => x.Active.Actual);
            var currentRoute  = loc.CurrentRoute.Actual;

            if (currentRoute == null)
            {
                // There must be no active sensor
                return(activeSensors.Any());
            }

            // The loc has a current route.
            // There must not be any active sensor that is not listed in the current route.
            return(activeSensors.Any(x => !currentRoute.Route.Contains(x)));
        }
Esempio n. 10
0
        /// <summary>
        /// Is the position of this block matching the direction of the route.
        /// </summary>
        private bool IsPositionMatchingRoute(IRouteState route)
        {
            var block = Block;

            if (block == route.From)
            {
                if (Type == BlockSignalType.Entry)
                {
                    return(false);
                }
                return(Position == route.FromBlockSide);
            }
            if (block == route.To)
            {
                if (Type == BlockSignalType.Exit)
                {
                    return(Position == route.ToBlockSide.Invert());
                }
                return(Position == route.ToBlockSide);
            }
            // Unknown
            return(false);
        }
Esempio n. 11
0
        /// <summary>
        /// Is there are traffic in the opposite direction of the given route (not including the given loc).
        /// </summary>
        protected bool HasTrafficInOppositeDirection(IRouteState route, ILocState currentLoc, int stepsRemaining, out IBlockState blockContainingTraffic)
        {
            if (stepsRemaining <= 0)
            {
                // We've taken to long to find opposing traffic
                blockContainingTraffic = null;
                return(false);
            }
            var toBlock = route.To;

            if (HasTrafficInOppositeDirection(toBlock, route.ToBlockSide, currentLoc))
            {
                blockContainingTraffic = toBlock;
                return(true);
            }

            // Check next routes
            var nextRoutes = railwayState.GetAllPossibleNonClosedRoutesFromBlock(toBlock).ToList();

            //var nextRoutes = railwayState.GetAllPossibleNonClosedRoutesFromBlock(toBlock, locDirection).ToList();

            if (nextRoutes.Count == 0)
            {
                // No next routes at all, we do no longer care about opposing traffic
                blockContainingTraffic = null;
                return(false);
            }
            if (nextRoutes.Count > 1)
            {
                // Multiple next routes, we stop now
                blockContainingTraffic = null;
                return(false);
            }
            // Only one route possible, check that for opposing traffic
            return(HasTrafficInOppositeDirection(nextRoutes[0], currentLoc, stepsRemaining - 1, out blockContainingTraffic));
        }
Esempio n. 12
0
 /// <summary>
 /// Create an 1 length sequence.
 /// </summary>
 public RouteSequence(IRouteState first)
 {
     sequence = new List <IRouteState> {
         first
     };
 }
 /// <summary>
 /// Default ctor
 /// </summary>
 public CriticalSectionBuilder(IRouteState route, IRailwayState railway)
 {
     this.route   = route;
     this.railway = railway;
 }
 /// <summary>
 /// Default ctor
 /// </summary>
 public BlockAndSide(IRouteState route)
 {
     block     = route.To;
     enterSide = route.ToBlockSide;
 }
 /// <summary>
 /// Can the given route be locked for the given loc?
 /// </summary>
 protected override bool CanLock(IRouteState route, ILocState loc, out ILocState lockedBy)
 {
     lockedBy = GetLockedBy(route.To);
     return((lockedBy == null) || (lockedBy == loc));
 }
 /// <summary>
 /// Let the given loc take the given route.
 /// </summary>
 public void TakeRoute(IRouteState route, ILocState loc)
 {
     locStates[loc].ChangeTo(route.To, route.ToBlockSide);
 }
 /// <summary>
 /// Is any of the sensors of the given route active?
 /// Sensors that are also in the current route of the given loc are ignored.
 /// </summary>
 protected override bool IsAnySensorActive(IRouteState route, ILocState loc)
 {
     return(false);
 }
 /// <summary>
 /// Is the critical section for the given route free for the given loc?
 /// </summary>
 protected override bool IsCriticalSectionFree(IRouteState route, ILocState loc)
 {
     return(true);
 }
Esempio n. 19
0
 /// <summary>
 /// Is the critical section for the given route free for the given loc?
 /// </summary>
 protected virtual bool IsCriticalSectionFree(IRouteState route, ILocState loc)
 {
     return(route.CriticalSection.AllFree(loc));
 }
Esempio n. 20
0
        /// <summary>
        /// Can the given route be taken by the given loc?
        /// </summary>
        /// <param name="route">The route being investigated</param>
        /// <param name="loc">The loc a route should be choosen for</param>
        /// <param name="locDirection">The direction the loc is facing in the From block of the given <see cref="route"/>.</param>
        /// <param name="avoidDirectionChanges">If true, the route is considered not available if a direction change is needed.</param>
        /// <param name="generationDelta">If larger than 0, look this number of generation less far in the future.</param>
        /// <returns>True if the route can be locked and no sensor in the route is active (outside current route).</returns>
        public virtual IRouteOption IsAvailableFor(IRouteState route, ILocState loc, BlockSide locDirection, bool avoidDirectionChanges, int generationDelta)
        {
            ILocState lockedBy;

            if (!CanLock(route, loc, out lockedBy))
            {
                // Cannot lock
                return(new RouteOption(route, RouteImpossibleReason.Locked, (lockedBy != null) ? lockedBy.Description : "?"));
            }

            // Route closed?
            if (route.Closed)
            {
                // Route closed
                return(new RouteOption(route, RouteImpossibleReason.Closed));
            }

            // Target blocked closed?
            if (route.To.Closed.Actual || route.To.Closed.Requested)
            {
                // Destination closed.
                return(new RouteOption(route, RouteImpossibleReason.DestinationClosed));
            }

            // Check opposite traffic
            IBlockState blockContainingTraffic;
            var         maxSteps = Math.Max(1, railwayState.BlockStates.Count - generationDelta);

            if (HasTrafficInOppositeDirection(route, loc, maxSteps, out blockContainingTraffic))
            {
                // Traffic in opposite direction found
                return(new RouteOption(route, RouteImpossibleReason.OpposingTraffic, blockContainingTraffic.Description));
            }

            // Check critical section of route
            if (!IsCriticalSectionFree(route, loc))
            {
                // Some route in critical section not free
                return(new RouteOption(route, RouteImpossibleReason.CriticalSectionOccupied));
            }

            // Check direction
            if (route.IsDirectionChangeNeeded(locDirection))
            {
                if (avoidDirectionChanges)
                {
                    // Do not take this route because a direction change would be needed.
                    return(new RouteOption(route, RouteImpossibleReason.DirectionChangeNeeded));
                }
                if (loc.ChangeDirection != ChangeDirection.Allow)
                {
                    // Loc does not allow direction changes
                    if (!route.From.IsDeadEnd)
                    {
                        return(new RouteOption(route, RouteImpossibleReason.DirectionChangeNeeded));
                    }
                    // Loc will reverse out of a dead end
                }
                if (route.From.ChangeDirection != ChangeDirection.Allow)
                {
                    // From block does not allowed direction changes
                    return(new RouteOption(route, RouteImpossibleReason.DirectionChangeNeeded));
                }
            }

            // Check permissions
            if (!route.Permissions.Evaluate(loc))
            {
                // Loc not allowed by permissions
                return(new RouteOption(route, RouteImpossibleReason.NoPermission));
            }

            // Check sensor states
            if (IsAnySensorActive(route, loc))
            {
                // Route is not available
                return(new RouteOption(route, RouteImpossibleReason.SensorActive));
            }

            // Route is available
            return(new RouteOption(route, true, RouteImpossibleReason.None));
        }
Esempio n. 21
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public RouteOption(IRouteState route, bool isPossible, RouteImpossibleReason reason)
     : this(route, isPossible, reason, null)
 {
 }
Esempio n. 22
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public RouteOption(IRouteState route, RouteImpossibleReason reason)
     : this(route, false, reason, null)
 {
 }
Esempio n. 23
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public RouteOption(IRouteState route, RouteImpossibleReason reason, string extra)
     : this(route, false, reason, extra)
 {
 }
Esempio n. 24
0
        /// <summary>
        /// Is is needed for a loc facing in the given direction (in the From block of the given route)
        /// to chance direction when taking this route?
        /// </summary>
        /// <param name="route">The route being investigated</param>
        /// <param name="locDirection">The direction the loc is facing in the From block of the given <see cref="route"/>.</param>
        internal static bool IsDirectionChangeNeeded(this IRouteState route, BlockSide locDirection)
        {
            var fromSide = route.FromBlockSide;

            return(fromSide != locDirection);
        }
Esempio n. 25
0
 /// <summary>
 /// Can the given route be locked for the given loc?
 /// </summary>
 protected virtual bool CanLock(IRouteState route, ILocState loc, out ILocState lockedBy)
 {
     return(route.CanLock(loc, out lockedBy));
 }