Esempio n. 1
0
 /// <summary>
 /// Chooses whether a signal is on or off and, if off, whether it has automatic working enabled.
 /// </summary>
 /// <param name="route">The route containing the signal.</param>
 /// <param name="signal">The ID number of the signal.</param>
 /// <param name="indication">Which indication to set.</param>
 public async Task ChangeSignalAsync(int route, int signal, ESignalIndication indication)
 {
     try {
         await Run8.ChangeSignalAsync(route, signal, indication);
     } catch (CommunicationException) {
         LinkError = true;
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Chooses whether a signal is on or off and, if off, whether it has automatic working enabled.
        /// </summary>
        /// <param name="route">The route containing the signal.</param>
        /// <param name="signal">The ID number of the signal.</param>
        /// <param name="indication">Which indication to set.</param>
        public Task ChangeSignalAsync(int route, int signal, ESignalIndication indication)
        {
            DispatcherSignalMessage msg;

            msg.Route            = route;
            msg.SignalID         = signal;
            msg.SignalIndication = indication;
            return(Task.Factory.FromAsync(Run8.BeginChangeSignal, Run8.EndChangeSignal, msg, null));
        }
Esempio n. 3
0
        /// <summary>
        /// Processes a message from Run8 carrying the indication of this signal.
        /// </summary>
        /// <param name="indication">This signal's indication.</param>
        public async Task UpdateFromRun8Async(ESignalIndication indication)
        {
            // Update indication.
            if (LastIndication != indication)
            {
                LastIndication = indication;
                UpdateAspects();
            }

            // Calculate a few derived values.
            AutoWorking = indication == ESignalIndication.Fleet;
            FlagBy      = indication == ESignalIndication.FlagBy;

            // Clear approach locking if the signal is set to proceed. Approach locking will be reapplied if the signal is cancelled a second time. The only cases where approach locking would not be reapplied would be (1) if a CAL exemption matches, in which case the old approach locking is clearly no longer needed, or (2) if the signal is on, which can only happen if a TC in advance of the signal is occupied, which means either the approaching train passed the signal (in which case approach locking should no longer apply and TORR should be allowed to happen) or some other train approaching the area SPADed (in which case all bets are off and it doesn't really matter what we do).
            if ((indication != ESignalIndication.Stop) && (indication != ESignalIndication.FlagBy))
            {
                ApproachLockExpires = null;
            }

            // Update approach locking status based on timer.
            ApproachLocked = ApproachLockExpires.HasValue && (ApproachLockExpires.Value > DateTime.UtcNow);

            // Check for train operated route release.
            if (!SwingingPoints && (indication == ESignalIndication.Stop) && !ApproachLocked)
            {
                // We aren't waiting for points before clearing a signal, the signal is at stop, and we aren't waiting for approach locking to time out. That means either there is no route set (in which case all this logic is harmless), a route is set and the train passing replaced the signal, or the signal was cancelled and either was exempt from approach locking or the timeout has passed.
                if (ReplaceDelayTimer == 0)
                {
                    if (CurrentRoute != null)
                    {
                        CurrentRoute.Elements[0].TrackCircuit.RouteLockCascaded = false;
                        CurrentRoute = null;
                    }
                }
                else
                {
                    --ReplaceDelayTimer;
                }
            }
            else
            {
                ReplaceDelayTimer = ReplaceDelayPeriod;
            }

            // If we were waiting for the points to prove after calling a route and they have now done so, clear the signal.
            if (SwingingPoints)
            {
                bool anyWrong = false;
                foreach (RoutePointPosition i in CurrentRoute.PointPositions)
                {
                    if (!i.Points.Proved)
                    {
                        anyWrong = true;
                    }
                }
                if (!anyWrong)
                {
                    SwingingPoints    = false;
                    ReplaceDelayTimer = ReplaceDelayPeriod;
                    await World.ChangeSignalAsync(SubArea, ID, AutoWorking?ESignalIndication.Fleet : ESignalIndication.Proceed);
                }
            }
        }