Exemplo n.º 1
0
        //================================================================================================//
        /// <summary>
        /// Constructor for restore
        /// </summary>

        public DeadlockPathInfo(BinaryReader inf)
        {
            if (null == inf)
            {
                throw new ArgumentNullException(nameof(inf));
            }

            Path = new TrackCircuitPartialPathRoute(inf);
            Name = inf.ReadString();

            Groups = new List <string>();
            int totalGroups = inf.ReadInt32();

            for (int iGroup = 0; iGroup <= totalGroups - 1; iGroup++)
            {
                string thisGroup = inf.ReadString();
                Groups.Add(thisGroup);
            }

            UsefulLength           = inf.ReadSingle();
            EndSectionIndex        = inf.ReadInt32();
            LastUsefulSectionIndex = inf.ReadInt32();

            AllowedTrains = new List <int>();
            int totalIndex = inf.ReadInt32();

            for (int iIndex = 0; iIndex <= totalIndex - 1; iIndex++)
            {
                int thisIndex = inf.ReadInt32();
                AllowedTrains.Add(thisIndex);
            }
        }
Exemplo n.º 2
0
        }                                                // index of linked end section

        //================================================================================================//
        /// <summary>
        /// Constructor
        /// </summary>

        public DeadlockPathInfo(TrackCircuitPartialPathRoute path, int pathIndex)
        {
            Path   = new TrackCircuitPartialPathRoute(path);
            Name   = string.Empty;
            Groups = new List <string>();

            UsefulLength           = 0.0f;
            EndSectionIndex        = -1;
            LastUsefulSectionIndex = -1;
            AllowedTrains          = new List <int>();

            Path[0].UsedAlternativePath = pathIndex;
        }
Exemplo n.º 3
0
        public void AddPlayers(MSGPlayer player)
        {
            if (Players.ContainsKey(player.user))
            {
                return;
            }
            if (MultiPlayerManager.Client != null && player.user == MultiPlayerManager.Client.UserName)
            {
                return; //do not add self//WARNING: may need to worry about train number here
            }
            OnlinePlayer p = new OnlinePlayer(player.user,
                                              Path.Combine(Simulator.Instance.RouteFolder.ContentFolder.ConsistsFolder, player.con),
                                              Path.Combine(Simulator.Instance.RouteFolder.PathsFolder, player.path));

            p.AvatarUrl           = player.url;
            p.LeadingLocomotiveID = player.leadingID;
            Train train = new Train();

            train.TrainType = TrainType.Remote;
            if (MultiPlayerManager.IsServer()) //server needs to worry about correct train number
            {
            }
            else
            {
                train.Number = player.num;
            }
            if (player.con.Contains("tilted"))
            {
                train.IsTilting = true;
            }
            int direction = player.dir;

            train.DistanceTravelled = player.Travelled;
            train.TrainMaxSpeedMpS  = player.trainmaxspeed;

            if (MultiPlayerManager.IsServer())
            {
                try
                {
                    AIPath aiPath = new AIPath(Simulator.Instance.TrackDatabase, Simulator.Instance.TSectionDat, p.Path, Simulator.Instance.TimetableMode);
                }
                catch (Exception) { MultiPlayerManager.BroadCast((new MSGMessage(player.user, "Warning", "Server does not have path file provided, signals may always be red for you.")).ToString()); }
            }

            try
            {
                train.RearTDBTraveller = new Traveller(Simulator.Instance.TSectionDat, Simulator.Instance.TrackDatabase.TrackDB.TrackNodes, player.Location, direction == 1 ? Traveller.TravellerDirection.Forward : Traveller.TravellerDirection.Backward);
            }
            catch (Exception e)
            {
                if (MultiPlayerManager.IsServer())
                {
                    MultiPlayerManager.BroadCast((new MSGMessage(player.user, "Error", "MultiPlayer Error:" + e.Message)).ToString());
                }
                else
                {
                    throw new Exception();
                }
            }
            for (var i = 0; i < player.cars.Length; i++)// cars.Length-1; i >= 0; i--) {
            {
                string   wagonFilePath = Path.Combine(Simulator.Instance.RouteFolder.ContentFolder.TrainSetsFolder, player.cars[i]);
                TrainCar car           = null;
                try
                {
                    car            = RollingStock.Load(Simulator.Instance, wagonFilePath);
                    car.CarLengthM = player.lengths[i] / 100.0f;
                }
                catch (Exception error)
                {
                    Trace.WriteLine(error.Message);
                    car = MultiPlayerManager.Instance().SubCar(wagonFilePath, player.lengths[i]);
                }
                if (car == null)
                {
                    continue;
                }
                bool flip = true;
                if (player.flipped[i] == 0)
                {
                    flip = false;
                }
                car.Flipped = flip;
                car.CarID   = player.ids[i];
                train.Cars.Add(car);
                car.Train = train;
                MSTSWagon w = (MSTSWagon)car;
                if (w != null)
                {
                    w.SignalEvent((player.pantofirst == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 1);
                    w.SignalEvent((player.pantosecond == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 2);
                    w.SignalEvent((player.pantothird == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 3);
                    w.SignalEvent((player.pantofourth == 1 ? PowerSupplyEvent.RaisePantograph : PowerSupplyEvent.LowerPantograph), 4);
                }
            }// for each rail car

            if (train.Cars.Count == 0)
            {
                throw (new Exception("The train of player " + player.user + " is empty from "));
            }

            train.ControlMode = TrainControlMode.Explorer;
            train.CheckFreight();
            train.InitializeBrakes();
            TrackCircuitPartialPathRoute tempRoute = train.CalculateInitialTrainPosition();

            if (tempRoute.Count == 0)
            {
                MultiPlayerManager.BroadCast((new MSGMessage(p.Username, "Error", "Cannot be placed into the game")).ToString());//server will broadcast this error
                throw new InvalidDataException("Remote train original position not clear");
            }

            train.SetInitialTrainRoute(tempRoute);
            train.CalculatePositionOfCars();
            train.ResetInitialTrainRoute(tempRoute);

            train.CalculatePositionOfCars();
            train.AITrainBrakePercent = 100;

            //if (MPManager.Instance().AllowedManualSwitch) train.InitializeSignals(false);
            for (int iCar = 0; iCar < train.Cars.Count; iCar++)
            {
                var car = train.Cars[iCar];
                if (car.CarID == p.LeadingLocomotiveID)
                {
                    train.LeadLocomotive = car;
                    (train.LeadLocomotive as MSTSLocomotive).Headlight    = player.headlight;
                    (train.LeadLocomotive as MSTSLocomotive).UsingRearCab = player.frontorrearcab == "R" ? true : false;
                }
                if (car is MSTSLocomotive && MultiPlayerManager.IsServer())
                {
                    MultiPlayerManager.Instance().AddOrRemoveLocomotive(player.user, train.Number, iCar, true);
                }
            }
            if (train.LeadLocomotive == null)
            {
                train.LeadNextLocomotive();
                if (train.LeadLocomotive != null)
                {
                    p.LeadingLocomotiveID = train.LeadLocomotive.CarID;
                }
                else
                {
                    p.LeadingLocomotiveID = "NA";
                }
            }

            if (train.LeadLocomotive != null)
            {
                train.Name = Train.GetTrainName(train.LeadLocomotive.CarID);
            }
            else if (train.Cars != null && train.Cars.Count > 0)
            {
                train.Name = Train.GetTrainName(train.Cars[0].CarID);
            }
            else if (player != null && player.user != null)
            {
                train.Name = player.user;
            }

            if (MultiPlayerManager.IsServer())
            {
                train.InitializeSignals(false);
            }
            p.Train = train;

            Players.Add(player.user, p);
            MultiPlayerManager.Instance().AddOrRemoveTrain(train, true);
        }
Exemplo n.º 4
0
        //================================================================================================//
        //
        // Check if conflict is real deadlock situation
        // Conditions :
        //   if section is part of deadlock definition, it is a deadlock
        //   if section has intermediate signals, it is a deadlock
        //   if section has no intermediate signals but there are signals on both approaches to the deadlock, it is not a deadlock
        // Return value : boolean to indicate it is a deadlock or not
        // If not a deadlock, the REF int elementIndex is set to index of the last common section (will be increased in the loop)
        //
        internal bool CheckRealDeadlockLocationBased(TrackCircuitPartialPathRoute route, TrackCircuitPartialPathRoute otherRoute, ref int elementIndex)
        {
            bool isValidDeadlock = false;

            TrackCircuitSection section = route[elementIndex].TrackCircuitSection;

            // check if section is start or part of deadlock definition
            if (section.DeadlockReference >= 0 || (section.DeadlockBoundaries != null && section.DeadlockBoundaries.Count > 0))
            {
                return(true);
            }

            // loop through common section - if signal is found, it is a deadlock
            bool validLoop       = true;
            int  otherRouteIndex = otherRoute.GetRouteIndex(section.Index, 0);

            for (int i = 0; validLoop; i++)
            {
                int thisElementIndex  = elementIndex + i;
                int otherElementIndex = otherRouteIndex - i;

                if (thisElementIndex > route.Count - 1)
                {
                    validLoop = false;
                }
                if (otherElementIndex < 0)
                {
                    validLoop = false;
                }

                if (validLoop)
                {
                    TrackCircuitSection thisRouteSection  = route[thisElementIndex].TrackCircuitSection;
                    TrackCircuitSection otherRouteSection = otherRoute[otherElementIndex].TrackCircuitSection;

                    if (thisRouteSection.Index != otherRouteSection.Index)
                    {
                        validLoop = false;
                    }
                    else if (thisRouteSection.EndSignals[TrackDirection.Ahead] != null || thisRouteSection.EndSignals[TrackDirection.Reverse] != null)
                    {
                        isValidDeadlock = true;
                        validLoop       = false;
                    }
                }
            }

            // if no signals along section, check if section is protected by signals - if so, it is not a deadlock
            // check only as far as maximum signal check distance
            if (!isValidDeadlock)
            {
                // this route backward first
                float totalDistance = 0.0f;
                bool  signalFound   = false;
                validLoop = true;

                for (int i = 0; validLoop; i--)
                {
                    int thisElementIndex = elementIndex + i; // going backward as iIndex is negative!
                    if (thisElementIndex < 0)
                    {
                        validLoop = false;
                    }
                    else
                    {
                        TrackCircuitRouteElement thisElement      = route[thisElementIndex];
                        TrackCircuitSection      thisRouteSection = thisElement.TrackCircuitSection;
                        totalDistance += thisRouteSection.Length;

                        if (thisRouteSection.EndSignals[thisElement.Direction] != null)
                        {
                            validLoop   = false;
                            signalFound = true;
                        }

                        if (totalDistance > MinCheckDistanceM)
                        {
                            validLoop = false;
                        }
                    }
                }

                // other route backward next
                totalDistance = 0.0f;
                bool otherSignalFound = false;
                validLoop = true;

                for (int iIndex = 0; validLoop; iIndex--)
                {
                    int thisElementIndex = otherRouteIndex + iIndex; // going backward as iIndex is negative!
                    if (thisElementIndex < 0)
                    {
                        validLoop = false;
                    }
                    else
                    {
                        TrackCircuitRouteElement thisElement      = otherRoute[thisElementIndex];
                        TrackCircuitSection      thisRouteSection = thisElement.TrackCircuitSection;
                        totalDistance += thisRouteSection.Length;

                        if (thisRouteSection.EndSignals[thisElement.Direction] != null)
                        {
                            validLoop        = false;
                            otherSignalFound = true;
                        }

                        if (totalDistance > MinCheckDistanceM)
                        {
                            validLoop = false;
                        }
                    }
                }

                if (!signalFound || !otherSignalFound)
                {
                    isValidDeadlock = true;
                }
            }

            // if not a valid deadlock, find end of common section
            if (!isValidDeadlock)
            {
                elementIndex = EndCommonSection(elementIndex, route, otherRoute);;
            }

            return(isValidDeadlock);
        }
Exemplo n.º 5
0
        // Obtain deadlock details - new style location based logic
        private int[] SetDeadlockLocationBased(int index, TrackCircuitPartialPathRoute route, TrackCircuitPartialPathRoute otherRoute, Train otherTrain)
        {
            int[] returnValue = new int[2];
            returnValue[1] = -1;  // set to no alternative path used

            TrackCircuitRouteElement firstElement = route[index];
            int  firstSectionIndex = firstElement.TrackCircuitSection.Index;
            bool alreadyActive     = false;

            int trainSectionIndex;
            int otherTrainSectionIndex;

            // double index variables required as last valid index must be known when exiting loop
            int trainIndex          = index;
            int trainNextIndex      = trainIndex;
            int otherTrainIndex     = otherRoute.GetRouteIndex(firstSectionIndex, 0);
            int otherTrainNextIndex = otherTrainIndex;
            int otherFirstIndex     = otherTrainIndex;

            TrackCircuitRouteElement trainElement;
            TrackCircuitRouteElement otherTrainElement;

            bool validPassLocation    = false;
            int  endSectionRouteIndex = -1;

            bool endOfLoop = false;

            // loop while not at end of route for either train and sections are equal
            // loop is also exited when alternative path is found for either train
            while (!endOfLoop)
            {
                trainIndex        = trainNextIndex;
                trainElement      = route[trainIndex];
                otherTrainIndex   = otherTrainNextIndex;
                trainSectionIndex = trainElement.TrackCircuitSection.Index;

                otherTrainElement      = otherRoute[otherTrainIndex];
                otherTrainSectionIndex = otherTrainElement.TrackCircuitSection.Index;

                TrackCircuitSection section = otherTrainElement.TrackCircuitSection;

                // if sections not equal : test length of next not-common section, if long enough then exit loop
                if (trainSectionIndex != otherTrainSectionIndex)
                {
                    int nextThisRouteIndex = trainIndex;
                    TrackCircuitSection passLoopSection = ValidRoute[0][nextThisRouteIndex].TrackCircuitSection;
                    _ = otherRoute.GetRouteIndex(passLoopSection.Index, otherTrainIndex);

                    float passLength    = passLoopSection.Length;
                    bool  endOfPassLoop = false;

                    while (!endOfPassLoop)
                    {
                        // loop is longer as at least one of the trains so is valid
                        if (passLength > Length || passLength > otherTrain.Length)
                        {
                            endOfPassLoop = true;
                            endOfLoop     = true;
                        }

                        // get next section
                        else if (nextThisRouteIndex < ValidRoute[0].Count - 2)
                        {
                            nextThisRouteIndex++;
                            passLoopSection = ValidRoute[0][nextThisRouteIndex].TrackCircuitSection;
                            int nextOtherRouteIndex = otherRoute.GetRouteIndexBackward(passLoopSection.Index, otherTrainIndex);

                            // new common section after too short loop - not a valid deadlock point
                            if (nextOtherRouteIndex >= 0)
                            {
                                endOfPassLoop       = true;
                                trainNextIndex      = nextThisRouteIndex;
                                otherTrainNextIndex = nextOtherRouteIndex;
                            }
                            else
                            {
                                passLength += passLoopSection.Length;
                            }
                        }
                        // end of route
                        else
                        {
                            endOfPassLoop = true;
                            endOfLoop     = true;
                        }
                    }
                }
                // if section is a deadlock boundary, check available paths for both trains
                else
                {
                    List <int> trainAllocatedPaths      = new List <int>();
                    List <int> otherTrainAllocatedPaths = new List <int>();

                    bool gotoNextSection = true;

                    if (section.DeadlockReference >= 0 && trainElement.FacingPoint) // test for facing points only
                    {
                        bool trainFits      = false;
                        bool otherTrainFits = false;

                        int endSectionIndex = -1;

                        validPassLocation = true;

                        // get allocated paths for this train
                        DeadlockInfo deadlockInfo = Simulator.Instance.SignalEnvironment.DeadlockInfoList[section.DeadlockReference];

                        // get allocated paths for this train - if none yet set, create references
                        int trainReferenceIndex = deadlockInfo.GetTrainAndSubpathIndex(Number, TCRoute.ActiveSubPath);
                        if (!deadlockInfo.TrainReferences.ContainsKey(trainReferenceIndex))
                        {
                            deadlockInfo.SetTrainDetails(Number, TCRoute.ActiveSubPath, Length, ValidRoute[0], trainIndex);
                        }

                        // if valid path for this train
                        if (deadlockInfo.TrainReferences.ContainsKey(trainReferenceIndex))
                        {
                            trainAllocatedPaths = deadlockInfo.TrainReferences[deadlockInfo.GetTrainAndSubpathIndex(Number, TCRoute.ActiveSubPath)];

                            // if paths available, get end section and check train against shortest path
                            if (trainAllocatedPaths.Count > 0)
                            {
                                endSectionIndex      = deadlockInfo.AvailablePathList[trainAllocatedPaths[0]].EndSectionIndex;
                                endSectionRouteIndex = route.GetRouteIndex(endSectionIndex, trainIndex);
                                Dictionary <int, bool> trainFitList = deadlockInfo.TrainLengthFit[deadlockInfo.GetTrainAndSubpathIndex(Number, TCRoute.ActiveSubPath)];
                                foreach (int i in trainAllocatedPaths)
                                {
                                    if (trainFitList[i])
                                    {
                                        trainFits = true;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            validPassLocation = false;
                        }

                        // get allocated paths for other train - if none yet set, create references
                        int otherTrainReferenceIndex = deadlockInfo.GetTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath);
                        if (!deadlockInfo.TrainReferences.ContainsKey(otherTrainReferenceIndex))
                        {
                            int otherTrainElementIndex = otherTrain.ValidRoute[0].GetRouteIndexBackward(endSectionIndex, otherFirstIndex);
                            if (otherTrainElementIndex < 0) // train joins deadlock area on different node
                            {
                                validPassLocation = false;
                                deadlockInfo.RemoveTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath); // remove index as train has no valid path
                            }
                            else
                            {
                                deadlockInfo.SetTrainDetails(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath, otherTrain.Length,
                                                             otherTrain.ValidRoute[0], otherTrainElementIndex);
                            }
                        }

                        // if valid path for other train
                        if (validPassLocation && deadlockInfo.TrainReferences.ContainsKey(otherTrainReferenceIndex))
                        {
                            otherTrainAllocatedPaths =
                                deadlockInfo.TrainReferences[deadlockInfo.GetTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath)];

                            // if paths available, get end section (if not yet set) and check train against shortest path
                            if (otherTrainAllocatedPaths.Count > 0)
                            {
                                if (endSectionRouteIndex < 0)
                                {
                                    endSectionIndex      = deadlockInfo.AvailablePathList[otherTrainAllocatedPaths[0]].EndSectionIndex;
                                    endSectionRouteIndex = route.GetRouteIndex(endSectionIndex, trainIndex);
                                }

                                Dictionary <int, bool> otherTrainFitList =
                                    deadlockInfo.TrainLengthFit[deadlockInfo.GetTrainAndSubpathIndex(otherTrain.Number, otherTrain.TCRoute.ActiveSubPath)];
                                foreach (int iPath in otherTrainAllocatedPaths)
                                {
                                    if (otherTrainFitList[iPath])
                                    {
                                        otherTrainFits = true;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        // other train has no valid path relating to the passing path, so passing not possible
                        {
                            validPassLocation = false;
                        }

                        // if both trains have only one route, make sure it's not the same (inverse) route

                        if (trainAllocatedPaths.Count == 1 && otherTrainAllocatedPaths.Count == 1)
                        {
                            if (deadlockInfo.InverseInfo.ContainsKey(trainAllocatedPaths[0]) && deadlockInfo.InverseInfo[trainAllocatedPaths[0]] == otherTrainAllocatedPaths[0])
                            {
                                validPassLocation = false;
                            }
                        }

                        // if there are passing paths and at least one train fits in shortest path, it is a valid location so break loop
                        if (validPassLocation)
                        {
                            gotoNextSection = false;
                            if (trainFits || otherTrainFits)
                            {
                                if (section.IsSet(otherTrain, true))
                                {
                                    alreadyActive = true;
                                }
                                endOfLoop = true;
                            }
                            else
                            {
                                trainNextIndex      = endSectionRouteIndex;
                                otherTrainNextIndex = otherRoute.GetRouteIndexBackward(endSectionIndex, otherTrainIndex);
                                if (otherTrainNextIndex < 0)
                                {
                                    endOfLoop = true;
                                }
                            }
                        }
                    }

                    // if loop not yet ended - not a valid pass location, move to next section (if available)

                    if (gotoNextSection)
                    {
                        // if this section is occupied by other train, break loop - further checks are of no use
                        if (section.IsSet(otherTrain, true))
                        {
                            alreadyActive = true;
                            endOfLoop     = true;
                        }
                        else
                        {
                            trainNextIndex++;
                            otherTrainNextIndex--;

                            if (trainNextIndex > route.Count - 1 || otherTrainNextIndex < 0)
                            {
                                endOfLoop = true; // end of path reached for either train
                            }
                        }
                    }
                }
            }

            // if valid pass location : set return index

            if (validPassLocation && endSectionRouteIndex >= 0)
            {
                returnValue[1] = endSectionRouteIndex;
            }

            // get sections on which loop ended
            trainElement      = route[trainIndex];
            trainSectionIndex = trainElement.TrackCircuitSection.Index;

            otherTrainElement      = otherRoute[otherTrainIndex];
            otherTrainSectionIndex = otherTrainElement.TrackCircuitSection.Index;

            // if last sections are still equal - end of route reached for one of the trains
            // otherwise, last common sections was previous sections for this train
            TrackCircuitSection lastSection = (trainSectionIndex == otherTrainSectionIndex) ? TrackCircuitSection.TrackCircuitList[trainSectionIndex] :
                                              route[trainIndex - 1].TrackCircuitSection;

            // TODO : if section is not a junction but deadlock is already active, wind back to last junction
            // if section is not a junction, check if either route not ended, if so continue up to next junction
            if (lastSection.CircuitType != TrackCircuitType.Junction)
            {
                bool endSectionFound = false;
                if (trainIndex < (route.Count - 1))
                {
                    for (int iIndex = trainIndex; iIndex < route.Count - 1 && !endSectionFound; iIndex++)
                    {
                        lastSection     = route[iIndex].TrackCircuitSection;
                        endSectionFound = lastSection.CircuitType == TrackCircuitType.Junction;
                    }
                }

                else if (otherTrainIndex > 0)
                {
                    for (int i = otherTrainIndex; i >= 0 && !endSectionFound; i--)
                    {
                        lastSection     = otherRoute[i].TrackCircuitSection;
                        endSectionFound = false;

                        // junction found - end of loop
                        if (lastSection.CircuitType == TrackCircuitType.Junction)
                        {
                            endSectionFound = true;
                        }
                        // train has active wait condition at this location - end of loop
                        else if (otherTrain.CheckWaitCondition(lastSection.Index))
                        {
                            endSectionFound = true;
                        }

                        if (lastSection.IsSet(otherTrain, true))
                        {
                            alreadyActive = true;
                        }
                    }
                }
            }

            // set deadlock info for both trains
            SetDeadlockInfo(firstSectionIndex, lastSection.Index, otherTrain.Number);
            otherTrain.SetDeadlockInfo(lastSection.Index, firstSectionIndex, Number);

            if (alreadyActive)
            {
                lastSection.SetDeadlockTrap(otherTrain, otherTrain.DeadlockInfo[lastSection.Index]);
                returnValue[1] = route.Count;  // set beyond end of route - no further checks required
            }

            // if any section occupied by own train, reverse deadlock is active
            TrackCircuitSection firstSection = TrackCircuitSection.TrackCircuitList[firstSectionIndex];

            int firstRouteIndex = ValidRoute[0].GetRouteIndex(firstSectionIndex, 0);
            int lastRouteIndex  = ValidRoute[0].GetRouteIndex(lastSection.Index, 0);

            for (int i = firstRouteIndex; i < lastRouteIndex; i++)
            {
                TrackCircuitSection partSection = ValidRoute[0][i].TrackCircuitSection;
                if (partSection.IsSet(this, true))
                {
                    firstSection.SetDeadlockTrap(this, DeadlockInfo[firstSectionIndex]);
                }
            }

            returnValue[0] = route.GetRouteIndex(lastSection.Index, index);
            if (returnValue[0] < 0)
            {
                returnValue[0] = trainIndex;
            }
            return(returnValue);
        }
Exemplo n.º 6
0
        // Obtain deadlock details - old style path based logic
        private int[] SetDeadlockPathBased(int index, TrackCircuitPartialPathRoute route, TrackCircuitPartialPathRoute otherRoute, Train otherTrain)
        {
            int[] returnValue = new int[2];
            returnValue[1] = -1;  // set to no alternative path used

            TrackCircuitRouteElement firstElement = route[index];
            int  firstSectionIndex = firstElement.TrackCircuitSection.Index;
            bool allreadyActive    = false;

            int trainSection      = firstSectionIndex;
            int otherTrainSection = firstSectionIndex;

            int trainIndex      = index;
            int otherTrainIndex = otherRoute.GetRouteIndex(firstSectionIndex, 0);

            int firstIndex      = trainIndex;
            int otherFirstIndex = otherTrainIndex;

            TrackCircuitRouteElement trainElement;
            TrackCircuitRouteElement otherTrainElement;

            // loop while not at end of route for either train and sections are equal
            // loop is also exited when alternative path is found for either train
            for (int i = 0; ((firstIndex + i) <= (route.Count - 1)) && ((otherFirstIndex - i)) >= 0 && (trainSection == otherTrainSection); i++)
            {
                trainIndex      = firstIndex + i;
                otherTrainIndex = otherFirstIndex - i;

                trainElement      = route[trainIndex];
                otherTrainElement = otherRoute[otherTrainIndex];
                trainSection      = trainElement.TrackCircuitSection.Index;
                otherTrainSection = otherTrainElement.TrackCircuitSection.Index;

                if (trainElement.StartAlternativePath != null)
                {
                    int endAlternativeSection = trainElement.StartAlternativePath.TrackCircuitSection.Index;
                    returnValue[1] = route.GetRouteIndex(endAlternativeSection, index);
                    break;
                }

                if (otherTrainElement.EndAlternativePath != null)
                {
                    int endAlternativeSection = otherTrainElement.EndAlternativePath.TrackCircuitSection.Index;
                    returnValue[1] = route.GetRouteIndex(endAlternativeSection, index);
                    break;
                }

                TrackCircuitSection section = TrackCircuitSection.TrackCircuitList[trainSection];
                if (section.IsSet(otherTrain, true))
                {
                    allreadyActive = true;
                }
            }

            // get sections on which loop ended
            trainElement = route[trainIndex];
            trainSection = trainElement.TrackCircuitSection.Index;

            otherTrainElement = otherRoute[otherTrainIndex];
            otherTrainSection = otherTrainElement.TrackCircuitSection.Index;

            // if last sections are still equal - end of route reached for one of the trains
            // otherwise, last common sections was previous sections for this train
            int lastSectionIndex = (trainSection == otherTrainSection) ? trainSection : route[trainIndex - 1].TrackCircuitSection.Index;

            // if section is not a junction, check if either route not ended, if so continue up to next junction
            TrackCircuitSection lastSection = TrackCircuitSection.TrackCircuitList[lastSectionIndex];

            if (lastSection.CircuitType != TrackCircuitType.Junction)
            {
                bool endSectionFound = false;
                if (trainIndex < (route.Count - 1))
                {
                    for (int i = trainIndex + 1; i < route.Count - 1 && !endSectionFound; i++)
                    {
                        lastSection     = route[i].TrackCircuitSection;
                        endSectionFound = lastSection.CircuitType == TrackCircuitType.Junction;
                    }
                }
                else if (otherTrainIndex > 0)
                {
                    for (int i = otherTrainIndex - 1; i >= 0 && !endSectionFound; i--)
                    {
                        lastSection     = otherRoute[i].TrackCircuitSection;
                        endSectionFound = lastSection.CircuitType == TrackCircuitType.Junction;
                        if (lastSection.IsSet(otherTrain, true))
                        {
                            allreadyActive = true;
                        }
                    }
                }
                lastSectionIndex = lastSection.Index;
            }

            // set deadlock info for both trains

            SetDeadlockInfo(firstSectionIndex, lastSectionIndex, otherTrain.Number);
            otherTrain.SetDeadlockInfo(lastSectionIndex, firstSectionIndex, Number);

            if (allreadyActive)
            {
                TrackCircuitSection section = TrackCircuitSection.TrackCircuitList[lastSectionIndex];
                section.SetDeadlockTrap(otherTrain, otherTrain.DeadlockInfo[lastSectionIndex]);
            }

            returnValue[0] = route.GetRouteIndex(lastSectionIndex, index);
            if (returnValue[0] < 0)
            {
                returnValue[0] = trainIndex;
            }
            return(returnValue);
        }
Exemplo n.º 7
0
        // Check on deadlock
        private protected void CheckDeadlock(TrackCircuitPartialPathRoute route, int number)
        {
            // clear existing deadlock info
            ClearDeadlocks();

            // build new deadlock info
            foreach (Train otherTrain in simulator.Trains)
            {
                // check if not AI_Static
                if (Simulator.Instance.SignalEnvironment.UseLocationPassingPaths && otherTrain.GetAiMovementState() == AiMovementState.Static)
                {
                    continue;
                }

                if (otherTrain.Number != number && otherTrain.TrainType != TrainType.Static)
                {
                    TrackCircuitPartialPathRoute  otherRoute     = otherTrain.ValidRoute[0];
                    ILookup <int, TrackDirection> otherRouteDict = otherRoute.ConvertRoute();

                    for (int i = 0; i < route.Count; i++)
                    {
                        TrackCircuitRouteElement routeElement     = route[i];
                        TrackCircuitSection      section          = routeElement.TrackCircuitSection;
                        TrackDirection           sectionDirection = routeElement.Direction;

                        if (section.CircuitType != TrackCircuitType.Crossover)
                        {
                            if (otherRouteDict.Contains(section.Index))
                            {
                                TrackDirection otherTrainDirection = otherRouteDict[section.Index].First();
                                //<CSComment> Right part of OR clause refers to initial placement with trains back-to-back and running away one from the other</CSComment>
                                if (otherTrainDirection == sectionDirection ||
                                    (PresentPosition[Direction.Backward].TrackCircuitSectionIndex == otherTrain.PresentPosition[Direction.Backward].TrackCircuitSectionIndex && section.Index == PresentPosition[Direction.Backward].TrackCircuitSectionIndex &&
                                     PresentPosition[Direction.Backward].Offset + otherTrain.PresentPosition[Direction.Backward].Offset - 1 > section.Length))
                                {
                                    i = EndCommonSection(i, route, otherRoute);
                                }
                                else
                                {
                                    if (Simulator.Instance.SignalEnvironment.UseLocationPassingPaths) //new style location based logic
                                    {
                                        if (CheckRealDeadlockLocationBased(route, otherRoute, ref i))
                                        {
                                            int[] endDeadlock = SetDeadlockLocationBased(i, route, otherRoute, otherTrain);
                                            // use end of alternative path if set
                                            i = endDeadlock[1] > 0 ? --endDeadlock[1] : endDeadlock[0];
                                        }
                                    }
                                    else //old style path based logic
                                    {
                                        int[] endDeadlock = SetDeadlockPathBased(i, route, otherRoute, otherTrain);
                                        // use end of alternative path if set - if so, compensate for iElement++
                                        i = endDeadlock[1] > 0 ? --endDeadlock[1] : endDeadlock[0];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }